【发布时间】:2014-05-12 20:57:44
【问题描述】:
每次使用 Hibernate 更新实体时都会出错。 这是我的故事:
我有一个带有 @Transactional 注释的服务,并且正在调用 DAO.update 方法。
@Service
@Transactional
public class FooServiceImpl implements FooService {
@Inject
private FooDAO fooDAO;
@Override
public Foo update(Foo foo) {
return fooDAO.update(foo);
}
@Override
public Foo find(int fooId) {
return fooDAO.findById(fooId);
}
}
我有一个 AOP,它捕获 DAO.update 以便进行一些操作。
@Aspect
@Order(2)
@Component
public class FooTackerAspect {
@Inject
private FooService fooService;
@Inject
private SessionFactoryManager sessionFactoryManager;
@Pointcut("execution(* com.foo.bar.FooService.update(..))")
public void methodToTrack() {}
@Around("methodToTrack")
public Object track(final ProceedingJoinPoint joinPoint) throws Throwable {
int fooId = fetchIdFromJoinPoint(joinPoint);
Foo foo = fooService.find(fooId);
// Do some operations
// I close the session in order to avoid the exception
// org.hibernate.NonUniqueObjectException: a different object with
// the same identifier value was already associated with the session
sessionFactoryManager.getSessionFactory(DataSource.FOO)
.getCurrentSession().close();
Object retVal = joinPoint.proceed();
return retVal;
}
}
但是,在更新实体 (fooDAO.update(foo)) 后,我收到以下错误:
2056953 [http-bio-8080-exec-4] ERROR o.s.t.s.TransactionSynchronizationUtils - TransactionSynchronization.beforeCompletion threw exception
java.lang.IllegalStateException: No value for key [org.hibernate.impl.SessionFactoryImpl@762d6271] bound to thread [http-bio-8080-exec-4]
at org.springframework.transaction.support.TransactionSynchronizationManager.unbindResource(TransactionSynchronizationManager.java:209) ~[spring-tx-3.2.4.RELEASE.jar:3.2.4.RELEASE]
at org.springframework.orm.hibernate3.SpringSessionSynchronization.beforeCompletion(SpringSessionSynchronization.java:193) ~[spring-orm-3.2.4.RELEASE.jar:3.2.4.RELEASE]
at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCompletion(TransactionSynchronizationUtils.java:106) ~[spring-tx-3.2.4.RELEASE.jar:3.2.4.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCompletion(AbstractPlatformTransactionManager.java:938) [spring-tx-3.2.4.RELEASE.jar:3.2.4.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:739) [spring-tx-3.2.4.RELEASE.jar:3.2.4.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:724) [spring-tx-3.2.4.RELEASE.jar:3.2.4.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:475) [spring-tx-3.2.4.RELEASE.jar:3.2.4.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:270) [spring-tx-3.2.4.RELEASE.jar:3.2.4.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94) [spring-tx-3.2.4.RELEASE.jar:3.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) [spring-aop-3.2.4.RELEASE.jar:3.2.4.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) [spring-aop-3.2.4.RELEASE.jar:3.2.4.RELEASE]
at com.sun.proxy.$Proxy112.update(Unknown Source) [$Proxy112.class:na]
此错误未阻塞(更新仍在进行)。但我想纠正这个错误。 你知道我该怎么做吗?
我认为错误来自我关闭会话的事实。但我必须关闭它才能更新实体。
【问题讨论】:
-
先关闭会话然后再调用
FooServiceImpl.update()听起来并不健康,因为这正是proceed()所做的。我建议您修复您的建议代码。也许您希望通过关闭会话来避免的另一个异常是由于您在代码中所做的事情没有向我们披露,而是被注释“做一些操作”所取代。