TypedQuery<String> 上的 NullPointerException -- JavaEE Spring JPA2.1

Posted

技术标签:

【中文标题】TypedQuery<String> 上的 NullPointerException -- JavaEE Spring JPA2.1【英文标题】:NullPointerException on TypedQuery<String> -- JavaEE Spring JPA2.1 【发布时间】:2016-02-24 13:59:38 【问题描述】:

Java Spring (4.0.1) Web 应用程序(在 NetBeans 8.0.2 中设置)。没有 Maven 或 Hibernate。 EclipseLink (JPA 2.1) 持久性。 构建和部署没问题。运行时在服务器日志中获取以下内容:

StandardWrapperValve[dispatcher]:Servlet 调度程序的 Servlet.service() 抛出异常 java.lang.NullPointerException 在 main.CourseDao.getAllCoursename(CourseDao.java:29)

CourseDao如下:

package main;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
public class CourseDao 
@PersistenceContext private EntityManager em;

public List<String> getAllCoursename()  
   TypedQuery<String> query = em.createQuery("SELECT c.coursename FROM Course AS c", String.class);
   return query.getResultList();
   

第 29 行是

TypedQuery<String> query = em.createQuery("SELECT c.coursename FROM Course AS c", String.class);

因此,它在数据库查询中为空。 但是从主要对象作为实体部署的意义上来说,持久性似乎还可以:因此 Course.java 在部署时在数据库中创建了一个表 Course。

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="ReportsPU" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/reports</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="javax.persistence.schema-generation.database.action" value="create"/>
      <property name="eclipselink.logging.level" value="FINE"/>
      <property name="eclipselink.ddl-generation" value="create-tables"/>
    </properties>
  </persistence-unit>
</persistence>

Course.java如下:

package main;
import java.io.Serializable;
import javax.persistence.*;

@Entity
public class Course  implements Serializable 
 private int id;
 private String coursecode;
 private String coursename;

public Course() 
    
public Course(int id) 
    this.id = id;
    
 public Course(int id, String coursecode, String coursename) 
   this.id = id;
   this.coursecode = coursecode;
   this.coursename = coursename;
     
@Id 
@Column(name="ID")
@GeneratedValue
public int getId() 
    return this.id;
      
public void setId(int id) 
    this.id = id;
    
@Column(name="COURSECODE", length=12)
public String getCoursecode() 
    return this.coursecode;
    
public void setCoursecode(String coursecode) 
    this.coursecode = coursecode;
    
@Column(name="COURSENAME", length=256)
public String getCoursename() 
    return this.coursename;
    
public void setCoursename(String coursename) 
    this.coursename = coursename;
    

COURSE 表目前只有 3 行,没有空值。

applicationContext.xml如下:

<?xml version='1.0' encoding='UTF-8' ?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:p="http://www.springframework.org/schema/p"
   xmlns:aop="http://www.springframework.org/schema/aop"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource"
    p:driverClassName="org.apache.derby.jdbc.EmbeddedDriver"
    p:url="jdbc:derby://localhost:1527/reports"
    p:username="*******"
    p:password="*******" />
</beans>

我已经用 Hibernate 而不是 EclipseLink JPA2.1 尝试了所有这些 - 最终遇到了同样的问题。

CourseDao 目前由 index.jsp 调用(是的,这是一个便宜的第一次尝试;几乎不是最佳实践;但这不是发生错误的地方):

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@page import="main.*"%>
<jsp:useBean id="courseDao" class="main.CourseDao" scope="request" />
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head> etc </head>
<body>
 <hr><ol> 
    <% for (String coursename : courseDao.getAllCoursename())  %>
        <li> <%= coursename %> </li>
    <%  %>
    </ol><hr>
 </body>
</html>

我要做的就是从带有 JPQL 查询的表中选择一列,并将其推送到前面的 jsp。简单的东西。非常感谢任何想法或帮助。谢谢。

【问题讨论】:

我猜 em(Entity Manager reference object) 为空。进行调试并检查 em 是否为空。 你是对的——它是空的。 ..所以现在我想弄清楚为什么会这样.. 我认为这可能与persistence.xml 文件的位置有关。它位于根目录(NetBeans 放置它的位置)下的“配置文件”目录中。 该应用程序只是一个 Web 应用程序,而不是具有 WAR 和 EJB 文件夹的企业应用程序... 【参考方案1】:

您无法通过&lt;jsp:useBean id="courseDao" class="main.CourseDao" scope="request" /&gt; 访问 Spring Bean(这将创建一个“普通”Java Bean,但您的 DAO 必须是 Spring Bean)。

你应该看看 Spring MVC(例如这个tutorial),看看 Spring 和 JSP 是如何协同工作的。

【讨论】:

谢谢。我一直致力于修复 jsp - 但不断出现的问题与 courseDao 本身有关,而不是 jsp。目前,我对企业应用程序结构的处理方式有所不同,但很可能会回到这一点。 @anvw:向你的 DAO 添加一个默认构造函数,它会打印一些日志语句。如果此日志语句仅出现一次(在启动应用程序时),那么一切都很好。但是,如果每个请求都出现日志语句(在呈现该 jsp 时),那么问题仍然存在:您必须使用 Spring Bean 并且不能使用 &lt;jsp:useBean

以上是关于TypedQuery<String> 上的 NullPointerException -- JavaEE Spring JPA2.1的主要内容,如果未能解决你的问题,请参考以下文章

检索时休眠 EntityExistsException

JPA 1.0 的 TypedQuery 等效项

JPQL typedquery 中 IN 子句的解析

java 使用jpa参数+ TypedQuery进行示例搜索查询并继承常见的crud操作

尽管具有正确的 DTO,但无法使用请求的结果类型为具有多个返回的查询创建 TypedQuery

使用 Like 和 % % 运算符的休眠命名查询?