我正在使用Hibernate和MySQL开发一个java Web应用程序。有时当我试图坚持下去时,我得到了这个回滚异常:
javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:94)
at com.tulips.dao.CommentDao.saveOrUpdate(CommentDao.java:42)
at com.tulips.servlets.CommentsServlet.doPost(CommentsServlet.java:168)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:155)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:91)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:55)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:77)
... 23 more
这是我的persistence.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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"
version="2.0">
<persistence-unit name="licenta_pu"
transaction-type="RESOURCE_LOCAL">
<!-- <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> -->
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/tulips"/>
<property name="hibernate.connection.username" value="...." />
<property name="hibernate.connection.password" value="...." />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="hibernate.show-sql" value="false" />
<!-- <property name="hibernate.jdbc.batch_size" value="1000" /> -->
<!-- <property name="hibernate.hbm2ddl.auto" value="update" /> -->
</properties>
</persistence-unit>
</persistence>
我尝试过更改hibernate提供程序但是没有帮助:( [org.hibernate.ejb.HibernatePersistence和org.hibernate.jpa.HibernatePersistenceProvider]
我不确切地知道如何复制这个错误,有时候我会得到它,有时我不知道。我观察到,每次重新启动计算机并在Eclipse中运行项目并尝试保留数据后,它都会起作用。如果我停止项目,最终通过MySQL Workbench将一些数据添加到数据库中,然后再次运行项目,我收到错误。
这是我的EntityManagerHolder:
public class EntityManagerHolder {
private static EntityManagerHolder INSTANCE = new EntityManagerHolder();
private EntityManagerFactory emf;
private EntityManager entityManager;
public EntityManager getEntityManager() {
return entityManager;
}
public static EntityManagerHolder getInstance() {
return INSTANCE;
}
private EntityManagerHolder() {
super();
emf = Persistence
.createEntityManagerFactory("licenta_pu");
entityManager = emf.createEntityManager();
}
}
这是我的GenericDao:
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import com.tulips.model.AbstractEntity;
@Transactional
public abstract class GenericDao {
protected EntityManager em;
public GenericDao(EntityManager em) {
this.em = em;
}
public void saveOrUpdate(AbstractEntity e) {
if (e == null) {
throw new NullPointerException("Trying to persist a null object");
}
em.getTransaction().begin();
if (e.getId() == null) {
em.persist(e);
} else {
em.merge(e);
}
em.getTransaction().commit();
}
}
我正在使用以下Hibernate库:
mysql-connector-java-5.1.9.jar;
hibernate-commons-annotations-4.0.4.Final.jar;
hibernate-core-4.3.4.Final.jar;
hibernate-entitymanager-4.3.4.Final.jar;
hibernate-jpa-2.1-api-1.0.0.Final.jar;
答案 0 :(得分:13)
问题可能是您有一个由所有Web请求共享的EntityManager。 EntityManager不是线程安全的。 webapp中的标准方法是为每个请求创建一个新的EntityManager实例。拥有共享的EntityManagerFactory是可以的,但不是共享的EntityManager。
EntityManager是一种廉价的非线程安全对象 对于单个业务流程,单个工作单元,可以使用一次, 然后丢弃。 EntityManager无法获取JDBC连接 (或数据源),除非需要,所以你可以安全地打开和 即使您不确定数据访问权限,也会关闭EntityManager 需要满足特定的要求。