Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 不工作的JPA/Hibernate实例_Java_Hibernate_Jpa - Fatal编程技术网

Java 不工作的JPA/Hibernate实例

Java 不工作的JPA/Hibernate实例,java,hibernate,jpa,Java,Hibernate,Jpa,想象一种情况: @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

想象一种情况:

@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
始终返回false

在OpenJPA上工作正常


我应该提交一个bug吗?Hibernate 4.3.10

这是因为Hibernate使用运行时代理,而OpenJPA在支持代理方法的同时,更喜欢编译时或运行时字节码增强

见:


这是因为Hibernate使用运行时代理,而OpenJPA在支持代理方法的同时,更喜欢编译时或运行时字节码增强

见:


这很可能是因为hibernate正在返回一个代理

为什么会这样?要实现延迟加载,框架需要拦截返回延迟加载对象或对象列表的方法调用。它这样做是为了首先从数据库加载对象,然后允许您的方法运行。Hibernate通过创建代理类来实现这一点。如果您在debug中检查类型,您应该能够看到实际类型是一个生成的类,它不是从基类扩展而来的

如何避开它?我曾经遇到过这个问题,并且成功地使用了访问者模式,而不是使用
instanceof
。它确实增加了额外的复杂性,因此它不是每个人都喜欢的模式,但我认为它比使用
instanceof
更干净

如果您使用
instanceof
,则通常会使用
If…else
块检查不同类型。当您添加更多类型时,您必须重新访问这些块中的每个块。visitor模式的优点是,条件逻辑内置于类层次结构中,因此如果添加更多类型,则不太可能在使用这些类的任何地方进行更改


我发现这在实现访问者模式时很有用。

这很可能是因为hibernate正在返回一个代理

为什么会这样?要实现延迟加载,框架需要拦截返回延迟加载对象或对象列表的方法调用。它这样做是为了首先从数据库加载对象,然后允许您的方法运行。Hibernate通过创建代理类来实现这一点。如果您在debug中检查类型,您应该能够看到实际类型是一个生成的类,它不是从基类扩展而来的

如何避开它?我曾经遇到过这个问题,并且成功地使用了访问者模式,而不是使用
instanceof
。它确实增加了额外的复杂性,因此它不是每个人都喜欢的模式,但我认为它比使用
instanceof
更干净

如果您使用
instanceof
,则通常会使用
If…else
块检查不同类型。当您添加更多类型时,您必须重新访问这些块中的每个块。visitor模式的优点是,条件逻辑内置于类层次结构中,因此如果添加更多类型,则不太可能在使用这些类的任何地方进行更改


我发现这在实现访问者模式时很有用。

Hibernate返回代理对象。您可以对要测试的类()使用
isAssignableFrom()
方法,而不是实现访问者模式(如上所述)。

Hibernate返回代理对象。您可以在要测试的类()上使用
isAssignableFrom()
方法,而不是实现访问者模式(如上所述)。

不确定,但我认为这会起作用

public static boolean instanceOf(Object object, Class<?> superclass) {
    return superclass.isAssignableFrom(Hibernate.getClass(object));
}
公共静态布尔实例of(对象对象,类超类){
返回超类.isAssignableFrom(Hibernate.getClass(object));
}

不确定,但我认为这会起作用

public static boolean instanceOf(Object object, Class<?> superclass) {
    return superclass.isAssignableFrom(Hibernate.getClass(object));
}
公共静态布尔实例of(对象对象,类超类){
返回超类.isAssignableFrom(Hibernate.getClass(object));
}

如果将“p”赋值给“newa()”,那么它显然是A的一个实例,由基本Java实现(与JPA无关)。如果“p”不是A的实例,那么它是什么类?instanceof返回一个实例类型,如果您创建了这个实例,那么它应该返回true,如果不是,那么您应该询问是谁做的。您真的做了
Parent p=new A()
或者您通过Hibernate从数据库中获得
A
?发布您的真实代码,您在这里描述的情况显然是不可能的。这里有很多答案。但问题是什么还不清楚:)如果你把“p”赋值给“newa()”,那么它显然是A的一个实例,由basicjava实现(与JPA无关)。如果“p”不是A的实例,那么它是什么类?instanceof返回一个实例类型,如果您创建了这个实例,那么它应该返回true,如果不是,那么您应该询问是谁做的。您真的做了
Parent p=new A()
或者您通过Hibernate从数据库中获得
A
?发布您的真实代码,您在这里描述的情况显然是不可能的。这里有很多答案。但问题是什么还不清楚:)这个想法很有趣,但如果instanceof失败了,怎么能阻止它工作呢?它们肯定都检查了类层次结构吗?isAssignableFrom可以在运行时检查类,这很好,因为代理是在运行时生成的
instanceof
还可以在运行时检查对象。我想你的意思是instanceof在编译时需要类名,而isAssignableFrom可以使用getClass从对象获取类。但这不是问题所在。instanceof已编译,但运行时对象由于代理而不属于类型层次结构。有趣的想法是,如果instanceof失败,IsAssignable如何停止工作?它们肯定都检查了类层次结构吗?isAssignableFrom可以在运行时检查类,这很好,因为代理是在运行时生成的
instanceof
还可以在运行时检查对象。我想你的意思是instanceof在编译时需要类名,而isAssignableFrom可以使用getClass从对象获取类。这不是问题所在