繁体   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