2017-10-21 293 views
0

我在我的Java EE应用程序中与我的Wildfly服务器结合使用hibernate以将我的类保存在mysql数据库中。 到目前为止,这工作正常,但现在我正在编写单元测试,并且我正在为我得到的一些错误疯狂。Java休眠JPA错误与JUnit测试

我想测试我DAO层在我的单元测试,但我得到这些错误:

Caused by: org.hibernate.engine.jndi.JndiException: Error parsing JNDI name [java:/MySqlDS] 
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial 

我的persistence.xml IST这样的:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.0" 
    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"> 

    <persistence-unit name="primary"> 
     <jta-data-source>java:/MySqlDS</jta-data-source> 
     <class>org.se.bac.data.Employee</class> 
     <properties> 
      <!-- Properties for Hibernate --> 
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> 
        <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> 
      <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/empdb?useSSL=false"/> 
      <property name="hibernate.connection.username" value="student"/> 
      <property name="hibernate.connection.password" value="student"/> 


      <!-- 
       SQL stdout logging 
      --> 
      <property name="hibernate.show_sql" value="true"/> 
      <property name="hibernate.format_sql" value="true"/> 
      <property name="use_sql_comments" value="true"/> 
     </properties> 
    </persistence-unit> 


</persistence> 

所以,我在这里使用jta-data-source>,如你所见。

如果我删除这条线,我的测试进行得很好!但我无法再用maven构建我的项目了。

Error: 
    Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] 
    Caused by: org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [com.mysql.jdbc.Driver] 
    Caused by: java.lang.ClassNotFoundException: Could not load requested class : com.mysql.jdbc.Driver"}} 

,因为我在persistence.xml中

删除行,他无法找到数据源如何管理让我的应用程序都运行。测试和当然的maven构建?

这里是我的测试:(设置已导致错误):

package org.se.bac.data.dao; 

import java.util.List; 

import javax.persistence.EntityManager; 

import org.junit.After; 
import org.junit.AfterClass; 
import org.junit.Assert; 
import org.junit.Before; 
import org.junit.BeforeClass; 
import org.junit.Test; 
import org.se.bac.data.model.Employee; 

public class EmployeeDAOTest 
{ 
    private static final JdbcTestHelper JDBC_HELPER = new JdbcTestHelper(); 
    private final static JpaTestHelper JPA_HELPER = new JpaTestHelper(); 

    private EntityManager em = JPA_HELPER.getEntityManager("primary"); 
    private EmpDAO dao; 

    @BeforeClass 
    public static void init() 
    { 

     JDBC_HELPER.executeSqlScript("sql/test/dropEmployeeTable.sql"); 
     JDBC_HELPER.executeSqlScript("sql/test/createEmployeeTable.sql"); 
    } 

    @AfterClass 
    public static void destroy() 
    { 
     //JDBC_HELPER.executeSqlScript("sql/test/dropEmployeeTable.sql");  
    } 


    @Before 
    public void setUp() 
    { 
     JDBC_HELPER.executeSqlScript("sql/test/dropEmployeeTable.sql"); 
     JDBC_HELPER.executeSqlScript("sql/test/createEmployeeTable.sql"); 
     dao = new EmpDAOImpl();  
     dao.setEm(em); 

     JPA_HELPER.txBegin(); 


     Employee emp2 = new Employee(); 
     emp2.setFirstname("Max"); 
     emp2.setLastname("Muster"); 
     emp2.setHiredate("23-12-1991"); 

     dao.insert(emp2); 
    } 

而且JPAHELPER类:

package org.se.bac.data.dao; 

import javax.persistence.EntityManager; 
import javax.persistence.EntityManagerFactory; 
import javax.persistence.EntityTransaction; 
import javax.persistence.Persistence; 


public class JpaTestHelper 
{ 
    /* 
    * Property: persistenceUnitName 
    */ 
    private String persistenceUnitName; 
    public String getPersistenceUnitName() 
    { 
     return persistenceUnitName; 
    } 
    public void setPersistenceUnitName(String persistenceUnitName) 
    { 
     if(persistenceUnitName == null || persistenceUnitName.length() == 0) 
      throw new IllegalArgumentException("Illegal parameter persistenceUnitName = " + persistenceUnitName); 
     this.persistenceUnitName = persistenceUnitName; 
    } 


    /* 
    * Get an instance of the EntityManagerFactory. 
    */ 
    protected EntityManagerFactory getEnityManagerFactory() 
    { 
     if(persistenceUnitName == null) 
      throw new IllegalStateException("PersistenceUnitName must be set!"); 
     return Persistence.createEntityManagerFactory(persistenceUnitName); 
    } 


    /* 
    * Manage an EntityManager. 
    */ 

    private EntityManager em; 
    public EntityManager getEntityManager() 
    { 
     if(em == null) 
     { 
      em = getEnityManagerFactory().createEntityManager(); 
     } 
     return em;   
    } 
    public EntityManager getEntityManager(String persistenceUnitName) 
    { 
     setPersistenceUnitName(persistenceUnitName); 
     return getEntityManager();   
    } 


    public void closeEntityManager() 
    { 
     if(em != null) 
      em.close(); 
    } 


    /* 
    * Handle Transactions 
    */ 

    protected void txBegin() 
    { 
     EntityTransaction tx = em.getTransaction(); 
     tx.begin(); 
    } 

    protected void txCommit() 
    { 
     EntityTransaction tx = em.getTransaction(); 
     if(tx.getRollbackOnly()) 
     { 
      tx.rollback(); 
     } 
     else 
     { 
      tx.commit(); 
     } 
    } 

    protected void txRollback() 
    { 
     EntityTransaction tx = em.getTransaction(); 
     tx.rollback(); 
    } 
} 

和吾道:

package org.se.bac.data.dao; 

import java.util.List; 

import javax.persistence.EntityManager; 
import javax.persistence.PersistenceContext; 

import org.se.bac.data.model.Employee; 

class EmpDAOImpl // package private 
     implements EmpDAO 
{ 
    @PersistenceContext 
    private EntityManager em; 

    /* 
    * CRUD methods 
    */ 


    public Employee findById(int id) 
    { 
     System.out.println("empdaoimpl ID " + id); 
     return em.find(Employee.class, id); 
    } 






    public EntityManager getEm() { 
     return em; 
    } 

    public void setEm(EntityManager em) { 
     this.em = em; 
    } 





} 

Wildfly数据源:

<datasources> 
      <datasource jta="true" jndi-name="java:/MySqlDS" pool-name="MySqlDS" enabled="true" use-ccm="false"> 
       <connection-url>jdbc:mysql://localhost:3306/empdb?useSSL=false</connection-url> 
       <driver-class>com.mysql.jdbc.Driver</driver-class> 
       <driver>mysql-connector-java-5.1.44-bin.jar_com.mysql.jdbc.Driver_5_1</driver> 
       <security> 
        <user-name>student</user-name> 
        <password>student</password> 
       </security> 
       <validation> 
        <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker"/> 
        <background-validation>true</background-validation> 
        <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLExceptionSorter"/> 
       </validation> 
      </datasource> 
     </datasources> 
+0

您正在所谓的非托管环境中执行Unittest。所以没有数据源,也没有Wildfly。要么创建RESOURCE_LOCAL persistence.xml,要么使用Arquillian进行测试。告诉我你喜欢什么,并告诉你如何做到这一点。 –

+0

你好,谢谢你的回答!如果你能给我一些关于RESOURCE_LOCAL的提示,那将是非常好的!谢谢 – Michael

+0

看看这个:http://in.relation.to/2016/01/14/hibernate-jpa-test-case-template/ –

回答

1

,因为我在persistence.xml中

删除行,他无法找到数据源如何管理让我的应用程序都运行。

问题是数据源是由您的测试环境中不可用的Wildfly管理的。所以,你可以做的是定义两个单独的持久性单元(一个为您的生产代码,另一个用于测试),如下所示:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.0" 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"> 

    <persistence-unit name="primary"> 
     <jta-data-source>java:/MySqlDS</jta-data-source> 

     <properties> 
      <!-- Properties for Hibernate --> 
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> 

      <!-- SQL stdout logging --> 
      <property name="hibernate.show_sql" value="true"/> 
      <property name="hibernate.format_sql" value="true"/> 
      <property name="use_sql_comments" value="true"/> 
     </properties> 
    </persistence-unit> 

    <persistence-unit name="testPU" transaction-type="RESOURCE_LOCAL"> 
     <class>org.se.bac.data.Employee</class> 
     <properties> 
      <!-- Properties for Hibernate --> 
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> 
      <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> 
      <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/empdb?useSSL=false"/> 
      <property name="hibernate.connection.username" value="student"/> 
      <property name="hibernate.connection.password" value="student"/> 


      <!-- SQL stdout logging --> 
      <property name="hibernate.show_sql" value="true"/> 
      <property name="hibernate.format_sql" value="true"/> 
      <property name="use_sql_comments" value="true"/> 
     </properties> 
    </persistence-unit> 

</persistence> 

,然后在EmployeeDAOTest类修改以下行:

private EntityManager em = JPA_HELPER.getEntityManager("testPU"); 

注:

  • 我删除从primary持久单元的JDBC连接属性,因为你并不需要他们为你已有的数据源有Ø Wild Wild。