2011-12-19 43 views
5

Cho phép nói rằng chúng tôi có lớp Thực thể người dùng. Người dùng có thể là bạn bè với những người dùng khác. Làm cách nào tôi có thể ánh xạ trường thu thập tự tham khảo này mà không tạo một thực thể mới được gọi là Kết nối hoặc tạo nhiều mục nhập trong cơ sở dữ liệu?ánh xạ trường tự tham chiếu trong JPA

@Entity 
public class User { 
... 
@ManyToMany 
private Collection<User> friends; 
... 
} 

USER_ID-FRIEND_ID 
1 - 2 
2 - 1 (duplicate... I don't need it) 
+0

Một mối quan hệ nhiều-tham chiếu tự tham chiếu là hợp lệ và có thể được ánh xạ bằng cách sử dụng chú thích JPA. Giống như tất cả các mối quan hệ nhiều-nhiều, bạn phải xác định một bảng cầu để lưu trữ cả hai mặt của mối quan hệ. Thực thể sẽ xác định một trường cho phía sở hữu và một trường khác cho phía ánh xạ của mối quan hệ. – scottb

Trả lời

1

Bạn không thể - bạn cần cả hai bản ghi trong cơ sở dữ liệu.

Thực ra, đối với quan hệ hữu nghị, tôi muốn nói rằng cơ sở dữ liệu đồ thị như neo4j là điều thích hợp để sử dụng. Ở đó bạn có hai người dùng và chỉ cần thêm một cạnh "bạn bè".

+0

thú vị ... tôi nghĩ rằng có thể có một gian lận hoặc sth –

+2

Câu trả lời này là không chính xác. Mối quan hệ nhiều-nhiều-tự tham chiếu là hợp lệ và có thể được ánh xạ trong JPA mà không định nghĩa bất kỳ thực thể mới nào.Mối quan hệ đòi hỏi một bảng cầu, giống như tất cả các mối quan hệ nhiều - nhiều. – scottb

6

Sau đây là ảnh chụp từ mã của tôi cho ElementEntity:

@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY) 
private List<ElementEntity> children; 

@JoinColumn(name = "ParentId", referencedColumnName = "ElementId") 
@ManyToOne(fetch = FetchType.LAZY) 
private ElementEntity parent; 

ở đâu trên cơ sở dữ liệu có các lĩnh vực:

  • ElementId - khóa chính;
  • ParentId mối quan hệ với cha mẹ
+0

cảm ơn anh chàng cho thời gian của bạn. tôi không tìm kiếm mối quan hệ cha-con. –

+3

@HayatiGuvence có gì sai - chỉ cần đổi tên ParentId thành USER_ID và elementId thành friend_Id – Dewfy

1

Ít nhất bạn sẽ cần một relational table.

Vì vậy, bạn có một bảng USERFRIENDS:

user_id friend_id 
    1  2 

Nhưng @Bozho Câu trả lời là cách tốt hơn so với mỏ (neo4j).

+0

:) bạn không thể có hai tên cột giống nhau trong một bảng –

+0

cảm ơn bạn! chỉ là một typ0 – ssedano

0

Vâng, trên thực tế bạn có thể.

Bạn có thể sử dụng chú thích như @PreUpdate, @PrePersists, @PostUpdate và như vậy để chuyển đổi thủ công các phần tử của bộ sưu tập. Bằng cách này, thực thể của bạn có thể hiển thị theo cách họ muốn trong khi trong cơ sở dữ liệu, bạn chỉ lưu trữ văn bản thô.

Một giải pháp thay thế tạm thời hơn sẽ là sử dụng chú thích @Convert, có sẵn từ jpa 2.1 (@UserType trong chế độ ngủ đông). Nó báo cho jpa chuyển đổi trường thành một kiểu khác mỗi khi nó đọc/lưu trong cơ sở dữ liệu. Đối với nó, bạn nên sử dụng @Convert anotation, chỉ định và đối tượng AttributeConverter.

Ví dụ

public class Parent { 
     @Id 
     private Integer id; 

     @Convert(converter = FriendConverter.class) 
     private Set<Parent>friends; 
    } 

Và lớp chuyển đổi như sau:

@Component 
    public class FriendConverter implements AttributeConverter<List, String>{ 
     @Autowired 
     private SomeRepository someRepository; 

     @Override 
     public String convertToDatabaseColumn(List attribute) { 
     StringBuilder sb = new StringBuilder(); 
     for (Object object : attribute) { 
      Parent parent = (parent) object; 
      sb.append(parent.getId()).append("."); 
     } 
     return sb.toString(); 
     } 

     @Override 
     public List convertToEntityAttribute(String dbData) { 
     String[] split = dbData.split("."); 
     List<Parent>friends = new ArrayList<>(); 
     for (String string : split) { 
      Parent parent = someRepository.findById(Integer.valueOf(string)); 
      friends.add(accion); 
     } 
     return friends; 
     } 
    } 

Đó là một thực hiện giả nhưng nó mang lại cho bạn những ý tưởng.

Là nhận xét cá nhân, tôi khuyên bạn nên lập bản đồ mối quan hệ theo ý muốn. Trong tương lai nó sẽ giúp bạn tránh được vấn đề. AttributeConverter có ích khi làm việc với enums

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