【问题标题】:Why is my Entity Manager returning empty ResultLists?为什么我的 Entitymanager 返回空的结果集?
【发布时间】:2019-11-01 21:32:39
【问题描述】:

我的 Web 应用程序陷入了困境。

对于我的学校项目,我们必须从经典的 JDBC 集成迁移到 JPA 集成。至于我自己,我决定使用 Hibernate JPA Framework。我已经尝试在 SessionBean 中的 main 中,它在那里工作。但每当我将它集成到 Web Servlet 中时,我注意到它返回了空列表。我尝试使用System.out.println() 显示列表的大小。

无论如何,我认为问题可能出在我的persistence.xml 中,更具体地说,其中缺少<jta-data-source>something here</jta-data-source>

这是我的persistence.xml,也许你可以看到我遇到问题的地方:

<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="PERSISTENCE" transaction-type="JTA">
    <description>Hibernate JPA Configuration Example</description>
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>JavaBeans.Employee</class>
    <class>JavaBeans.User</class>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/JEEPRJ?serverTimezone=Europe/Paris"/>
      <property name="javax.persistence.jdbc.user" value="jee"/>
      <property name="javax.persistence.jdbc.password" value="jee"/>
      <property name="javax.persistence.jdbc.serverTimezone" value="Europe/Paris"/>
      <property name="javax.persistence.jdbc.useSSL" value="false"/>
      <property name="hibernate.show_sql" value="true"/>
      <property name="hibernate.hbm2ddl.auto" value="update"/>
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
      <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
    </properties>
  </persistence-unit>
</persistence>

这是我的员工会话 Bean:

package SessionBeans;

import JavaBeans.Employee;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;
import javax.persistence.Query;

/**
 *
 */
@Stateless
public class EmployeeSB {

    @PersistenceContext(name="PERSISTENCE")
    EntityManager em;

    public List<Employee> getAllEmployees(){

        String query = "SELECT e FROM Employee e ";
        Query q  = em.createQuery(query);
        List<Employee> employees = q.getResultList();
        if(employees!=null){
            System.out.println("it's not null list size : " + q.getResultList().size());
            for(Employee emp:employees){
                System.out.println("id  : " + emp.getId());
            }
            return employees;
        }
        System.out.println("it's null");
        return employees;
    }

还有我的 Employee 类:

@Entity
@Table(name = "EMPLOYE")
public class Employee implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Integer id;
    @Size(max = 255)
    @Column(name = "NOM")
    public String nom;
    @Size(max = 255)
    @Column(name = "PRENOM")
    public String prenom;
    @Size(max = 255)
    @Column(name = "TELDOMICILE")
    public String telDomicile;
    @Size(max = 255)
    @Column(name = "TELPORTABLE")
    public String telPortable;
    @Size(max = 255)
    @Column(name = "TELPRO")
    public String telPro;
    @Size(max = 255)
    @Column(name = "ADRESSE")
    public String adresse;
    @Size(max = 255)
    @Column(name = "CODEPOSTAL")
    public String codePostal;
    @Size(max = 255)
    @Column(name = "VILLE")
    public String ville;
    // @Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
    @Size(max = 255)
    @Column(name = "EMAIL")
    public String email;


    public Employee() {

    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getNom() {
        return nom;
    }

    public void setNom(String nom) {
        this.nom = nom;
    }

    public String getPrenom() {
        return prenom;
    }

    public void setPrenom(String prenom) {
        this.prenom = prenom;
    }

    public String getTelDomicile() {
        return telDomicile;
    }

    public void setTelDomicile(String telDomicile) {
        this.telDomicile = telDomicile;
    }

    public String getTelPortable() {
        return telPortable;
    }

    public void setTelPortable(String telPortable) {
        this.telPortable = telPortable;
    }

    public String getTelPro() {
        return telPro;
    }

    public void setTelPro(String telPro) {
        this.telPro = telPro;
    }

    public String getAdresse() {
        return adresse;
    }

    public void setAdresse(String adresse) {
        this.adresse = adresse;
    }

    public String getCodePostal() {
        return codePostal;
    }

    public void setCodePostal(String codePostal) {
        this.codePostal = codePostal;
    }

    public String getVille() {
        return ville;
    }

    public void setVille(String ville) {
        this.ville = ville;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }





    public Employee(String nom, String prenom, String telDomicile, String telPortable, String telPro, String adresse, String codePostal, String ville, String email) {
        this.nom = nom;
        this.prenom = prenom;
        this.telDomicile = telDomicile;
        this.telPortable = telPortable;
        this.telPro = telPro;
        this.adresse = adresse;
        this.codePostal = codePostal;
        this.ville = ville;
        this.email = email;
    }



    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Employee)) {
            return false;
        }
        Employee other = (Employee) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "JavaBeans.Employee[ id=" + id + " ]";
    }
}

(别介意法语哈哈)。

无论如何,如果有人看到实体管理器返回空列表的原因,那将对我有很大帮助,让我明白我在哪里犯了愚蠢的错误。

非常感谢大家,祝你有美好的一天,

票价。

【问题讨论】:

    标签: java xml hibernate jpa jakarta-ee


    【解决方案1】:

    如果您在 servlet 中复制/粘贴上述会话 bean 的相同代码,请注意事务管理。由于会话 bean 将事务作为其默认行为进行管理,因此您不必在 bean 中管理它们。但是 servlet 没有这种行为,实现它们是您自己的责任。

    请注意,在属于视图层的 servlet 中实现与数据库相关的作业是一种反模式。更好的方法是使用会话 bean 来实现这种功能,并在视图层内调用它们。

    【讨论】:

    • 谢谢艾哈迈德。我正在为我的数据库操作使用会话 Bean。问题是我似乎无法从这些操作中获得结果......
    • 如果您可以在会话 bean 中检索数据,您应该能够通过调用该会话 bean 在 servlet 中获得相同的结果。你确定,你做的和你解释的一样吗?如果是这样,我需要查看您的代码的更多详细信息。
    • 这就是问题所在,我无法在会话 Bean 中检索数据...但是,如果我通过 public static void main() 中的实体管理器工厂手动创建实体管理器并逐个配置它,我确实通过手动创建的实体管理器接收数据。问题是会话 Bean 中的实体管理器没有接收到数据。
    【解决方案2】:

    我设法找到了问题所在。系好安全带,因为它会很长。

    在我的persistence.xml 中,我从未定义过&lt;jta-data-source&gt;&lt;/jta-data-source&gt;,因为我不明白它的目标以及我们为什么需要使用它。

    从那时起,我积累了大量的知识和智慧(不是真的,基本上是试错法)。

    所以。说够了。直奔答案。

    正如我之前所说,&lt;jta-data-source&gt;&lt;/jta-data-source&gt; 没有在 persistence.xml 中定义,以代替巨大的 &lt;properties&gt;&lt;/properties&gt; 部分。

    Netbeans IDE 在您的目录的 WEB-INF 文件夹中生成一个文件。它被称为glassfish-resources.xml。我们的persistence.xml 与它有些绑定。在资源文件中,我们定义了所有的 JDBC 连接属性。我们通过 JNDI 在池中命名它。

    因此我们的新 `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="m1se_appv2_war_1.0PU" transaction-type="JTA">
        <jta-data-source>java:app/DBJEE</jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties/>
      </persistence-unit>
    </persistence>
    

    还有著名的 glassfish-resources.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
    <resources>
        <jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="mysql_JEEPRJ_jeePool" non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.DataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
            <property name="serverName" value="localhost"/>
            <property name="portNumber" value="3306"/>
            <property name="databaseName" value="JEEPRJ"/>
            <property name="User" value="jee"/>
            <property name="Password" value="***"/>
            <property name="URL" value="jdbc:mysql://localhost:3306/JEEPRJ?useSSL=false&amp;serverTimezone=Europe/Paris"/>
            <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        </jdbc-connection-pool>
        <jdbc-resource enabled="true" jndi-name="java:app/DBJEE" object-type="user" pool-name="mysql_JEEPRJ_jeePool"/>
    </resources>
    

    顺便说一句,如果您使用 5.7 以上的 MySQL 版本,如果您不打算使用它,请绝对将 URL 中的 useSSL 属性定义为 false。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-05
      • 2015-10-10
      • 1970-01-01
      • 2016-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多