簡體   English   中英

JPA/Hibernate 實例不工作

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM