无法使用 Hibernate 和 Maven 运行 JPA2

Posted

技术标签:

【中文标题】无法使用 Hibernate 和 Maven 运行 JPA2【英文标题】:Can't get JPA2 running with Hibernate and Maven 【发布时间】:2011-02-11 07:21:48 【问题描述】:

一整天都在尝试,并在网上搜索了 **** ......徒劳无功。你是我最后的希望:

这是我的代码:

实体:

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; 

服务类:

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


还有主类:

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

最后是我的自信。

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>

我保证,persistence.xml 位于目标的类路径中:

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

正如您可能从一些注释代码中注意到的那样,我尝试了 JPA2.0 的 Hibernate 和 J2EE 6 实现,但是都失败了。上述代码最终出现以下错误:

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)

知道出了什么问题吗?任何实际运行的“Hello World”maven/JPA2 演示?我无法运行谷歌搜索提供的任何内容。

提前感谢。

【问题讨论】:

【参考方案1】:

如果你不使用Maven依赖并且只使用eclipse类路径设置,你只需要将上面的jar文件放在hibernate 3.5及以上的类路径中

1) 休眠核心Jar

2) 休眠注释jar

3) jboss 日志记录 jar

4) 休眠实体管理器 jar

JPA API 2.jar(包含在 hibernate 发行版中)。

我也遇到过类似的问题,我使用了这种方法并且效果很好。从同一版本的发行版中获取所有依赖的 jar 是最好的主意。如果您发现任何错误,您可以从日志中找到它并继续将 jar 放入类路径中

【讨论】:

【参考方案2】:

我没有发现我的前任没有提到的一件重要的事情,但似乎至关重要的是添加到休眠依赖 provided 范围。因此,不会添加这些导致的战争/耳朵。

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

我花了一段时间才发现这一点,所以我为其他人指出这一点。

【讨论】:

通常是应用程序服务器,在我的情况下它位于 ./jboss-6.0.0/common/lib/hibernate-entitymanager.jar【参考方案3】:

Hibernate EntityManager 3.4.0.GA 不是 JPA 2.0 实现,因此它不支持persistence.xml 中的标准化javax.persistence.* 属性(因此没有提供JDBC 连接的例外情况)。对于 JPA 2.0,您需要 Hibernate EM 3.5.1-Final。下面是一个具有正确依赖关系的简单 POM:

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

这就是你所需要的,其他依赖项将被传递。只需将我正在使用的 slf4j 绑定替换为您喜欢的绑定即可。

如果您想使用 Bean Validation (JSR-303) API 和 RI,请添加(根据您的需要调整范围):

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

我没有测试你的代码,但这至少可以修复你的 POM。

PS:如果类路径上只有一个,则无需在persistence.xml 中指定持久性提供程序,则无需指定方言。但这不应该受到伤害。

PPS:请注意,javax.persistence:persistence-api:jar:1.0 是一个 API,而不是一个实现,它本身不会做任何事情(我的意思是,它不能替代 Hibernate、EclipseLink 等)。

【讨论】:

非常感谢!有用!上帝保佑 *** 及其参与者! 你怎么知道哪个hibernate-validator对hibernate 3.5.1-Final有效?

以上是关于无法使用 Hibernate 和 Maven 运行 JPA2的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 JPA 2.0、Spring 2.5.6、Hibernate 3.6.1 和 Maven 在 HSQLDB 中持久化

Hibernate SchemaExport 无法首先创建架构

无法使用 maven 项目配置 mysql hibernate

无法使用 hibernate3-maven-plugin-3.0 生成 hbm2ddl

JPA、MySQL、Hibernate 和 Maven 骨架

基于maven搭建hibernate运行环境