在@PostConstruct阶段设置自己的代理会导致@Transactional问题

时间:2014-09-11 14:57:47

标签: java spring validation proxy transactions

我的服务有一些@Transactional工作。如果我标记它@Validated我会收到org.hibernate.LazyInitializationException:无法初始化代理 - 没有Session 在(B)点。如果我删除行(A),一切都按预期工作。我的服务已经过验证,可以再次使用。如果我稍后使用此代理对象并不重要。一旦在@PostConstruct阶段初始化它就不能成为@Transactional。如果我尝试使用InitializingBean接口,则相同。谁能解释我为什么?在创建所有代理之后,不应该调用@PostConstruct方法吗?

我通过使用getter而不是实例变量为此做了一个简单的解决方法。所以我可以在我的bean完全初始化时询问应用程序上下文,然后一切正常。

@Service
@Lazy(value = true)
//@Validated
public class XXXXServiceImpl implements XXXService {

  private String name;

  private XXXService proxy;

  @Autowired
  private ApplicationContext applicationContext;

  @Override
  public void setBeanName(String name) {
    this.name = name;
  }

  @PostConstruct
  public void postConstruct() {
    proxy = (XXXService)applicationContext.getBean(name); // (A)
  }

  @Transactional
  public void test(Company object) {
       License l = licenseDAO.find(1234);
       l.getCompany(); // (B)
  }
}

解决方法

private XXXService getProxy() {
  if (proxy == null)
    proxy = (XXXService)applicationContext.getBean(name);
  return proxy;
}

stacktrace :(来自我的真实代码,未简化)

org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:165)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286)
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
    at pl.xxx.bean.CompanyIdentity_$$_jvstd73_f.getId(CompanyIdentity_$$_jvstd73_f.java)
    at pl.xxx.services.AdminServiceImpl.cleanTestData_aroundBody12(AdminServiceImpl.java:228)
    at pl.xxx.services.AdminServiceImpl$AjcClosure13.run(AdminServiceImpl.java:1)
    at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:59)
    at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:65)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:63)
    at pl.xxx.services.AdminServiceImpl.cleanTestData(AdminServiceImpl.java:157)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:45)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.validation.beanvalidation.MethodValidationInterceptor$HibernateValidatorDelegate.invokeWithinValidation(MethodValidationInterceptor.java:168)
    at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:132)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

0 个答案:

没有答案