问题
I am having a weird, and hard to debug, issue using Weblogic 10.3.6, Spring 4.0.6, Spring Data JPA 1.6.2, Eclipselink (reproduced both the Weblogic embedded 2.3 version and the newest 2.5.2) and Container Managed Transactions. (I updated Weblogic to use JPA 2.0 installing the patch provided by Oracle).
The issue is the following: I have a simple, stateless, EJB 3.0 in which I do use Spring Autowiring and spring-data-jpa repositories.
When I do call any service exposed by the EJB, I get the following, weird, exception (please notice that I had to find/replace all the real class names/paths):
EJB Exception: : com.oracle.pitchfork.interfaces.LifecycleCallbackException: Failure to invoke public void org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor.autowireBean(javax.interceptor.InvocationContext) on bean class class
... 58 more
Caused by: org.springframework.beans.factory.access.BootstrapException: Unable to initialize group definition. Group resource name [classpath*:beanRefContext.xml], factory key [null]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mainApplicationContext' defined in URL [file:/C:/work/project/spring-ejb-project/target/classes/beanRefContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.context.support.ClassPathXmlApplicationContext]: Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'actionTBConverter': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private myproject.dao.repositories.personRepository myproject.converters.DataConverter.personRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personRepository': Invocation of init method failed; nested exception is javax.persistence.PersistenceException:
Exception Description: Error binding to externally managed transaction
Internal Exception: weblogic.transaction.RollbackException: setRollbackOnly called on transaction
at org.springframework.beans.factory.access.SingletonBeanFactoryLocator.useBeanFactory(SingletonBeanFactoryLocator.java:387)
at org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor.getBeanFactoryReference(SpringBeanAutowiringInterceptor.java:160)
at org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor.getBeanFactory(SpringBeanAutowiringInterceptor.java:141)
at org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor.doAutowireBean(SpringBeanAutowiringInterceptor.java:121)
at org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor.autowireBean(SpringBeanAutowiringInterceptor.java:95)
... 63 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mainApplicationContext' defined in URL [file:/C:/work/project/spring-ejb-project/target/classes/beanRefContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.context.support.ClassPathXmlApplicationContext]: Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'actionTBConverter': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private myproject.dao.repositories.personRepository myproject.converters.DataConverter.personRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personRepository': Invocation of init method failed; nested exception is javax.persistence.PersistenceException:
Exception Description: Error binding to externally managed transaction
Internal Exception: weblogic.transaction.RollbackException: setRollbackOnly called on transaction
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:278)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1114)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1017)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.context.access.ContextSingletonBeanFactoryLocator.initializeDefinition(ContextSingletonBeanFactoryLocator.java:143)
at org.springframework.beans.factory.access.SingletonBeanFactoryLocator.useBeanFactory(SingletonBeanFactoryLocator.java:382)
... 67 more
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.context.support.ClassPathXmlApplicationContext]: Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'actionTBConverter': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private myproject.dao.repositories.personRepository myproject.converters.DataConverter.personRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personRepository': Invocation of init method failed; nested exception is javax.persistence.PersistenceException:
Exception Description: Error binding to externally managed transaction
Internal Exception: weblogic.transaction.RollbackException: setRollbackOnly called on transaction
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:164)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:125)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:270)
... 80 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'actionTBConverter': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private myproject.dao.repositories.personRepository myproject.converters.DataConverter.personRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personRepository': Invocation of init method failed; nested exception is javax.persistence.PersistenceException:
Exception Description: Error binding to externally managed transaction
Internal Exception: weblogic.transaction.RollbackException: setRollbackOnly called on transaction
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
... 82 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private myproject.dao.repositories.personRepository myproject.converters.DataConverter.personRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personRepository': Invocation of init method failed; nested exception is javax.persistence.PersistenceException:
Exception Description: Error binding to externally managed transaction
Internal Exception: weblogic.transaction.RollbackException: setRollbackOnly called on transaction
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
... 99 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personRepository': Invocation of init method failed; nested exception is javax.persistence.PersistenceException:
Exception Description: Error binding to externally managed transaction
Internal Exception: weblogic.transaction.RollbackException: setRollbackOnly called on transaction
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1017)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
... 101 more
Caused by: javax.persistence.PersistenceException:
Exception Description: Error binding to externally managed transaction
Internal Exception: weblogic.transaction.RollbackException: setRollbackOnly called on transaction
at org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.registerIfRequired(JTATransactionWrapper.java:145)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.setJTATransactionWrapper(EntityManagerImpl.java:2153)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.detectTransactionWrapper(EntityManagerImpl.java:878)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.initialize(EntityManagerImpl.java:401)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.<init>(EntityManagerImpl.java:394)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:321)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:336)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:302)
at sun.reflect.GeneratedMethodAccessor257.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at weblogic.deployment.EntityManagerFactoryProxyImpl.invoke(EntityManagerFactoryProxyImpl.java:96)
at com.sun.proxy.$Proxy59.createEntityManager(Unknown Source)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:283)
at com.sun.proxy.$Proxy160.createNamedQuery(Unknown Source)
at org.springframework.data.jpa.repository.query.NamedQuery.<init>(NamedQuery.java:62)
at org.springframework.data.jpa.repository.query.NamedQuery.lookupFrom(NamedQuery.java:113)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:132)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:166)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:69)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:320)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:169)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:224)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:210)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
... 111 more
Caused by: weblogic.transaction.RollbackException: setRollbackOnly called on transaction
at weblogic.transaction.internal.TransactionImpl.throwRollbackException(TransactionImpl.java:1884)
at weblogic.transaction.internal.ServerTransactionImpl.registerSynchronization(ServerTransactionImpl.java:639)
at org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.registerIfRequired(JTATransactionWrapper.java:136)
... 137 more
Caused by: weblogic.transaction.internal.AppSetRollbackOnlyException: setRollbackOnly called on transaction
at weblogic.transaction.internal.TransactionImpl.setRollbackOnly(TransactionImpl.java:555)
at weblogic.transaction.internal.TransactionManagerImpl.setRollbackOnly(TransactionManagerImpl.java:340)
at weblogic.transaction.internal.TransactionManagerImpl.setRollbackOnly(TransactionManagerImpl.java:333)
at org.eclipse.persistence.transaction.JTATransactionController.markTransactionForRollback_impl(JTATransactionController.java:160)
at org.eclipse.persistence.transaction.AbstractTransactionController.markTransactionForRollback(AbstractTransactionController.java:216)
at org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.setRollbackOnlyInternal(JTATransactionWrapper.java:85)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.setRollbackOnly(EntityManagerImpl.java:2092)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createNamedQuery(EntityManagerImpl.java:1127)
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:606)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:289)
... 124 more
; nested exception is: com.oracle.pitchfork.interfaces.LifecycleCallbackException: Failure to invoke public void org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor.autowireBean(javax.interceptor.InvocationContext) on bean class class org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor_s85z0p_Impl with args: [com.oracle.pitchfork.intercept.InterceptionMetadata$LifecycleEventCallbackInvocationContext@cb3ef49]
I am really struggling to understand why this happens and I hope someone will find time to help me.
Here follow my code details
(I stripped out xml namespaces to save characters, and removed real project class names)
Here is my beanRefContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans ...">
<bean id="mainApplicationContext" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<list>
<value>classpath*:/spring-config.xml</value>
</list>
</constructor-arg>
</bean>
</beans>
Here is my spring-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...
default-lazy-init="false">
<context:annotation-config/>
<context:component-scan base-package="myproject"/>
</beans>
Here is my Spring Config java file:
@Configuration
@EnableLoadTimeWeaving
@EnableJpaRepositories("myproject.dao.repositories")
public class SpringConfig implements ApplicationContextAware, LoadTimeWeavingConfigurer {
private static final Logger LOG = LoggerFactory.getLogger(SpringConfig.class);
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext ac) {
this.applicationContext = ac;
}
@Bean
public EntityManagerFactory entityManagerFactory() throws Exception {
Context ctx = new InitialContext();
return (EntityManagerFactory) ctx.lookup("java:/comp/env/MyPersistenceUnitJNDI");
}
@Bean
public TransactionManager transactionManager() throws Exception {
InitialContext initCtx = new InitialContext();
TransactionManager tm = (TransactionManager) initCtx.lookup("weblogic.transaction.TransactionManager");
WebLogicJtaTransactionManager wlTx = new WebLogicJtaTransactionManager();
wlTx.setTransactionManager(tm);
return (TransactionManager) wlTx;
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
EclipseLinkJpaVendorAdapter va = new EclipseLinkJpaVendorAdapter();
va.setDatabase(Database.ORACLE);
return va;
}
@Override
public LoadTimeWeaver getLoadTimeWeaver() {
LoadTimeWeaver ltw = new WebLogicLoadTimeWeaver();
return ltw;
}
}
Persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.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_2_0.xsd">
<persistence-unit name="MyPersistenceUnit" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>db/myprojectdatasource</jta-data-source>
<class>myproject.dao.entities.Person</class>
<properties>
<property name="eclipselink.target-server" value="WebLogic_10"/>
<property name="eclipselink.logging.level" value="FINEST"/>
</properties>
</persistence-unit>
</persistence>
My EJB Class:
@Stateless(name="TestEJB", mappedName="ejb/MyProject/TestEJB")
@WebService
@Interceptors({SpringBeanAutowiringInterceptor.class})
@PersistenceUnit(name="MyPersistenceUnitJNDI", unitName="MyPersistenceUnit")
@TransactionManagement(TransactionManagementType.CONTAINER)
public class TestEJB implements TestEJBRemote, TestEJBLocal {
private static final Logger LOG = LoggerFactory.getLogger(TestEJB.class);
@Autowired
private ApplicationContext appContext;
@Autowired
private PersonRepository personRepo;
public TestEJB() {
}
@WebMethod
public String findPerson(String name) {
return ""+ personRepo.findByName(name);
}
@WebMethod
public String findAllPerson() {
return ""+ personRepo.findAll();
}
}
The Person entity class (simply auto-generated through Eclipse):
@Entity
@Table(name="PERSON")
public class Person implements Serializable {
private static final Long serialVersionUID = 1L;
@Id
@Column(name="ID")
private Long id;
private String name;
public Person() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
...
}
The PersonRepository class:
@Eager
public interface PersonRepository extends JpaRepository<Person, Long> {
List<Person> findByName(String name);
}
The DataConverter class:
@Service
public final class DataConverter implements Converter<Person, PersonDTO> {
@Autowired
private PersonRepository personRepository;
public DataConverter() {
}
@Override
public PersonDTO convert(Person p) {
...
}
}
UPDATE: following better the stacktrace, in particupar this part:
at weblogic.deployment.EntityManagerFactoryProxyImpl.invoke(EntityManagerFactoryProxyImpl.java:96)
at com.sun.proxy.$Proxy59.createEntityManager(Unknown Source)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:283)
at com.sun.proxy.$Proxy160.createNamedQuery(Unknown Source)
at org.springframework.data.jpa.repository.query.NamedQuery.<init>(NamedQuery.java:62)
at org.springframework.data.jpa.repository.query.NamedQuery.lookupFrom(NamedQuery.java:113)
it seems that Spring is not able to initialize a JPA repository if the Stateless bean creation is triggered by a call to a Transactional method!!!
Indeed, if I do the following: 1. Call a non-transactional method on the ejb (@TransactionAttributeType.NEVER): this call succeeds 2. Now I do call the personRepository.findByName: it works!
So the issue seems like that Spring JPA repositories fail to register their named queries when there is an ongoing CMT transaction.
Does this sounds familiar to someone ? Perhaps there is a way to avoid those repositories to be initialized within a transactional context ? (I tried @Eager annotation, but does not change anything in this context).
p.s. another bit of information: switching to Hibernate 3.6.10.Final as JPA Provider is a workaround to this issue. The more I work on this the more I believe could be a bug between Spring Data JPA and Eclipselink (I both tried Eclipselink 2.3 (embedded in Weblogic) and 2.5.2).
回答1:
I would like to add this workaround I found: switching to Hibernate 3.6.10.Final as JPA Provider fixes the issue.
This switch requires just to change the persistece.xml file, as follows:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.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_2_0.xsd">
<persistence-unit name="MyPersistenceUnit" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>db/myprojectdatasource</jta-data-source>
<class>myproject.dao.entities.Person</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.WeblogicTransactionManagerLookup" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
While in Spring you still have the EntityManagerFactory
looked up from the JNDI context and the JtaTransactionManager
.
Note that I am explicitly omitting to set the JtaFactoryClass
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory" />
property on hibernate: if I do so, for some reasons, Weblogic Transaction Manager disables auto-commit before executing transactions.
来源:https://stackoverflow.com/questions/25682503/transaction-exception-with-spring-4-0-6-weblogic-10-3-6-ejb-3-0-cmt-spring