我对此完全陌生,如果这是愚蠢的问题,我很抱歉。
我正在尝试在 JPA 中为 Google App Engine 设计数据库模型,但我无法做到正确。当我找到无法正确获取注释的方式或收到有关 Google App Engine 不支持 M:N 的错误时。
我需要实体用户有多个组,组有多个用户,并且有些用户也是组管理员。
我的基本模型是User -> usergroup(user; group; (bool)isAdmin) <-Group
有人可以举一个简单明了的例子来说明如何定义关系吗?
我对此完全陌生,如果这是愚蠢的问题,我很抱歉。
我正在尝试在 JPA 中为 Google App Engine 设计数据库模型,但我无法做到正确。当我找到无法正确获取注释的方式或收到有关 Google App Engine 不支持 M:N 的错误时。
我需要实体用户有多个组,组有多个用户,并且有些用户也是组管理员。
我的基本模型是User -> usergroup(user; group; (bool)isAdmin) <-Group
有人可以举一个简单明了的例子来说明如何定义关系吗?
请试试这个。
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key id;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
private UserGroup usergroup;
}
类用户组
@Entity
public class UserGroup {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key id;
private String name;
private boolean admin;
@OneToMany(mappedBy = "usergroup", cascade = CascadeType.ALL)
private List<User> users = new ArrayList<User>();
}
请注意 GAE 对 JPA 有限制,您可以在此处阅读更多信息
我对 Google App Engine 一无所知,但我可以在 JPA 方面提供帮助。
这里的问题是“isAdmin”列,它阻止数据模型成为与连接表的简单@ManyToMany 关系。
引入该字段后,在数据模型中,您需要在用户实体上使用 key=Group 和 value=isAdmin 的 Map,类似地,您需要在 Group 实体中使用相应的 Map,以便了解每个用户是否是管理员。
这通过以下方式使用@ElementCollection 建模:
@Entity
@Table(name="User")
public class User
{
@Id
@GeneratedValue(strategy= GenerationType.TABLE)
private int id;
private String name;
@ElementCollection
@CollectionTable(name="Users_Groups", joinColumns={@JoinColumn(name="userId")})
@MapKeyJoinColumn(name="groupId")
@Column(name="isAdmin")
private Map<Group, Boolean> groups;
}
@Entity
@Table(name="Group")
public class Group
{
@Id
@GeneratedValue(strategy= GenerationType.TABLE)
private int id;
private String name;
@ElementCollection
@CollectionTable(name="Users_Groups", joinColumns={@JoinColumn(name="groupId")})
@MapKeyJoinColumn(name="userId", insertable=false, updatable=false)
@Column(name="isAdmin", insertable=false, updatable=false)
private Map<User, Boolean> users;
}
重要的注解是@ElementCollection,其他注解只是命名集合表的特定列,并确保它们从两个实体中匹配:@CollectionTable 给出表的名称和表示当前 id 的列的名称实体。@MapKeyJoinColumn 给出了表示 Map 中“key”元素的 id 的列的名称,@Column 给出了 map 中“value”元素的名称。
我不确定其中一个实体是否需要 insertable=false 和 updatable=false,由于用户和组之间的循环依赖关系,可能会避免添加重复行。
您还需要手动创建集合表,因为至少 EclipseLink 尝试使用两个“groupId”和“isAdmin”列来创建它。如果绝对需要用户和组之间的循环依赖关系,您可能会考虑审查设计。