Java JPA query.getResultList()返回错误的对象?

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

我执行下面的查询是为了测试JPA是否正在从数据库检索预期结果

我不明白为什么Ativo的
行instanceof
返回false
row.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();