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

NullPointerException in dao layer (only persist is working)

我一直在寻找类似的问题,但没有实际结果,所以我试图用 JPA/Maven 创建简单的 DAO 层,但如果我使用它,那么只有持久化方法(插入)在我使用 EntityManager 直到 class,但如果我创建 EntityManager 之前没有任何其他注释和自动注释,测试工作正常。我得到 NullPointerException,但我不明白为什么(尤其是为什么在这种情况下 persist 方法有效)。

摘要测试

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());
  }
}

型号

@Entity
@Table(name = "test")
public class Test implements Serializable {

@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;

@Column(name = "title", nullable = false)
@Size(min = 0, max = 255)
private String title;

@Column(name = "descr", nullable = false, length = 16777215, columnDefinition = "Mediumtext")
private String descr;

@Column(name = "avatar", nullable = false)
private String avatar;

@Column(name = "date_add", nullable = false, insertable = false, updatable = false, columnDefinition = "Datetime DEFAULT CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
private Date date_add;

public Test() {
}

//getters and setters

测试 DAO

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;

}

}

我也尝试通过 PersistenceContext 注入 EntityManager,但它不起作用

主要

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.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>

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

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