2009-09-23 60 views
5

Đây là khóa chính kết hợp cho một trong các thực thể của tôi.@IdClass JPA Chú thích

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(); 
    } 
} 

Là thực thể của tôi (một phần) sử dụng ở trên làm Khóa chính kết hợp.

@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) { 
// 

Tôi hơi bối rối về việc nên thực hiện phương pháp bằng cho thực thể trên. Làm cách nào tôi có thể so sánh hai khóa chính kết hợp?

Mọi nhận xét về các phần khác của mã của tôi đều được chào đón.

Trả lời

7

Bạn không nên lưu trữ các thực thể dưới dạng khóa chính. Có một số hạn chế khi sử dụng ngôn ngữ truy vấn và JPA 1.0 không hỗ trợ. Bên cạnh đó nó không cần phải sử dụng các thực thể như khóa chính. Hãy suy nghĩ về it.If bạn muốn, hãy xem đặc biệt tại những câu dưới đây

A class that behaves like @Entity and @Embeddable

Answer one

Comment about answer one

Bạn sẽ thấy rằng việc sử dụng một thực thể như khóa chính là không cần thiết.

Thay vì

public class GroupMembershipPK implements Serializable { 

    private User user; 
    private Group group; 

} 

Sử dụng

public class GroupMembershipPK implements Serializable { 

    private Integer userId; 
    private Integer groupId; 

} 

bằng thực hiện là rất quan trọng bởi vì JPA so sánh hai thực thể bằng cách sử dụng nó (JPA kiểm tra xem một thực thể là trong bối cảnh kiên trì bằng cách sử dụng tương đương với thực hiện). Vì vậy, bạn có thể triển khai theo

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

Tư vấn: bạn nên sử dụng đối tượng proxy vì vấn đề hiệu suất. Một đối tượng proxy sử dụng quyền truy cập thuộc tính vì nó cho phép thực thi JPA truy cập cơ sở dữ liệu khi cần thiết.

Làm cách nào để lưu đối tượng sử dụng khóa chính kết hợp?

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

Bạn có muốn biết cách triển khai UserGroup không?

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

Cách tiếp cận khác để sử dụng khóa chính kết hợp là IdClass. Xem IdClass

regards,

+0

Bạn cũng nên thực hiện một phương thức hashCode mà sử dụng userId và tài sản groupId, vì đối tượng bằng nhau cũng phải có cùng bảng băm. Ví dụ: (getUserId() == null? 0: getUserId(). HashCode())^(getGroupId() == null? 0: getGroupId(). HashCode()) –

+0

@ Jörn Horstmann Xin chào, bạn là đúng. Nhưng nó đã được thực hiện chỉ bằng thực hiện do trả lời. Cảm ơn bạn anyway –

+0

@Arthur Ronald. Cảm ơn, hoạt động hoàn hảo. Tuy nhiên, bạn có thể cho tôi biết cách duy trì thực thể bằng cách sử dụng khóa chính kết hợp như được mô tả ở trên không? Tôi nhận được lỗi sau trong JBoss khi tôi cố gắng làm điều đó .——--- "Ngoại lệ trong chủ đề" chính "javax.ejb.EJBException: javax.persistence.PersistenceException: org.hibernate.id.IdentifierGenerationException: ids cho Lớp này phải được gán thủ công trước khi gọi save() " – soontobeared

1

Nó đã được đề cập một phần, dù sao:

  1. Khi thực hiện phương pháp equals, bạn nên sử dụng instanceof để cho phép so sánh với các lớp con. Nếu lười biếng Hibernate tải một hoặc một đến một mối quan hệ, bạn sẽ có một proxy cho lớp thay vì lớp đồng bằng. Một proxy là một lớp con. So sánh tên lớp sẽ thất bại.
    Về mặt kỹ thuật, bạn nên theo dõi Liskovs Substitution Principle và bỏ qua đối xứng.
  2. Cạm bẫy tiếp theo là sử dụng một cái gì đó như name.equals(that.name) thay vì name.equals(that.getName()). Việc đầu tiên sẽ thất bại, nếu đó là một proxy.

http://www.laliluna.de/jpa-hibernate-guide/ch06s06.html

Các vấn đề liên quan