我想使用JPA来创建一个Jaas登录模块来存储我的 AuthUser 和 AuthUserRole 。我会在这个问题上专注于JPA方面。
以下是我在数据库中所做的事情(不是所有合法的SQL代码,但希望全面):
TABLE AuthUser( INT uid, VARCHAR password )
PRIMARY KEY (uid)
TABLE AuthUserRole( INT uid, INT role )
PRIMARY KEY (uid , role)
FOREIGN KEY (uid) REFERENCE AuthUser.uid
对我来说,一个角色只能分配给用户一次。
以下是我在Java中尝试做的事情,而不是在AuthUser中显示用户名和电子邮件:
@Entity
public class AuthUser {
@Id
private int uid;
private String password;
@OneToMany
private Set<AuthUserRole> roles;
}
@Entity
public class AuthUserRole {
@Embeddedid
private AuthUserRolePK authUserRolePK;
}
@Embeddable
public class AuthUserRolePK {
public int uid;
public int role;
}
Eclipselink做的映射很好,这意味着它可以工作,但不是我想要的方式。它创建了一个名为* authuser_authuserrole *的第三个表,它包含(AuthUser_uid,uid,role)列。无需提及AuthUser_uid和uid是完全相同的。
琐碎的答案是:
@Entity
public class AuthUser {
@Id
private int uid;
private String password;
@OneToMany
@JoinColumn(name="authUserRolePK.uid", referencedColumnName="uid")
private Set<AuthUserRole> roles;
}
但EclipseLink告诉我们,当使用@Embeddedid时,必须提到所有主键列。
问:如何让Eclipselink映射我的实体,就像我提到的数据库架构一样?我应该使用@IdClass吗?我可以看到数据库的结果 - &gt;实体映射,但这太容易了:)
感谢您的回答!
答案 0 :(得分:0)
实际上有三个表是实现这一目的的典型方法,你的方法只是缺少一点JPA技巧。
通常,您有三个表关联如下:
AuthUser AuthUser_Role (association) Role frank ---- frank,admin ----- admin
这实际上是Eclipselink试图为您映射的内容,但一般情况下,您不会自己创建AuthUser_Role映射。相反,您在AuthUser上创建一个字段,如:
@ManyToMany
Set<Roles> userRoles
和(可选)在角色上:
@ManyToMany(mappedBy="userRoles")
Set<AuthUser> usersWithRole;
然后EclipseLink会为您处理连接表,您需要担心的是userRoles字段,它将更新连接。
您可以对此进行扩展,以便为在设定日期等开始和结束的角色手动创建连接,但对于除最复杂项目之外的所有项目,这通常不是必需的,并且通常可以以不同的方式完成。出于合规性目的,使用其中一个ELUG扩展来保存和访问更改历史记录更容易,例如,这是我在添加额外元数据到连接信息时看到的最常见原因。
或者,如果您真的只想使用两个表来执行此操作,请将AuthUserRole设置为主要端,将AuthUser设置为被动端。
@Entity
public class AuthUser {
@Id
private int uid;
private String password;
@OneToMany(mappedBy="user")
private Set<AuthUserRole> roles;
}
@Entity
public class AuthUserRole {
@Embeddedid
private AuthUserRolePK authUserRolePK;
}
@Embeddable
public class AuthUserRolePK {
public AuthUser user;
public int role;
}
在这种安排中,最终只有两个表,“user”字段确实等于数据库中AuthUser的uid,它只是在Java端显示为一个对象。