[英]Hibernate: How to test a JPA/Hibernate Predicate instance?
[英]JPA/Hibernate instance of not working
想象一種情況:
@javax.persistence.Inheritance(strategy=javax.persistence.InheritanceType.JOINED)
@javax.persistence.DiscriminatorColumn
@javax.persistence.Entity
@javax.persistence.Table(name="PARENT")
public abstract class Parent{
...
}
@javax.persistence.Entity
@javax.persistence.Table(name="A")
public class A extends Parent{
...
}
@javax.persistence.Entity
@javax.persistence.Table(name="B")
public class B extends Parent{
...
}
Parent p = new A();
現在我們稱之為:
p instance of A
總是返回假!!
在 OpenJPA 上工作正常!
我應該提交錯誤嗎? 休眠 4.3.10
這很可能是因為休眠狀態返回了代理。
為什么這樣做呢? 要實現延遲加載,框架需要攔截您的方法調用,這些方法返回延遲加載的對象或對象列表。 這樣做是為了可以首先從數據庫加載對象,然后允許您的方法運行。 Hibernate通過創建代理類來做到這一點。 如果您在調試中檢查類型,則應該能夠看到實際類型是生成的類,它不是從基類擴展的。
如何解決呢? 我曾經遇到這個問題,成功地使用了訪問者模式,而不是使用instanceof
。 它確實增加了額外的復雜性,因此不是每個人都喜歡的模式,但是恕我直言,這是比使用instanceof
更干凈的方法。
如果使用instanceof
則通常會以if...else
阻止檢查不同類型。 隨着添加更多類型,您將不得不重新訪問每個這些塊。 訪問者模式的優勢在於,條件邏輯內置於您的類層次結構中,因此,如果添加更多類型,則可以減少使用這些類的任何地方的更改。
在實現訪客模式時,我發現本文很有用。
這是因為Hibernate在支持代理方法的同時使用了運行時代理和OpenJPA,而是傾向於編譯時或運行時字節碼增強。
看到:
http://openjpa.apache.org/entity-enhancement.html
//Hibernate
Entity e = repository.load(entityId); // may return a proxy
//OpenJPA
Entity e = repository.load(entityId); //will return an (enhanced) actual instance of E
Hibernate返回代理對象。 而不是實現Visitor模式(如描述在這里 ),你可以使用isAssignableFrom()
你要測試的類方法( https://docs.oracle.com/javase/8/docs/api/java/lang/ Class.html#isAssignableFrom-java.lang.Class- )。
不確定,但是我認為這會起作用。
public static boolean instanceOf(Object object, Class<?> superclass) {
return superclass.isAssignableFrom(Hibernate.getClass(object));
}
您可以嘗試取消代理您的對象:
/**
*
* @param <T>
* @param entity
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T initializeAndUnproxy(T entity) {
if (entity == null) {
// throw new NullPointerException("Entity passed for initialization is null");
return null;
}
Hibernate.initialize(entity);
if (entity instanceof HibernateProxy) {
entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
}
return entity;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.