@IdClass JPA Annotation

soo*_*red 5 jpa

这是我的一个实体的复合主键.

public class GroupMembershipPK implements Serializable{

    private static final long serialVersionUID = 7816433876820743311L;

    private User user;
    private Group group;

    public GroupMembershipPK(){
    }

    public boolean equals(Object o){
        if(o==null){
            return false;
        }

        if(o instanceof GroupMembershipPK){
            final GroupMembershipPK groupMembershipPK=(GroupMembershipPK)o;
            return groupMembershipPK.group.getGroupName().equals(this.group.getGroupName()) &&
                groupMembershipPK.user.getName().equals(this.user.getName());
        }
        return false;
    }

    public int hashCode(){
        return super.hashCode();
    }
}
Run Code Online (Sandbox Code Playgroud)

继承我的实体(部分)使用上面的复合主键.

@Entity
@IdClass(GroupMembershipPK.class)
public class GroupMembership extends AbstractModelElementVersionOther{

    private static final long serialVersionUID = 9188465566607060376L;

    private String memType;
    private Group group;
    private User user;

    public GroupMembership(){
        super();
    }

    @Column(nullable=false)
    public String getMemType(){
        return this.memType;
    }

    public void setMemType(String memType){
        this.memType=memType;
    }

    @Id
    @ManyToOne
    @JoinColumn(name="groupId")
    public Group getGroup(){
        return this.group;
    }

    public void setGroup(Group group){
        this.group=group;
    }

    @Id
    @ManyToOne
    @JoinColumn(name="userId")
    public User getUser(){
        return this.user;
    }

    public void setUser(User user){
        this.user=user;
    }

    @Override
    public boolean equals(Object o) {
//
Run Code Online (Sandbox Code Playgroud)

我对上面实体的equals方法实现应该有点困惑.如何比较两个复合主键?

我也欢迎对我的代码的其他部分发表任何评论.

Art*_*ald 7

将实体存储为主键并不是一个好主意.使用查询语言时存在一些限制,而JPA 1.0不支持.除此之外,不需要使用实体作为主键.想一想.如果你想,请特别关注以下问题

一个行为类似于@Entity和@Embeddable的类

回答一个

关于答案一的评论

您将看到不必使用实体作为主键.

代替

public class GroupMembershipPK implements Serializable {

    private User user;
    private Group group;

}
Run Code Online (Sandbox Code Playgroud)

使用

public class GroupMembershipPK implements Serializable {

    private Integer userId;
    private Integer groupId;

}
Run Code Online (Sandbox Code Playgroud)

equals实现很重要,因为JPA通过使用它来比较两个实体(JPA通过使用equals实现来检查实体是否在持久化上下文中).所以你可以按照实现

public boolean equals(Object o) {
    if(o == null)
        return false;

    if(!(o instanceof GroupMembershipPK))
        return false;

    GroupMembershipPK other = (GroupMembershipPK) o;
    if(!(getUserId().equals(other.getUserId()))
        return false;

    if(!(getGroupId().equals(other.getGroupId()))
        return false;

    return true;
}
Run Code Online (Sandbox Code Playgroud)

建议:使用属性访问而不是字段访问是个好主意,因为在某些时候,由于性能问题,JPA实现使用代理对象.代理对象使用属性访问,因为它允许JPA实现在必要时访问数据库.

如何保存使用复合主键的对象?

User user = new user();
Group group = new Group();

entityManager.save(user);
entityManager.save(group);

entityManager.flush();

UserGroup userGroup = new UserGroup();

userGroup.setId(new UserGroup.UserGroupId(user.getId(), group.getId()));

entityManager.save(userGroup);
Run Code Online (Sandbox Code Playgroud)

您想知道如何实现UserGroup吗?

public class UserGroup {

    private UserGroupId id;

    // You can create UserGroupId outside UserGroup class
    // Feel free to choice your best approach
    @Embeddable
    public static class UserGroupId implements Serializable {

        private Integer userId;
        private Integer groupId;

        // required no-arg constructor
        public UserGroupId() {}

        public UserGroupId(Integer userId, Integer groupId) {
            this.userId = userId;
            this.roupId = groupId;
        }

        // getter's and setter's

        // equals and hashcode as shown above

    }

    @EmbeddedId
    public UserGroupId getId() {
        return this.id;
    }

    public setId(UserGroupId id) {
        this.id = id;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用复合主键的另一种方法是IdClass.见IdClass

问候,