2011-01-08 23 views
5

Có ai biết nếu nó có thể thiết lập một backreference từ bên trong một JPA @EmbeddedId.Làm thế nào để thiết lập một backreference từ một @EmbeddedId trong JPA

Vì vậy, ví dụ có một Entity của Mẫu

@Entity 
public class Entity1 { 
    @Id 
    @GeneratedValue 
    private String identifier; 

    private Entity1 relationToEntity1; 
    //Left out the getters and setters for simplicity 
} 

Và một thực thể thứ hai với một Id nhúng phức tạp. Một phần của thực thể thứ hai này là một tham chiếu đến thực thể cha của nó. Cũng giống như vậy:

@Entity 
public class Entity2 { 
    @EmbeddedId private Entity2Identifier id; 
    //Left out the getters and setters for simplicity. 
} 

@Embedabble 
public class Entity2Identifier { 
    private String firstPartOfIdentifier; 
    private Entity1 parent; 
    //Left out the getters and setters for simplicity. 
} 

Khi tôi cố gắng tiết kiệm một cấu trúc như vậy qua JPA (thực hiện là EclipseLink) vào một cơ sở dữ liệu tôi nhận được một vài trường hợp ngoại lệ có dạng:

Exception [EclipseLink-93] (Eclipse Persistence Services - 1.1.0.r3639-SNAPSHOT): 
org.eclipse.persistence.exceptions.DescriptorException 
Exception Description: The table [ENTITY1] is not present in this descriptor. 
Descriptor: RelationalDescriptor(test.Entity2 --> [DatabaseTable(ENTITY2)]) 

Có ai đó gặp sự cố như vậy và có giải pháp không?

Trả lời

4

Điều bạn đang tìm kiếm là một Id bắt nguồn. Nếu bạn đang sử dụng JPA 2.0 thì sau đây sẽ làm việc. Bạn thực sự không muốn toàn bộ Parent là một phần của PK, chỉ là PK của cha mẹ.

@Entity 
public class Entity1 { 
    @EmbeddedId 
    private ParentId identifier; 

    @OneToOne(mappedBy="relationToEntity1") 
    private Entity2 relationToEntity2; 

    //Left out the getters and setters for simplicity 
} 

@Entity 
public class Entity2 { 
    @EmbeddedId private Entity2Identifier id; 
    //Left out the getters and setters for simplicity. 

    @MapsId("parentId") 
    @OneToOne 
    private Entity1 parent; 

} 

@Embedabble 
public class Entity2Identifier { 
    private String firstPartOfIdentifier; 
    private ParentId parentId; 
    //Left out the getters and setters for simplicity. 
} 
+0

OK. Tôi đoán ví dụ của tôi là đơn giản. Cha mẹ thực sự có một ID nhúng phức tạp, bao gồm hai chuỗi, là tốt. Đó là lý do tại sao tôi không thể chỉ đơn giản là tham chiếu ID của nó. – ali

+1

Điều đó cũng đơn giản. Tôi đã cập nhật ví dụ ở trên để sử dụng EmbeddedId trên thực thể 1. –

+1

@MapsId là người chiến thắng! Rất hữu ích. –

1

Chú thích @EmbeddedId không cho phép các mối quan hệ trong lớp nhận dạng hỗn hợp. Từ số EmbeddedId JavaDoc:

Ánh xạ quan hệ được xác định trong lớp id được nhúng không được hỗ trợ.

Tôi hiểu rằng bạn muốn Entity2Identifier để chứa khóa cho phụ huynh, nhưng trong ví dụ của bạn, bạn đang tạo mối quan hệ với toàn bộ đối tượng thay vì chỉ bao gồm khóa chính của phụ huynh. Ngay cả khi việc xây dựng này có hiệu quả, bạn sẽ thiết lập khóa tổng hợp không chỉ là khóa chính của phụ huynh mà còn là toàn bộ trạng thái của cha mẹ.

Nếu bạn chỉ đơn giản là tìm kiếm một cách dễ dàng để thiết lập mối quan hệ hai chiều, bạn có thể làm như vậy với các @OneToOne chú thích và mappedBy thuộc tính:

@Entity 
public class Entity1 { 
    @Id 
    @GeneratedValue 
    private String identifier; 

    @OneToOne(mappedBy="relationToEntity1") 
    private Entity2 relationToEntity2; 
    ... 
} 

@Entity 
public class Entity2 { 

    @OneToOne 
    private Entity1 relationToEntity1; 
    ... 
} 

Với thiết lập này các chú thích, JPA nhà cung cấp sẽ xử lý các mối quan hệ hai chiều như Entity1.relationToEntity2Entity2.relationToEntity1. Bạn cũng có thể muốn ghi đè hành vi xếp tầng mặc định (không có) cũng như hành vi xóa bỏ trẻ mồ côi mặc định (không có). Xem JavaDoc để biết thêm chi tiết.

+0

Cảm ơn câu trả lời của bạn. Thực ra tôi biết điều đó. Vấn đề là khóa chính của tôi bao gồm nhiều phần, một trong số đó là thực thể cha. Điều này có nghĩa là có một số giá trị xác định thực thể nhưng nó chỉ hợp lệ trong ngữ cảnh của phụ huynh. – ali

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