Jpa EclipseLink:是否可以将@OneToMany关系作为外键添加到@EmbeddedId属性的类中?

Jpa EclipseLink:是否可以将@OneToMany关系作为外键添加到@EmbeddedId属性的类中?,jpa,eclipselink,one-to-many,Jpa,Eclipselink,One To Many,我想使用JPA来执行Jaas登录模块,以存储我的AuthUser和AuthUserRole。在这个问题上,我将集中讨论JPA方面 下面是我将在数据库中执行的操作(完全不是合法的SQL代码,但希望是全面的): 这对我来说很有意义,一个角色只能分配给一个用户一次 以下是我在Java中尝试的操作,在AuthUser中不显示用户名和电子邮件: @Entity public class AuthUser { @Id private int uid; private String

我想使用JPA来执行Jaas登录模块,以存储我的AuthUser和AuthUserRole。在这个问题上,我将集中讨论JPA方面

下面是我将在数据库中执行的操作(完全不是合法的SQL代码,但希望是全面的):

这对我来说很有意义,一个角色只能分配给一个用户一次

以下是我在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;
}
@实体
公共类AuthUser{
@身份证
私用uid;
私有字符串密码;
@独身癖
私人设定角色;
}
@实体
公共类AuthUserRole{
@嵌入ID
私有AuthUserRolePK AuthUserRolePK;
}
@可嵌入
公共类AuthUserRolePK{
公共信息;
公共角色;
}
Eclipselink做的很好,这意味着它可以工作,但不是我想要的方式。它生成第三个名为*authuser\u authuserrole*的表,其中包含(authuser\u uid,uid,role)列。无需提及AuthUser\u uid和uid是相同的

简单的答案是:

@Entity
public class AuthUser {
    @Id
    private int uid;

    private String password;

    @OneToMany
    @JoinColumn(name="authUserRolePK.uid", referencedColumnName="uid")
    private Set<AuthUserRole> roles;
}
@实体
公共类AuthUser{
@身份证
私用uid;
私有字符串密码;
@独身癖
@JoinColumn(name=“authUserRolePK.uid”,referencedColumnName=“uid”)
私人设定角色;
}
但EclipseLink强调,当使用@Embeddedid时,必须提及所有主键列

Q:如何使Eclipselink像我提到的数据库模式那样映射实体?我应该使用@IdClass吗?我可以看到数据库-->实体映射的结果,但这太简单了:)


谢谢你的回答

三张表是实现这一点的典型方法实际上,您的方法只是缺少一点JPA技巧

通常有三个表关联,如下所示:

AuthUser AuthUser_Role (association) Role frank ---- frank,admin ----- admin AuthUser AuthUser_角色(关联)角色 弗兰克----弗兰克,管理员----管理员 这实际上是Eclipselink试图为您映射的内容,但一般来说,您不会自己创建AuthUser_角色映射。而是在AuthUser上创建一个字段,如:

@ManyToMany
Set<Roles> userRoles
@manytomy
设置用户角色
和(可选)角色,如:

@ManyToMany(mappedBy="userRoles")
Set<AuthUser> usersWithRole;
@ManyToMany(mappedBy=“userRoles”)
设置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;
}
@实体
公共类AuthUser{
@身份证
私用uid;
私有字符串密码;
@OneToMany(mappedBy=“用户”)
私人设定角色;
}
@实体
公共类AuthUserRole{
@嵌入ID
私有AuthUserRolePK AuthUserRolePK;
}
@可嵌入
公共类AuthUserRolePK{
公共授权用户;
公共角色;
}

在这种安排下,最终只有两个表,“user”字段实际上等于数据库中AuthUser的uid,它只是在Java端显示为一个对象。

@manytomy Set userRoles,这让我相信这是一种更好的方法。我假设在@entities中创建模型时,不考虑关系模型需要实践。我将使用这种方法。这与嵌入式编程无关。stackoverflow.com/tags/embedded/info。重新标记
@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;
}