当前位置: 代码迷 >> java >> 具有@EmbeddedId的JPA复合键
  详细解决方案

具有@EmbeddedId的JPA复合键

热度:72   发布时间:2023-07-17 20:26:43.0

在旧版数据库中,我有三个表:Users,Workgroup和UsersWorkgroup。 UsersWorkgroup存储用户在工作组中扮演的角色。 以下是相关的代码段:

@Entity
@Table(name = "users_workgroup")
public class UsersWorkgroup implements Serializable {
    private static final long serialVersionUID = 1L;
    @EmbeddedId
    protected UsersWorkgroupPK usersWorkgroupPK;

    @JoinColumn(name = "idworkgroup", referencedColumnName = "idworkgroup")
    @ManyToOne(optional = false)
    private Workgroup workgroup;
    @JoinColumn(name = "user_name", referencedColumnName = "user_name")
    @ManyToOne(optional = false)
    private Users users;

    @Column(name = "role")
    private Integer role;


@Embeddable
public class UsersWorkgroupPK implements Serializable {

    @Basic(optional = false)
    @Column(name = "idworkgroup", insertable=false, updatable=false)
    private int idworkgroup;
    @Basic(optional = false)
    @Column(name = "user_name", insertable=false, updatable=false)
    private String userName;


@Entity
@Table(name = "workgroup")
public class Workgroup implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "idworkgroup")
    private Integer idworkgroup;
    @Column(name = "name")
    private String name;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "idworkgroup")
    private Collection<UsersWorkgroup> usersWorkgroupCollection;

当然,问题是,它不起作用。 目前,我收到此异常:

异常描述:[类entity.Workgroup]和[类entity.UsersWorkgroup]之间遇到了不兼容的映射。 当映射的基数与其后向指针的基数不对应时,通常会发生这种情况。

由于OneToMany应该与ManyToOne相匹配,我不了解...还是是ManyToMany关系? 如果我切换到@ManyToMany,则会得到以下信息:

异常描述:无法确定类[com.ericsson.rsg.ejb.entity.UsersWorkgroup]类上的关系属性[workgroup]的目标实体。 不使用泛型时,请确保在关系映射上定义了目标实体。

我试图理解复合键(嵌入式),但是我能找到的所有示例都只有简单的列,这些列不是外键(但这就是复合键的全部,不是吗?)。 UsersWorkgroup表可以秘密地成为联接表吗?

我应该将PK类声明为严格的POJO类吗? 还是应该将@JoinColumn批注放在PK类中? 如何从另一个表引用复合键中的列? 我应该在引用类构造函数中初始化PK对象,还是没有必要?

我感到完全卡住了。

首先,我认为您的关系是一个多对多的关系,因为一个用户可以处于多个组中,而一个组可以有多个用户(或者我可以这样假设)。

其次,据我所知,必须将id_workgroup和user_name都引用为JoinColumns,因为它们是PK和单元的一部分,因此都应同时引用。

另外,我看到嵌入式PK以及getter / setter方法中缺少“ equals”和“ hashCode”方法。 我相信它们是强制性的。

除了mappedBy之外,您的映射看起来不错-它应该是属性名称,而不是列名称:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "workgroup") 
private Collection<UsersWorkgroup> usersWorkgroupCollection;