2010-04-22 18 views
10

He intentado todo el día y he buscado en Google el **** de la Web ... en vano. Tu eres mi última esperanza:No se puede ejecutar JPA2 con Hibernate y Maven

Aquí está mi código:

La Entidad:

package sas.test.model; 

import javax.persistence.Entity; 
import javax.persistence.Id; 

@Entity 
public class Employee { 
    @Id private int id; 
    private String name; 
    private long salary; 
    public Employee() {} 
    public Employee(int id) { this.id = id; } 
    public int getId() { return id; } 
    public void setId(int id) { this.id = id; } 
    public String getName() { return name; } 
    public void setName(String name) { this.name = name; } 
    public long getSalary() { return salary; } 
    public void setSalary (long salary) { this.salary = salary; } 
} 

La clase de servicio:

package sas.test.dao; 

import sas.test.model.Employee; 

import javax.persistence.*; 
import java.util.List; 

public class EmployeeService { 

    protected EntityManager em; 

    public EmployeeService(EntityManager em) { 
     this.em = em; 
    } 
    public Employee createEmployee(int id, String name, long salary) { 
     Employee emp = new Employee(id); 

     emp.setName(name); 
    emp.setSalary(salary); 
    em.persist(emp); 
    return emp; 
} 
    public void removeEmployee(int id) { 
     Employee emp = findEmployee(id); 
     if (emp != null) { 
      em.remove(emp); 
     } 
    } 
    public Employee raiseEmployeeSalary(int id, long raise) { 
     Employee emp = em.find(Employee.class, id); 
     if (emp != null) { 
      emp.setSalary(emp.getSalary() + raise); 
     } 
     return emp; 
    } 
    public Employee findEmployee(int id) { 
     return em.find(Employee.class, id); 
    } 

} 

Y la clase principal:

package sas.test.main; 

import javax.persistence.*; 
import java.util.List; 
import sas.test.model.Employee; 
import sas.test.dao.EmployeeService; 


public class ExecuteMe { 
    public static void main(String[] args) { 
     EntityManagerFactory emf = 
       Persistence.createEntityManagerFactory("EmployeeService"); 
     EntityManager em = emf.createEntityManager(); 
     EmployeeService service = new EmployeeService(em); 

      // create and persist an employee 
      em.getTransaction().begin(); 
      Employee emp = service.createEmployee(158, "John Doe", 45000); 
      em.getTransaction().commit(); 
      System.out.println("Persisted " + emp); 
      // find a specific employee 
      emp = service.findEmployee(158); 
      System.out.println("Found " + emp); 
      // find all employees 
    //  List<Employee> emps = service.findAllEmployees(); 
     // for (Employee e : emps) 
     //  System.out.println("Found employee: " + e); 
      // update the employee 
      em.getTransaction().begin(); 
      emp = service.raiseEmployeeSalary(158, 1000); 
      em.getTransaction().commit(); 
      System.out.println("Updated " + emp); 
      // remove an employee 
      em.getTransaction().begin(); 
      service.removeEmployee(158); 
      em.getTransaction().commit(); 
      System.out.println("Removed Employee 158"); 
      // close the EM and EMF when done 
      em.close(); 
      emf.close(); 
    } 
} 

Finalmente mi confs.

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>Test_JPA_CRUD</groupId> 
    <artifactId>Test_JPA_CRUD</artifactId> 
    <packaging>jar</packaging> 
    <version>1.0</version> 
    <name>Test_JPA_CRUD</name> 
    <url>http://maven.apache.org</url> 
    <repositories> 


     <repository> 
      <id>maven2-repository.dev.java.net</id> 
      <name>Java.net Repository for Maven</name> 
      <url>http://download.java.net/maven/2/ 
      </url> 
      <layout>default</layout> 
     </repository> 


     <repository> 
      <id>maven.org</id> 
      <name>maven.org Repository</name> 
      <url>http://repo1.maven.org/maven2</url> 
      <releases> 
       <enabled>true</enabled> 
      </releases> 
      <snapshots> 
       <enabled>true</enabled> 
      </snapshots> 
     </repository> 
    </repositories> 
    <dependencies> 
     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>4.8.1</version> 
      <scope>test</scope> 
     </dependency> 

     <!-- 

       <dependency> 
        <groupId>javax</groupId> 
        <artifactId>javaee-api</artifactId> 
        <version>6.0</version> 
       </dependency> 
     --> 
     <!-- 
     <dependency> 
      <groupId>javax.persistence</groupId> 
      <artifactId>persistence-api</artifactId> 
      <version>1.0</version> 
     </dependency> 
             --> 
     <!-- JPA2 provider --> 
     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-entitymanager</artifactId> 
      <version>3.4.0.GA</version> 
     </dependency> 

     <!-- JDBC driver --> 
     <dependency> 
      <groupId>org.apache.derby</groupId> 
      <artifactId>derby</artifactId> 
      <version>10.5.3.0_1</version> 
     </dependency> 


     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-core</artifactId> 
      <version>3.3.2.GA</version> 
     </dependency> 
     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>ejb3-persistence</artifactId> 
      <version>3.3.2.Beta1</version> 
     </dependency> 

     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-annotations</artifactId> 
      <version>3.4.0.GA</version> 
     </dependency> 

     <dependency> 
      <groupId>org.slf4j</groupId> 
      <artifactId>slf4j-log4j12</artifactId> 
      <version>1.5.2</version> 
     </dependency> 
     <dependency> 
      <groupId>log4j</groupId> 
      <artifactId>log4j</artifactId> 
      <version>1.2.14</version> 
     </dependency> 
    </dependencies> 
    <build> 
     <plugins> 
      <!-- compile with mvn assembly:assembly --> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-jar-plugin</artifactId> 
       <version>2.2</version> 
      </plugin> 
      <!-- compile with mvn assembly:assembly --> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-assembly-plugin</artifactId> 
       <version>2.2-beta-2</version> 
       <configuration> 
        <descriptorRefs> 
         <descriptorRef>jar-with-dependencies</descriptorRef> 
        </descriptorRefs> 
        <archive> 
         <manifest> 
          <mainClass>sas.test.main.ExecuteMe</mainClass> 
         </manifest> 
        </archive> 
       </configuration> 
       <executions> 
        <execution> 
         <phase>package</phase> 
        </execution> 
       </executions> 
      </plugin> 
      <plugin> 
       <!-- Force UTF-8 & Java-Version 1.6 --> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <configuration> 
        <source>1.6</source> 
        <target>1.6</target> 
        <!--<encoding>utf-8</encoding>--> 
       </configuration> 
      </plugin> 
     </plugins> 
    </build> 

</project> 

y la persistence.xml, que, prometo, se encuentra en la ruta de clase del objetivo:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="1.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_1_0.xsd 
http://java.sun.com/xml/ns/persistence "> 
    <persistence-unit name="EmployeeService" transaction-type="RESOURCE_LOCAL"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider> 
     <class>sas.test.model.Employee</class> 
     <properties> 

      <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/> 
      <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/> 
      <property name="hibernate.show_sql" value="true"/> 
      <property name="javax.persistence.jdbc.url" value="jdbc:derby:webdb;create=true"/> 


     </properties> 
    </persistence-unit> 
</persistence> 

Como se habrán dado cuenta de algún código comentado , Probé ambas, la implementación de Hibernate y J2EE 6 de JPA2.0, sin embargo, ambas fallaron. El código mencionado anteriormente termina con el siguiente error:

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version). 
log4j:WARN Please initialize the log4j system properly. 
Exception in thread "main" java.lang.UnsupportedOperationException: The user must supply a JDBC connection 
at org.hibernate.connection.UserSuppliedConnectionProvider.getConnection(UserSuppliedConnectionProvider.java:54) 
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446) 
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167) 
at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:142) 

¿Alguna idea de qué está pasando? ¿Alguna demo de maven/JPA2 de "Hello World" que realmente se ejecute? No pude obtener ninguno de los proporcionados por la búsqueda de google en ejecución.

Gracias por adelantado.

Respuesta

19

Hibernate EntityManager 3.4.0.GA es no un 2,0 implementación JPA por lo que no va a apoyar los estandarizados javax.persistence.* propiedades en el persistence.xml (de ahí la excepción de que no había conexión JDBC siendo suministrados). Para JPA 2.0, necesitas Hibernate EM 3.5.1-Final. A continuación un sencillo POM con la dependencia derecha:

<project> 
    ... 
    <repositories> 
    <repository> 
     <id>jboss</id> 
     <name>JBoss repository</name> 
     <url>http://repository.jboss.org/maven2</url> 
    </repository> 
    </repositories> 

    <dependencies> 
    <!-- JPA API and Hibernate --> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-entitymanager</artifactId> 
     <version>3.5.1-Final</version> 
    </dependency> 

    <!-- Logging --> 
    <dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>slf4j-simple</artifactId> 
     <version>1.5.8</version> 
    </dependency> 

    ... 
    </dependencies> 
    ... 
</project> 

Y eso es todo lo que necesita, otras dependencias serán sacados de forma transitiva. Simplemente reemplace el enlace slf4j que estoy usando con su favorito.

Si desea utilizar Bean Validation API (JSR-303) y la RI, añadir (adaptar el alcance para satisfacer sus necesidades):

<!-- Bean Validation API and RI --> 
<dependency> 
    <groupId>javax.validation</groupId> 
    <artifactId>validation-api</artifactId> 
    <version>1.0.0.GA</version> 
    <scope>compile</scope> 
</dependency> 
<dependency> 
    <groupId>org.hibernate</groupId> 
    <artifactId>hibernate-validator</artifactId> 
    <version>4.0.2.GA</version> 
    <scope>runtime</scope> 
</dependency> 

no he probado el código, pero esto será en arregla tu POM por lo menos

PD: No necesita especificar el proveedor de persistencia en su persistence.xml si solo hay uno en el classpath, no es necesario que especifique el dialecto. Pero esto no debería doler.

PPS: Tenga en cuenta que javax.persistence:persistence-api:jar:1.0 es una API, no una implementación, no hará nada por sí misma (es decir, no sustituye a Hibernate, EclipseLink, etc.).

+0

¡Muchas gracias! ¡Funciona! ¡Dios salve a stackoverflow y sus participantes! –

+0

¿cómo sabes qué hibernate-validator es válido para hibernate 3.5.1-Final? – Phil

0

Una cosa importante que no encontré en mi predecesor no mencionó, pero parece ser crucial es agregar a la dependencia de hibernación alcance provisto. De modo que en la guerra/oreja resultante no se agregan.

<dependency> 
    <groupId>org.hibernate</groupId> 
    <artifactId>hibernate-entitymanager</artifactId> 
    <version>3.5.1-Final</version> 
    <scope>provided</scope> 
</dependency> 

Me tomó un tiempo para descubrir eso, así que estoy señalando esto para los demás.

+0

¿Quién proporciona esto? – Reddy

+1

Normalmente servidor de aplicaciones, en mi caso está en ./jboss-6.0.0/common/lib/hibernate-entitymanager.jar –

3

Si no está utilizando Maven dependencia y utilizando sólo eclipsar rutas de clases, sólo tiene que poner los archivos jar anteriores en la ruta de clase de hibernación 3.5 o superior

1) hibernar núcleo Jar

2) hibernar anotaciones tarro

3) jboss tala tarro

4) hibernar entidad gestora tarro

JPA AP I 2. jar (está incluido en la distribución de hibernación).

Tuve problemas similares y utilicé este enfoque y funcionó. Conseguir todo el jar de depedent de la misma versión de la distribución es la mejor idea. Si encuentra algún error, puede encontrarlo en los registros y continuar colocando el jar en classpath

Cuestiones relacionadas