JPA Compound key with @EmbeddedId

只愿长相守 提交于 2019-12-14 02:35:06

问题


In a legacy database, I have three tables: Users, Workgroups, and UsersWorkgroup. UsersWorkgroup stores what role a user has in a workgroup. Here are the relevant code snippets:

@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;

And of course, problem is, it doesn't work. Currently I get this exception:

Exception Description: An incompatible mapping has been encountered between [class entity.Workgroup] and [class entity.UsersWorkgroup]. This usually occurs when the cardinality of a mapping does not correspond with the cardinality of its backpointer.

Which I don't understand since OneToMany should match ManyToOne... Or is it a ManyToMany relationship? If I switch to @ManyToMany, I get this:

Exception Description: The target entity of the relationship attribute [workgroup] on the class [class com.ericsson.rsg.ejb.entity.UsersWorkgroup] cannot be determined. When not using generics, ensure the target entity is defined on the relationship mapping.

I'm trying to understand compound keys (embedded), but all the examples I could find have only simple columns that are not foreign keys (but that's the whole point of a compound key, isn't it?). Can the UsersWorkgroup table secretly be a join table?

Should I declare the PK class as a strict POJO class? Or should I put the @JoinColumn annotations in the PK class? How do I refer to the columns within the compound key from another table? Should I initialize the PK object in the refering class constructor, or is it not necessary?

I feel stuck completely.


回答1:


First of all, I think your relation is a Many To Many, as a user can be in many groups, and a group can have many users (or I would assume so).

Second, as far as I know you have to reference both id_workgroup and user_name as JoinColumns, because they are part of the PK and a unit, so both should be referenced.

Also, I see the "equals" and "hashCode" methods missing from your embedded PK, as well as the getters/setters. I believe they are mandatory.




回答2:


Your mapping looks fine except for mappedBy - it should be a property name, not a column name:

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


来源:https://stackoverflow.com/questions/3164207/jpa-compound-key-with-embeddedid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!