2010-04-22 8 views
10

J'ai essayé toute la journée et googlé le **** sur le web ... en vain. Vous êtes mon dernier espoir:Impossible de faire fonctionner JPA2 avec Hibernate et Maven

Voici mon code:

L'entité:

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 classe de service:

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); 
    } 

} 

Et la classe principale:

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(); 
    } 
} 

Enfin mes 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> 

et persistence.xml, qui, je vous le promets, est dans le classpath de la cible:

<?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> 

Comme vous avez pu le constater à partir du code commenté , J'ai essayé les deux, l'implémentation Hibernate et J2EE 6 de JPA2.0, cependant, les deux ont échoué. Le code mentionné ci-dessus se termine par erreur suivant:

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) 

Toute idée de ce qui se passe mal? Toute démo maven/JPA2 "Hello World" qui fonctionne réellement? Je ne pouvais obtenir aucun de ceux fournis par la recherche de Google en cours d'exécution.

Merci d'avance.

Répondre

19

Hibernate EntityManager 3.4.0.GA est pas une implémentation JPA 2.0 de sorte qu'il ne soutiendra pas les javax.persistence.* normalisées propriétés dans le persistence.xml (donc l'exception au sujet aucune connexion JDBC étant fournis). Pour JPA 2.0, vous avez besoin d'Hibernate EM 3.5.1-Final. Ci-dessous un POM simple avec la dépendance droite:

<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> 

Et c'est tout ce que vous avez besoin, d'autres dépendances seront tirés transitive. Il suffit de remplacer la liaison slf4j que j'utilise avec votre favori.

Si vous souhaitez utiliser la validation Bean (JSR-303) API et le RI, ajouter (adapter la portée en fonction de vos besoins):

<!-- 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> 

Je n'ai pas testé votre code mais cela à moins réparer votre POM. PS: Vous n'avez pas besoin de spécifier le fournisseur de persistance dans votre persistence.xml s'il n'y en a qu'un sur le chemin de classe, vous n'avez pas besoin de spécifier le dialecte. Mais cela ne devrait pas faire de mal. PPS: Notez que javax.persistence:persistence-api:jar:1.0 est une API, pas une implémentation, elle ne fera rien par elle-même (je ne veux pas dire qu'elle remplace Hibernate, EclipseLink, etc.).

+0

Merci beaucoup! Ça marche! God save stackoverflow et ses participants! –

+0

comment savez-vous quel hibernate-validator est valide pour hibernate 3.5.1-Final? – Phil

0

Une chose importante que je n'ai pas trouvé dans mon prédécesseur n'a pas mentionné, mais semble être crucial est d'ajouter à la dépendance d'hibernation fourni portée. Alors que dans la guerre/l'oreille qui en résulte, ils ne sont pas ajoutés.J'ai pris un peu de temps pour le savoir, donc je le signale pour les autres.

+0

Qui fournit cela? – Reddy

+1

Généralement le serveur d'application, dans mon cas c'est ./jboss-6.0.0/common/lib/hibernate-entitymanager.jar –

3

Si vous n'utilisez pas la dépendance Maven et en utilisant seulement éclipser les paramètres de classpath, il vous suffit de mettre les fichiers jar ci-dessus dans classpath de mise en veille prolongée 3.5 et au-dessus

1) mise en veille prolongée noyau Jar

2) mise en veille prolongée annotations jar

3) pot d'enregistrement jboss

4) Mise en veille prolongée pot de gestionnaire d'entités

JPA AP Je 2. jar (c'est inclus dans la distribution d'hibernate).

J'ai eu des problèmes similaires et j'ai utilisé cette approche et cela a fonctionné. Obtenir tout le pot de depedent de la même version de la distribution est la meilleure idée. Si vous trouvez une erreur, vous pouvez le trouver dans les journaux et continuer à mettre le pot dans le classpath