带@EmbeddedId的JPA复合键

时间:2010-07-02 08:31:21

标签: java jpa jpa-2.0 compound-key

在旧数据库中,我有三个表:Users,Workgroups和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;

当然,问题是,它不起作用。 目前我得到了这个例外:

  

异常说明:不兼容   已经遇到过映射   [class entity.Workgroup]和[class   entity.UsersWorkgroup。这通常   当基数为a时发生   映射不符合   背景的基数。

我不明白,因为OneToMany应该匹配ManyToOne ......或者它是ManyToMany关系?如果我切换到@ManyToMany,我明白了:

  

异常说明:目标   关系属性的实体   班上的[工作组] [班级   com.ericsson.rsg.ejb.entity.UsersWorkgroup]   无法确定。什么时候不用   泛型,确保目标实体   在关系映射上定义。

我正在尝试理解复合键(嵌入式),但我找到的所有示例都只有简单的列,而不是外键(但这是复合键的重点,不是吗?)。 UsersWorkgroup表可以秘密地成为连接表吗?

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

我完全陷入困境。

2 个答案:

答案 0 :(得分:1)

首先,我认为你的关系是一个多对多,因为一个用户可以在很多组中,一个组可以有很多用户(或者我会这么认为)。

其次,据我所知,你必须将id_workgroup和user_name都引用为JoinColumns,因为它们是PK和一个单元的一部分,所以两者都应该被引用。

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

答案 1 :(得分:0)

mappedBy外,您的映射看起来很好 - 它应该是属性名称,而不是列名:

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