2014-06-10 14 views
6

Tôi đang xem các cách khác nhau để chú thích bản đồ bằng cách sử dụng chú thích JPAnate 4.1.9 & JPA.Ghi đè tên cột và giá trị khi ánh xạ java.util.Map với chú thích JPA

Nếu tôi muốn để lưu trữ một bản đồ nơi chính là một thuộc tính của giá trị thực thể đánh dấu lên vẻ như thế này

@OneToMany(mappedBy = "deptById", targetEntity = com.demo.impls.Employee.class) 
    @MapKey(name = "entityId") 
    private Map<Long, Employee> employeesById; 

Lưu ý dấu trên lên không tạo ra một bảng tham gia nhưng bản đồ được trả về thông qua truy vấn tại thời gian chạy, vì vậy Bản đồ là động và bạn không phải thêm phần tử vào bản đồ trong Java để chúng được truy vấn trả về.

Bây giờ tôi muốn nội dung của Bản đồ phản ánh những gì ứng dụng đã thêm vào Bản đồ thay vì thực hiện truy vấn động.

Có 4 loại Map Tôi muốn để lưu trữ

private Map<String, String> map0; 
    private Map<String, Entity> map1; 
    private Map<Entity, String> map2; 
    private Map<Entity, Entity> map3; 

Trong những trường hợp đó là NO mối quan hệ giữa chính trị & và cũng không có bất kỳ mối quan hệ với Entity giữ. Tôi phải có thể chỉ định tên của bảng kết nối cũng như tên cột cho giá trị & chính.

Tôi đã thử những điều sau

@Entity 
public class Department { 
    @ElementCollection 
    @CollectionTable(name = "TEST_MAP0") 
    @Column(name="value") 
    @MapKeyColumn(name="Key") 
    private Map<String, String> map0; 

    @ElementCollection(targetClass = com.demo.bb.impls.Employee.class) 
    @CollectionTable(name = "TEST_MAP1") 
    @Column(name="value") 
    @MapKeyColumn(name="Key") 
    private Map<String, Employee> map1; 

    @ElementCollection 
    @MapKeyClass(value = com.demo.bb.impls.Employee.class) 
    @CollectionTable(name = "TEST_MAP2") 
    @Column(name="value") 
    @MapKeyColumn(name="Key") 
    private Map<Employee, String> map2; 

    @ElementCollection(targetClass = com.demo.bb.impls.ParkingSpace.class) 
    @MapKeyClass(value = com.demo.bb.impls.Employee.class) 
    @CollectionTable(name = "TEST_MAP3") 
    @Column(name="value") 
    @MapKeyColumn(name="Key") 
    private Map<Employee, ParkingSpace> map3; 

Trường hợp 0 ​​Bản đồ hoạt động tốt & được tạo ra tham gia bảng có các cột SỞ, GIÁ TRỊ, KEY

Ba trường hợp khác làm việc trong nhiều như bạn có thể lưu trữ dữ liệu trong các bảng & trong Java thẩm tra các bảng có các khóa/giá trị có liên quan & lấy lại kết quả mong đợi - tức là nó xử lý việc lưu trữ Thực thể bằng cách sử dụng @ElementCollection

Nhưng ghi đè tên cột bằng cách sử dụng @Column (name = "value") & @MapKeyColumn (name = "key") được bỏ qua khi khóa hoặc giá trị là một Thực thể.

Tôi đã cố gắng sử dụng @ManyToMany chú thích như sau

@ManyToMany(targetEntity = com.demo.bb.impls.Employee.class) 
    @JoinTable(name = "TEST_MAP1_B") 
    @Column(name="value") 
    @MapKeyColumn(name="Key") 
    private Map<String, Employee> map1_B; 

    @ManyToMany(targetEntity = com.demo.bb.impls.ParkingSpace.class) 
    @MapKeyClass(value = com.demo.bb.impls.Employee.class) 
    @JoinTable(name = "TEST_MAP3_B") 
    @Column(name="value") 
    @MapKeyColumn(name="Key") 
    private Map<Employee, ParkingSpace> map3_B; 

Nhưng một lần nữa giá trị & ghi đè tên cột quan trọng bị bỏ qua. Có ai biết cách để thực thi các ghi đè tên cột này không.

Cảm ơn trước ...

CẬP NHẬT .... Sau khi xem xét phản hồi từ @wypieprz Tôi nghĩ rằng tôi biết chú thích chính xác cho phép bạn chỉ định tên cột cho giá trị & phím khi Bản đồ được khóa bởi một cơ bản với một giá trị thực thể.

Bằng việc sử dụng

sau
@ManyToMany(targetEntity = com.demo.bb.impls.Employee.class) 
    @JoinTable(name = "TEST_MAP1", [email protected](name="VALUE")) 
    @MapKeyColumn(name="KEY") 
    private Map<String, Employee> map1; 

Sử dụng inverseJoinColumn tôi có thể chỉ định tên cột giá trị.

Nhưng nếu khóa là thực thể tôi chưa tìm thấy cách để chỉ định tên cột khóa.Theo tài liệu, hãy nói @MapKeyColumn "chỉ định ánh xạ cho cột khóa của bản đồ có khóa bản đồ là loại cơ bản"

Tôi cũng không chắc chắn về chú thích sẽ sử dụng khi khóa là một thực thể & giá trị là căn bản. Sử dụng ManyToMany chỉ không hoạt động & Tôi nghĩ rằng tôi có thể phải sử dụng ElementCollection nhưng một lần nữa tôi không thể tìm thấy một cách để chỉ định tên cột chính.

CẬP NHẬT 2 ... Cảm ơn Peter Halicky đã giải đáp.

Tóm tắt để đặt tên cho tất cả 3 cột trên mỗi trường hợp bạn cần thực hiện như thế này.

@ElementCollection 
@CollectionTable(name = "TEST_MAP0", joinColumns = @JoinColumn(name = "DEPARTMENT")) 
@Column(name = "value") 
@MapKeyColumn(name = "key") 
private Map<String, String> map0; 

@ManyToMany(targetEntity = com.hibernate.elephants.Employee.class) 
@JoinTable(name = "TEST_MAP1", joinColumns = @JoinColumn(name = "DEPARTMENT"), inverseJoinColumns = @JoinColumn(name = "value")) 
@MapKeyColumn(name = "key") 
private Map<String, Employee> map1; 

@ElementCollection 
@CollectionTable(name = "TEST_MAP2", joinColumns = @JoinColumn(name = "DEPARTMENT")) 
@MapKeyClass(value = com.hibernate.elephants.Employee.class) 
@MapKeyJoinColumn(name = "key") 
@Column(name = "value") 
private Map<Employee, String> map2; 

@ManyToMany(targetEntity = com.hibernate.elephants.ParkingSpace.class) 
@JoinTable(name = "TEST_MAP3", joinColumns = @JoinColumn(name = "DEPARTMENT"), inverseJoinColumns = @JoinColumn(name = "value")) 
@MapKeyClass(value = com.hibernate.elephants.Employee.class) 
@MapKeyJoinColumn(name="key") 
private Map<Employee, com.hibernate.elephants.ParkingSpace> map3; 

Lưu ý hai trường hợp được chỉ định là ElementCollection nhưng hai trường hợp giá trị là một thực thể khác cần sử dụng ManyToMany.

+0

'@ ElementCollection' và' @ CollectionTable' nên chỉ được sử dụng với nhiều loại cơ bản và các embeddables, cho các tổ chức sử dụng '@ OneToMany' hoặc' @ ManyToMany'. Lưu ý: bạn không cần '@ MapKeyClass' và' targetEntity' cho java.util.Map đã nhập – wypieprz

+0

Tôi đang sử dụng @MapKeyClass vì java.util.Map đã nhập được sử dụng Giao diện cho Thực thể. Bạn cần MapKeyClass để cho biết lớp thực thể nào là instaniate. – James

+0

Như tôi đã nói trong câu hỏi ban đầu tôi đã thử sử dụng @ManyToMany nhưng nó vẫn không ghi đè tên cột khi khóa hoặc giá trị là một thực thể – James

Trả lời

5

Tôi đang sử dụng pháp nhân làm chìa khóa cho Bản đồ, như bên dưới. Sử dụng chú thích @MapKeyJoinColumn Tôi có thể chỉ định tên của cột là khóa của bản đồ. Điều này làm việc cho tôi trên Hibernate, không chắc chắn những gì khác JPA triển khai sẽ làm, nhưng nó chắc chắn là giá trị cố gắng.

@ElementCollection 
@CollectionTable(name="breed_descriptions", joinColumns={ @JoinColumn(name="breed") }) 
@Column(name="description") 
@MapKeyJoinColumn(name="language") 
private Map<Language, String> descriptions = new HashMap<>(); 
Các vấn đề liên quan