Java dao层中的NullPointerException(只有persist有效)

Java dao层中的NullPointerException(只有persist有效),java,unit-testing,jpa,jakarta-ee,entitymanager,Java,Unit Testing,Jpa,Jakarta Ee,Entitymanager,我在寻找一个类似的问题,但没有实际的结果,所以我尝试用JPA/Maven创建简单的DAO层,但是如果我使用它,那么当我使用EntityManager直到类时,只有persist方法(insert)起作用,但是如果我使用before和auto注释创建EntityManager,而不使用任何其他内容,那么测试工作正常。我得到了NullPointerException,但我无法理解为什么(特别是为什么在这种情况下持久化方法有效) 抽象测试 public abstract class AbstractP

我在寻找一个类似的问题,但没有实际的结果,所以我尝试用JPA/Maven创建简单的DAO层,但是如果我使用它,那么当我使用EntityManager直到类时,只有persist方法(insert)起作用,但是如果我使用before和auto注释创建EntityManager,而不使用任何其他内容,那么测试工作正常。我得到了
NullPointerException
,但我无法理解为什么(特别是为什么在这种情况下持久化方法有效)

抽象测试

public abstract class AbstractPersistentTest {

  protected static EntityManagerFactory emf = Persistence.createEntityManagerFactory("Services");
  protected EntityManager em;
  protected EntityTransaction tx;

  @Before
  public void initEntityManager() throws Exception {
    em = emf.createEntityManager();
    tx = em.getTransaction();
  }

  @After
  public void closeEntityManager() throws SQLException {
    if (em != null) em.close();
  }

  protected Integer getRandomId() {
    return Math.abs(new Random().nextInt());
  }
}
模型

测试刀

public class TestDAO  {

//@PersistenceContext(unitName = "Services")
//private EntityManager emgr;

public Integer persist(String title,
                       String avatar,
                       String descr) {

    EntityManager em = EMgrUtil.createEntityManager();
    EntityTransaction transaction = em.getTransaction();
    Test test = new Test();

    try {

        transaction.begin();
        test.setTitle(title);
        test.setAvatar(avatar);
        test.setDescr(descr);
        em.persist(test);
        transaction.commit();

    }
    catch(RuntimeException e) {
        e.printStackTrace();
        transaction.rollback();

    } finally {
        //em.close();
    }

    return test.getId();

}

public Test findById(Integer id) {

    EntityManager em = EMgrUtil.getEntityManager();
    Test t = em.find(Test.class, id);
    return t;

}

public List<Test> findAll() {

    EntityManager em = EMgrUtil.getEntityManager();

    List<Test> list = em.createQuery("SELECT t FROM Test t", Test.class).getResultList();

    return list;

}
公共类TestDAO{
//@PersistenceContext(unitName=“服务”)
//私人实体经理emgr;
公共整数持久化(字符串标题,
字符串化身,
字符串描述){
EntityManager em=EMgrUtil.createEntityManager();
EntityTransaction=em.getTransaction();
测试=新测试();
试一试{
transaction.begin();
测试。设置标题(标题);
测试。设置化身(化身);
测试。设置描述(描述);
em.persist(试验);
commit();
}
捕获(运行时异常e){
e、 printStackTrace();
transaction.rollback();
}最后{
//em.close();
}
return test.getId();
}
公共测试findById(整数id){
EntityManager em=EMgrUtil.getEntityManager();
Test t=em.find(Test.class,id);
返回t;
}
公共列表findAll(){
EntityManager em=EMgrUtil.getEntityManager();
List List=em.createQuery(“从测试t中选择t”,Test.class).getResultList();
退货清单;
}
}

我还试图通过PersistenceContext注入EntityManager,但它不起作用

主要

公共类testDAO\u测试{
公共静态void main(字符串[]args){
TestDAO TestDAO=新的TestDAO();
List tests=testDAO.findAll();
用于(测试:测试){
系统输出打印LN(测试);
}
//Test Test=testDAO.findById(2);
//系统输出打印LN(测试);
}
}
persistence.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">

    <persistence-unit name="Services" transaction-type="RESOURCE_LOCAL">
        <description>
            Maven Test JPA
        </description>
        <!--provider>org.hibernate.ejb.HibernatePersistence</provider-->
        <class>com.spring_test2.jpa.models.Test</class>

        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/spring_test2" />
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="pwd" />
            <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>

            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>

    </persistence-unit>

</persistence>

Maven测试JPA
com.spring_test2.jpa.models.Test

在getEntityManager()中为实体管理器添加null检查,就像在createEntityManager()中所做的那样,如果它为null,则创建一个em


或者简单地在TestDAO中为findAll()和findById()方法使用createEntityManager()而不是getEntityManager()。

哪个类的哪一行引发了
nullPointerException
?您的实体管理器为Null您是否也获得了按ID查找的NPE?这就是为什么你有一个调试器,不是吗?请查看Stack Overflow的帮助文章。哦,是的,非常容易出错:(非常感谢
public class testDAO_test {

    public static void main(String[] args) {

        TestDAO testDAO = new TestDAO();

        List<Test> tests = testDAO.findAll();

        for(Test test : tests) {
            System.out.println(test);
        }

        //Test test = testDAO.findById(2);
        //System.out.println(test);
    }

}
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">

    <persistence-unit name="Services" transaction-type="RESOURCE_LOCAL">
        <description>
            Maven Test JPA
        </description>
        <!--provider>org.hibernate.ejb.HibernatePersistence</provider-->
        <class>com.spring_test2.jpa.models.Test</class>

        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/spring_test2" />
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="pwd" />
            <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>

            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>

    </persistence-unit>

</persistence>