为什么JPA EntityManager查询总是返回NullPointerException?

时间:2017-05-14 23:59:13

标签: java jpa jndi tomcat8

我试图在Java 8 Web项目中实现Java Persistence API(JPA)。在Tomcat 8上运行。

我使用的persistence.jar来自EclipseLink

我已经设置了我的persistence.xml配置,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
  <persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">
    <persistence-unit name="myDatabase" transaction-type="JTA">
      <non-jta-data-source>jdbc/myDB</non-jta-data-source>
    </persistence-unit>
  </persistence>

我的JNDI资源在context.xml中定义,我测试过它可以作为另一个类中的常规DataSource查询,因​​此数据库连接正常运行。

我已经关注了 Java EE 7:大图片,&#39;第12章:现代回忆:Java持久性API&#39;由丹尼考沃德博士,但无法获得任何em.find,em.createNamedQuery等工作。

使用实体管理器访问我的数据:[stub]

@Singleton
public class JPAPersonDataImpl {
    @PersistenceUnit
    private EntityManager em;

    private Person getPersonById(int id) {
        return (em.find(Person.class, id));
    }
}

如果使用实体管理器工厂,我的数据访问:[stub]

@Singleton
public class JPAPersonDataImpl {
    @PersistenceUnit(unitName = "myDatabase")
    private EntityManagerFactory entityManagerFactory;

    private Person getPersonById(int id) {
        EntityManager em = entityManagerFactory.createEntityManager();
        try {
            return (em.find(Person.class, id));
        } finally {
            em.close();
        }
    }
}

我的Person.class [stub]

@Entity
@NamedQueries(
        {
                @NamedQuery(
                        name = "Person.getAllPersons",
                        query = "select m from Person m"
                ),
                @NamedQuery(
                        name = "Person.getPersonByUsername",
                        query = "select m from Person m where m.userName = :userName"
                ),
                @NamedQuery(
                        name = "Person.getLastPersonCreated",
                        query = "select m from Person m order by m.PersonId desc"
                ),
                @NamedQuery(
                        name = "Person.getUsernames",
                        query = "select m.userName from Person m"
                )
        }
)
public class Person implements Serializable {
    @Id
    @Column(name="PersonId")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    private String userName;
    private String firstName;
    private String surname;
    private Date joined;

    public Person() {}

    public Person(int id, String userName, String firstName, String surname, Date joined) {
        this.id = id;
        this.userName = userName;
        this.firstName = firstName;
        this.surname = surname;
        this.joined = joined;
    }

    public int getId() {
        return this.id;
    }

    public String getUserName() {
        return this.userName;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public String getSurname() {
        return this.surname;
    }

    public Date getJoinedDate() {
        return this.joined;
    }
}

执行NamedQueries的示例(我已经尝试了所有的TypedQuery,Query并创建了一个Native查询 - 都返回了NullPointer):

@Singleton
public class JPAPersonDataImpl {
    @PersistenceUnit(unitName = "myDatabase")
    private EntityManagerFactory entityManagerFactory;

    // This can also be modifed to use EntityManager instead of EntityManagerFactory
    private boolean userNameIsInUse(String username) {
        EntityManager em = entityManagerFactory.createEntityManager();
        try {
            TypedQuery<Person> queryUserNames = em.createNamedQuery("Person.getUsernames", Person.class);
            List queryResultList = queryUserNames.setMaxResults(1).getResultList();
            return (matchInList(queryResultList, username));
        } finally {
            em.close();
        }
    }
}

当存在有效的JNDI资源时,为什么任何访问尝试(查询,持久,删除,查找等)都会返回NullPointerException?是否有一个简单的测试可以确定EntityManager是否设置正确?

1 个答案:

答案 0 :(得分:1)

您应该了解实体管理员的管理方式。 i)集装箱管理 ii)应用程序管理。 在您的情况下,由于Tomcat不是J2EE容器,请查看Application managed EM。  看看这个。 https://docs.oracle.com/javaee/7/tutorial/persistence-intro003.htm