2008-12-22 36 views
5

Tôi muốn ánh xạ nhiều-nhiều trong Hibernate bằng cách sử dụng một bảng liên kết. Tôi có hai lớp, phụ huynh và trẻ em lớp, ví dụ:Làm thế nào để ánh xạ nhiều-nhiều danh sách trong Hibernate với một bảng liên kết

public class Parent{ 

private List<Child> _children; 

//...getters and setters 
} 

tôi sử dụng một bảng liên kết (link_table) với ba cột link_id, parent_idchild_id. Cơ sở dữ liệu là máy chủ SQL và các loại id là uniqueidentifier. Vì vậy, tôi thường sử dụng guid cho các lĩnh vực id.

Làm cách nào bạn có thể triển khai điều này bằng cách sử dụng thẻ <list /> nếu đây là thẻ đúng để sử dụng? Bạn có biết bất kỳ tài liệu tốt nào để thực hiện việc này không?

Tôi hiện đang nhận được một ConstraintViolationException nhưng không thể tìm thấy bất kỳ tài liệu hay ví dụ nào về điều này.

Tôi nghĩ rằng vấn đề chính là: cách chỉ định link_id để được tạo tự động trong bảng liên kết.

Trả lời

5

tôi không nghĩ rằng có thể (hoặc cần) để thêm một khóa chính LINK_ID đến tham gia bàn. Bảng nối sẽ thường bao gồm các khóa chính của hai bảng tham gia.

Sử dụng XML, bạn sẽ cần cú pháp như thế này:

<class name="Parent"> 
    .... 
    <list name="children" table="link_table"> 
    <key column="parent_id"/> 
    <many-to-many column="child_id" 
     class="Children"/> 
    </list> 
    ... 
</class> 

<class name="Child"> 
... 
<list name="parents" inverse="true" table="link_table"> 
    <key column="child_id"/> 
    <many-to-many column="parent_id" 
     class="Parent"/> 
</list> 
... 
</class> 

Mặc dù tôi thấy chú thích tốt hơn để sử dụng.

+5

điều này cũng yêu cầu cột chỉ mục mà tôi tin. – Brandon

+0

Yêu cầu là một từ mạnh mẽ. Bạn có thể kết thúc với cái mà một số người gọi là hiệu năng kém hiệu quả mà không có chỉ mục, nhưng tôi không thể tưởng tượng chỉ mục là * bắt buộc *. – corsiKa

+2

"cột chỉ mục" rất khác với chỉ mục cơ sở dữ liệu trong ngữ cảnh này. – araqnid

0

Tôi không chắc chắn rằng bạn có thể dễ dàng tắt tính năng này cho cơ sở dữ liệu hiện có với dữ liệu hiện có. Hibernate thường là tốt hơn hết xác định sơ đồ dữ liệu riêng của mình lần đầu tiên bạn kết nối ...

Tôi đã chỉ kéo ra nhiều-nhiều với các chú thích, nhưng tôi nghĩ rằng tài liệu Hibernate cung cấp XML ví dụ dựa: link text

7

tôi làm điều này bằng chú thích, đặc biệt @ManyToMany và @JoinTable:

Hibernate Docs:

@Entity 
public class Employer implements Serializable { 
    @ManyToMany(
     targetEntity=org.hibernate.test.metadata.manytomany.Employee.class, 
     cascade={CascadeType.PERSIST, CascadeType.MERGE} 
    ) 
    @JoinTable(
     name="EMPLOYER_EMPLOYEE", 
     [email protected](name="EMPER_ID"), 
     [email protected](name="EMPEE_ID") 
    ) 
    public Collection getEmployees() { 
     return employees; 
    } 
} 


@Entity 
public class Employee implements Serializable { 
    @ManyToMany(
     cascade = {CascadeType.PERSIST, CascadeType.MERGE}, 
     mappedBy = "employees", 
     targetEntity = Employer.class 
    ) 
    public Collection getEmployers() { 
     return employers; 
    } 
} 
+0

câu trả lời tuyệt vời, đã giúp rất nhiều –

0

Tôi đã tìm thấy một blog trực tuyến rất tốt, cung cấp 2 cách để thêm các trường bổ sung vào nhiều cột được lập bản đồ ngủ đông. Theo truyền thống, chúng tôi hy vọng nhiều bản đồ để đưa ra một bảng mới sẽ FK của các bảng được ánh xạ. Nhưng có nhiều cách để tinh chỉnh và thêm nhiều trường/cột vào bảng được nối kết này.

Bảng đã tham gia này có thể chứa PK hoặc có thể chứa một số trường bổ sung không có PK. Xem blog này để triển khai chính xác See Here

Và theo ví dụ của bạn, bạn cần thêm PK trong bảng để khai báo bảng mới ParentChildren và khai báo khóa chính của bạn là linkId. Tôi chỉ hiển thị lớp cha mẹ bị hủy bỏ, vì các chú thích cho nhiều đối với nhiều ánh xạ trong lớp cha và con có thể được tham chiếu từ bài đăng ở trên.

@Entity 
@Table(name = "parent_children") 
public class ParentChildren{ 
    @Id @GeneratedValue 
    private long linkId; 

    @ManyToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name = "parent_id") 
    private Parent parent; 

    @ManyToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name = "children_id) 
    private Children children; 

    // additional fields if you want 
    private boolean activated; 

    //getters and setters 
    } 
} 

Vì vậy, điều này sẽ tạo bảng ánh xạ có linkId làm khóa chính và parent_id và children_id làm Khóa ngoại. Chỉ cần được rõ ràng về lý do tại sao bạn muốn một link_id riêng biệt như khóa chính và làm thế nào bạn sẽ sử dụng nó.

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