Tôi có một vấn đề kỳ lạ nơi hibernate không tạo ra các loại thực thể dự kiến trong một relataionship nhiều. Chúng tôi có các đối tượng sau với hệ thống phân cấp lớp (giản thể):Hibernate tạo subtype thực thể sai trong mối quan hệ
@Entity
@Table(name = "A")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING, length = 1)
public abstract class A {
@Id
...
public Long getId() { ... }
...
}
@Entity
@DiscriminatorValue("1")
public class A1 extends A {
...
}
@Entity
@DiscriminatorValue("2")
public class A2 extends A {
...
}
@Entity
@Table(name = "B")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING, length = 1)
public abstract class B<AClass extends A> {
protected AClass a;
@Id
...
public Long getId() { ... }
...
public abstract AClass getA();
public void setA(AClass a) { ... }
}
@Entity
@DiscriminatorValue("1")
public class B1 extends B<A1> {
...
@Override
@ManyToOne(fetch = EAGER)
@JoinColumn(name = "A_ID")
public A1 getA() { ... }
}
@Entity
@DiscriminatorValue("2")
public class B2 extends B<A2> {
...
@Override
@ManyToOne(fetch = EAGER)
@JoinColumn(name = "A_ID")
public A2 getA() { ... }
}
Trong persistence.xml
cả các đối tượng được khai báo theo thứ tự
A2
A1
B2
B1
Bây giờ tôi có thể tạo thể hiện của A1 và B1 trong DB:
A1 a1 = new A1();
entityManager.persist(a1);
B1 b1 = new B1();
b1.setA(a1);
entityManager.persist(b1);
Tôi có thể xem các trường hợp được lưu vào DB chính xác mỗi ID có 1, DISCRIMINATOR cũng là 1, A_ID trong B cũng là 1.
Khi tôi bây giờ cố gắng để có được B (trong một phiên hibernate):
B b = entityManager.find(B.class, 1L);
tôi nhận được ngoại lệ:
org.hibernate.PropertyAccessException: Exception occurred inside getter of B
Caused by: java.lang.ClassCastException: A2 cannot be cast to A1
at B1.getA(B1.java:61)
... 108 more
Với gỡ lỗi tôi phát hiện ra rằng chế độ ngủ đông đang tạo ra các thực thể chính xác loại B1 và tạo ra một thực thể không chính xác của loại A2 cho mối quan hệ với A. Loại đúng A1 được tạo ra nếu thứ tự trong persistence.xml
được thay đổi. Có vẻ như hibernate không lấy cột DISCRIMINATOR của bảng A trong trường hợp này nhưng luôn luôn tạo kiểu con đầu tiên được khai báo trong cấu hình. Làm thế nào để sửa cái này? Có điều gì sai với chú thích không?
(Tôi cũng đã thực hiện cụ thể của phương pháp getA()
với các chú thích của nó trong siêu kiểu B lúc đầu, nhưng điều này dẫn đến vấn đề tương tự.)
Cảm ơn câu trả lời của bạn. Hôm qua tôi đã có cơ hội để kiểm tra điều này và nó hoạt động trong kịch bản của câu hỏi :) – Gandalf