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

时间:2011-06-28 02:35:25

标签: jpa eclipselink one-to-many

我想使用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;实体映射,但这太容易了:)

感谢您的回答!

1 个答案:

答案 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端显示为一个对象。