无法使用 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