Java JPA query.getResultList()返回错误的对象?
我执行下面的查询是为了测试JPA是否正在从数据库检索预期结果 我不明白为什么Ativo的Java JPA query.getResultList()返回错误的对象?,java,jpa,jpql,Java,Jpa,Jpql,我执行下面的查询是为了测试JPA是否正在从数据库检索预期结果 我不明白为什么Ativo的行instanceof返回falserow.getClass()返回br.meuspila.entity.Ativo,打印的对象是br.meuspila.entity.Ativo[id=1]。类的导入是正常的,并且在同一个包中没有其他名为Ativo的类 // OUTPUT: INFO: br.meuspila.entity.Ativo[ id=1 ] // row INFO: false // r
行instanceof
返回falserow.getClass()
返回br.meuspila.entity.Ativo
,打印的对象是br.meuspila.entity.Ativo[id=1]
。类的导入是正常的,并且在同一个包中没有其他名为Ativo的类
// OUTPUT:
INFO: br.meuspila.entity.Ativo[ id=1 ] // row
INFO: false // row instanceof Ativo?
INFO: class br.meuspila.entity.Ativo // row.getClass()
MyMB类别:
package br.meuspila.mb;
import br.meuspila.database.JpaUtil;
import br.meuspila.entity.Ativo;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
@ManagedBean
@SessionScoped
public class MyMB {
public String teste = "testando, 123";
/**
* Creates a new instance of ManagedBean
*/
public MyMB() {
}
public String getTeste() {
return teste;
}
public void setTeste(String teste) {
this.teste = teste;
}
public void actionTeste() {
EntityManager em = JpaUtil.getInstance().createEntityManager();
try {
EntityTransaction t = em.getTransaction();
t.begin();
Query query = em.createQuery("select x from Ativo x");
List result = query.getResultList();
for (Object row : result) {
System.out.println(row);
System.out.println(row instanceof Ativo);
System.out.println(row.getClass());
}
t.commit();
} finally {
em.close();
}
}
}
JpaUtil等级:
package br.meuspila.database;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public final class JpaUtil {
private JpaUtil() {
}
public static JpaUtil getInstance() {
return JpaUtilHolder.INSTANCE;
}
private static class JpaUtilHolder {
private static final JpaUtil INSTANCE = new JpaUtil();
private static final EntityManagerFactory EMF = Persistence.createEntityManagerFactory("MeusPila3_WebPU");
}
public EntityManager createEntityManager() {
return JpaUtilHolder.EMF.createEntityManager();
}
}
persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="MeusPila3_WebPU" transaction-type="JTA">
<jta-data-source>jdbc/meuspiladb</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
</properties>
</persistence-unit>
</persistence>
注意:
JpaUtil
类在br.meuspila.database
包中。随机加载程序出现!我无法不看到整个应用程序,但这里有一个快速修复方法:从WEB-INF/lib
中删除Ativo
类定义(更好地处理整个bean包),并将所有bean放在容器库路径的存档中(请参阅容器文档)。这样,由于委托,bean类将始终从同一个加载程序加载
同样,确保
WEB-INF
中没有bean类定义(既不在JAR中,也不在plain.class文件中)。如果您使用支持以下内容的构建工具,请尝试将bean放在一个单独的项目(子项目/模块/子模块)中,使其他项目依赖于它,并将依赖范围设置为提供的(或等效的,即编译和测试需要类,但不能包含在输出工件、war、jar或ear中)正如@Rafaelle所建议的,我认为问题出在我的单身班:JpaUtil。通过删除该类修复了代码
也许如果我换个班,问题就会解决了。我注意到我做了一些(可能)错误的事情:在singleton中,我试图在内部类(JpaUtilHolder)中创建2个实例。。。也许我应该从该内部类中删除EMF,并将其作为JpaUtil类的非静态属性
已在多年电价确定中替换:
EntityManager em = JpaUtil.getInstance().createEntityManager();
借
在我的例子中,实体的复合PK与表的PK不同。
修复映射,解决问题。除了使用错误的类之外,我看不到打印
false
的任何其他原因。你需要给我们看更多的代码。也可能是导入。假设您的导入是正确的,并且没有导入其他的Ativo类,那么很可能是类加载器的问题。你在使用什么JPA实现,在什么环境下?给我一分钟。。。我将发布完整的代码。这不是完整的代码:)如果这真的是一个类加载问题,我们需要了解JpaUtil是如何工作的,这是最重要的部分。我们可以看到这是一个单例,顺便说一句,单例常常与许多意外的bug相关:请尝试确定这是否是一个类加载问题。检索一行后创建一个Activo
对象,然后比较它们的类classloader(使用调试器或打印它们)。如果两者不同,那么我们有一个类加载问题,您应该更好地描述您的环境(例如,它是一个webapp吗?您是否将Activo类定义部署在两个不同的jar中,如say container lib和app lib?),谢谢您的回复!你认为我应该使用Eclipse或其他IDE而不是Netbeans吗?我没有更改任何类加载器配置,我想知道为什么会发生这种情况……应用程序使用的加载器不依赖于IDE-主题不适合注释,所以要理解这个bug,最好的办法是阅读关于类加载机制的内容并玩几天(如果可以的话)。您是否尝试了我建议的修复方法,即从除容器的lib路径(或类路径)之外的所有位置删除bean定义?我忘了说:我的Ativo类不在WEB-INF/lib。但是我看到编译后的类将WEB-INF\classes
,最后我认为你关于单例的第一句话是正确的。那个单例(JpaUtil)被删除了,现在一切正常。我认为EntityManagerFactory是因为Singleton而过早创建的。。。你建议用什么来代替单件呢?单件不是问题,它们只是一种模式。问题是,这在Java中是一种危险的模式,因为它涉及到静态的,因此涉及到语言语义和运行时平台的知识,这绝对不是初学者可以使用的。另一方面,它是描述的最简单的模式之一,因此很容易获得它并尽可能多地应用它-但是嘿!跌倒是学习走路的必要条件:)如果你能分享整个项目以及重现bug所需的步骤,那会很有帮助,这样我们就能真正理解错误所在,更多的人可能会从中受益:)也许吧,但我认为对Persistence.createEntityManagerFactory(…)的静态调用正在生成错误。。。
EntityManager em = JpaUtil.getInstance().createEntityManager();
EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
EntityManager em = emf.createEntityManager();