朋友们,StackOverflow, 我不明白如何回滚我阅读了Spring的文档,但我仍然不明白。基本上我要在db中持久保存一个对象(手动使用主键),这个对象被插入到db中。但是当你使用相同的主键再次持久化对象时,我引起了异常,这是正确的,违反了对唯一性的限制。在这种情况下,我会得到一个事务回滚并警告您存在问题并继续运行程序
这是我的班级:
public class ServiceDaoImpl{
@PersistenceContext (unitName="fb-persistence")
protected EntityManager em;
public void setEntityManager(EntityManager entityManager) {
this.em = entityManager;
}
@Transactional(readOnly=false)
public void write(Service entity){
try {
em.persist(entity);
em.flush();
} catch(Exception ex) {
ex.printStackTrace();
}
}
/*
* .. other method
*/
}
这是错误的堆栈:
javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1214)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1147)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1153)
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:798)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
at $Proxy27.flush(Unknown Source)
at it.synclab.fb.jpa.dao.impl.GenericDaoImpl.write(GenericDaoImpl.java:236)
at it.synclab.fb.jpa.dao.impl.EnteDaoImpl.write(EnteDaoImpl.java:1)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy34.write(Unknown Source)
at it.synclab.fb.jpa.test.ConfigTest.insertEnte(ConfigTest.java:47)
at it.synclab.fb.jpa.test.ConfigTest.main(ConfigTest.java:32)
Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:795)
... 21 more
Caused by: java.sql.BatchUpdateException: ORA-00001: violata restrizione di unicità (FLUSSIBATCH.SYS_C008896)
我的配置文件是(persistence.xml和applicationContext.xml):
这是applicationContext.xml: ...
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="fb-persistence" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean name="serviceDaoImpl" class="it.synclab.fb.jpa.dao.impl.ServiceDaoImpl" />
...
This is the persistence.xml:
<persistence>
<persistence-unit name="fb-persistence" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<mapping-file>META-INF/orm.xml</mapping-file>
<class>it.entity.Service</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.connection.username" value="############"/>
<property name="hibernate.connection.password" value="############"/>
<property name="hibernate.connection.url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
</properties>
</persistence-unit>
</persistence>
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:629)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:9467)
at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:211)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 27 more
Exception in thread "main" org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:476)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy34.write(Unknown Source)
at it.synclab.fb.jpa.test.ConfigTest.insertEnte(ConfigTest.java:47)
at it.synclab.fb.jpa.test.ConfigTest.main(ConfigTest.java:32)
Caused by: javax.persistence.RollbackException: Transaction marked as rollbackOnly
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:73)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:467)
... 9 more
为什么要复杂?我只是不明白......我希望你们中的一些人遇到同样的问题并解决了
答案 0 :(得分:4)
我不知道我是否正确理解了您的问题,但您的问题可能在于ServiceDaoImpl
异常处理:
try {
em.persist(entity);
em.flush();
} catch(Exception ex) {
ex.printStackTrace();
}
这是非常糟糕的做法(tm)。不要捕获异常,但让它从您的方法中弹出。这样:
所以缩短长话短说:
public class ServiceDaoImpl{
@PersistenceContext (unitName="fb-persistence")
private EntityManager em;
@Transactional(readOnly=false)
public void write(Service entity){
em.persist(entity);
em.flush();
}
}
请注意,您不需要EntityManager
的设置器,该字段可以是私有的。
答案 1 :(得分:0)
在write方法中添加try catch块,并在出现错误时抛出异常。
如果要控制回滚事件,请在rollbackFor
注释中添加rollbackForClassname
或@Transactional
属性,以获得引发的异常。