我有一個奇怪的問題,即hibernate沒有在多對一的關係中創建預期的實體類型。我們有子類層次結構下面的實體(簡化):Hibernate在關係中創建錯誤的實體子類型
@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() { ... }
}
在persistence.xml
兩個實體在
A2
A1
B2
B1
現在我在DB創建A1的實例和B1的順序聲明:
A1 a1 = new A1();
entityManager.persist(a1);
B1 b1 = new B1();
b1.setA(a1);
entityManager.persist(b1);
我可以看到實例保存到數據庫的每個ID都是1,DISCRIMINATOR也是1,B中的A_ID也是1.
現在當我試圖讓B(在另一個Hibernate的Session):
B b = entityManager.find(B.class, 1L);
我得到異常:
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
調試,我發現,Hibernate是創造正確的實體鍵入B1併爲與A的關係創建類型A2的不正確實體。如果persistence.xml
中的順序發生更改,則會創建正確的類型A1。在這種情況下,hibernate似乎並未將A表的DISCRIMINATOR列考慮在內,但總是創建在配置中聲明的第一個子類型。這怎麼解決?註釋有問題嗎?
(我也有其在超B中第一註釋的具體實施方法getA()
的,但是這會導致類似的問題。)
謝謝你的回答。昨天我有機會測試這個,它在問題的場景中工作:) – Gandalf