Deadlock while syncronizing Spring entity manager query - spring

I'm developing an application using Spring which directs the DB using entity manager with #PersistenceContext injection. the application is executed in multiple threads, each in its own #Transactional scope.
As part of the thread process it should go and call :
entityManager.createQuery("some statement").getResultList()
This should return if an object exists on the DB and if not it will persist it. because i am using multiple threads i have put the call in a syncronized block on a shared object like this:
synchronized (getLock())
{
List<SomeObject> listOfObjects = entityManager.createQuery("some statement").getResultList();
if(listOfObjects == null || listOfObjects.size() < 1)
{
createObject();
}
}
The problem is that when I'm running this the process get stuck on the call to the getResultList and never released. Moreover, when i run the code and creating only one thread I get the same behavior.
if i change the flushMode to COMMIT the process is released but the results are not reflected well because the different threads could end at different times and the one creating the object will not necessarily be the one to end first.
my persistence xml is:
<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_1_0.xsd"
version="1.0">
<persistence-unit name="syncAdapterUnit"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.max_fetch_depth" value="3"/>
<property name="hibernate.connection.pool_size" value="10"/>
<property name="format_sql" value="false"/>
<property name="hibernate.jdbc.batch_size" value="50" />
<property name="hibernate.cache.use_query_cache" value="false" />
<property name="hibernate.cache.use_second_level_cache" value="false" />
</properties>
</persistence-unit>
</persistence>
The spring bean xml:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="managerFactoryBean" class="com.amdocs.dim.ManagerFactory" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" destroy-method="destroy">
<property name="dataSource" ref="myDataSource"/>
<property name="jpaVendorAdapter" ref="hibernateVendorAdapter"/>
<property name="persistenceUnitName" value="syncAdapterUnit"/>
</bean>
<bean id="hibernateVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="false"/>
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="database" value="ORACLE"/>
</bean>
<bean id="cifDBProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="location" value="classpath:APP-INF/conf/database.properties"/>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK"/>
</bean>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" scope="singleton">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
I believe that the flush process is the one which blocks the app but didn't manage to understand why.

Related

Hibernate JPA Persistence multiple database with Spring

I'm trying to add a new connection to my project based on Spring, JPA and Hibernate. I dont know what's wrong with my settings when I add the second connection
database.properties
database.driverClassName=oracle.jdbc.OracleDriver
database.url=jdbc:oracle:thin:#192.33.333.33:1530:sid
database.username=user
database.password=pass
#DB2
database2.driverClassName=oracle.jdbc.OracleDriver
database2.url=jdbc:oracle:thin:#192.33.333.33:1530:sid
database2.username=user2
database2.password=pass
persistence.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="persistenceUnitUno" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<!-- value="create" to build a new database on each run; value="update" to modify an existing database; value="create-drop" means the same as "create" but also drops tables when Hibernate closes; value="validate" makes no changes to the database -->
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.DefaultNamingStrategy"/>
<property name="hibernate.connection.charSet" value="UTF-8"/>
<property name="hibernate.default_schema" value="user"/>
<property name="hibernate.show_sql" value="false"/>
</properties>
</persistence-unit>
<persistence-unit name="persistenceUnitDos" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.DefaultNamingStrategy"/>
<property name="hibernate.connection.charSet" value="UTF-8"/>
<property name="hibernate.default_schema" value="user2"/>
<property name="hibernate.show_sql" value="false"/>
</properties>
</persistence-unit>
</persistence>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>
<context:spring-configured/>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:config/ehcache.xml"/>
<property name="shared" value="true"/>
</bean>
<bean id="cacheManager" class="com.project.cache.CacheManager">
<property name="cacheManager" ref="ehcache"/>
</bean>
<context:component-scan base-package="com.project">
<context:exclude-filter expression=".*_Roo_.*" type="regex"/>
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
<context:exclude-filter type="regex" expression="com.project.interceptor.component.*" />
</context:component-scan>
<cache:annotation-driven/>
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSourceUno">
<property name="driverClassName" value="${database.driverClassName}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="true"/>
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="1800000"/>
<property name="numTestsPerEvictionRun" value="3"/>
<property name="minEvictableIdleTimeMillis" value="1800000"/>
<property name="validationQuery" value="SELECT 1 FROM DUAL"/>
</bean>
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSourceDos">
<property name="driverClassName" value="${database2.driverClassName}"/>
<property name="url" value="${database2.url}"/>
<property name="username" value="${database2.username}"/>
<property name="password" value="${database2.password}"/>
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="true"/>
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="1800000"/>
<property name="numTestsPerEvictionRun" value="3"/>
<property name="minEvictableIdleTimeMillis" value="1800000"/>
<property name="validationQuery" value="SELECT 1 FROM DUAL"/>
</bean>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactoryUno">
<property name="persistenceUnitName" value="persistenceUnitUno"/>
<property name="dataSource" ref="dataSourceUno"/>
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactoryDos">
<property name="persistenceUnitName" value="persistenceUnitDos"/>
<property name="dataSource" ref="dataSourceDos"/>
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManagerUno">
<property name="entityManagerFactory" ref="entityManagerFactoryUno"/>
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManagerDos">
<property name="entityManagerFactory" ref="entityManagerFactoryDos"/>
</bean>
<bean id="org.springframework.context.annotation.internalPersistenceAnnotationProcessor"
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" >
<property name="defaultPersistenceUnitName" value="entityManagerFactoryUno"/>
</bean>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
Error:
INFO || || Class: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean || Line: 285 || Building JPA container EntityManagerFactory for persistence unit 'persistenceUnitUno'
INFO || || Class: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean || Line: 285 || Building JPA container EntityManagerFactory for persistence unit 'persistenceUnitDos'
INFO || Date: || Class: java.sql.DatabaseMetaData || Line: 147 || HHH000262: Table not found: TABLE
.....
Caused by: org.hibernate.HibernateException: Missing table: TABLE
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1335)
at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:155)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:525)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1859)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:852)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:845)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:844)
at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:152)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:67)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:288)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1571)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1509)
... 22 more
the TABLE on the error belongs to the first user scheme, it should not happen in user2.
Assuming the Entities reside in different packages, you can control which entities are associated with each persitence unit by setting the packagesToScan property as below:
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactoryUno">
<property name="persistenceUnitName" value="persistenceUnitUno"/>
<property name="dataSource" ref="dataSourceUno"/>
<property name="packagesToScan">
<list>
<value>com.test.domain.entitiesforpu1.package1</value
<value>com.test.domain.entitiesforpu1.package2</value
</list>
<property>
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactoryDos">
<property name="persistenceUnitName" value="persistenceUnitDos"/>
<property name="dataSource" ref="dataSourceDos"/>
<property name="packagesToScan">
<list>
<value>com.test.domain.entitiesforpu2.package1</value
</list>
<property>
</bean
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.html#setPackagesToScan-java.lang.String...-
If the entities are not in separate packages then the other option is to explicity list the classes in each persistence unit and exclude any lised which would look like:
<persistence-unit name="persistenceUnitDos" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.DefaultNamingStrategy"/>
<property name="hibernate.connection.charSet" value="UTF-8"/>
<property name="hibernate.default_schema" value="user2"/>
<property name="hibernate.show_sql" value="false"/>
</properties>
<class>com.acme.Entity1ForPu2</class>
<class>com.acme.Entity2ForPu2</class>
<class>com.acme.Entity3ForPu2</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>

Spring JPA configuration issue

I have gone through almost all the posts here regarding Spring JPA configuration. Basically I want to implement JPA Pagination in my project and for that I need spring JPA support. But when I include the spring-data-jpa.jar in my project I get the following exception.
Caused by: java.lang.IllegalArgumentException: JBAS011470: Persistence unitName was not specified and there are 2 persistence unit definitions in application deployment deployment "CPCardApp.ear". Either change the application deployment to have only one persistence unit definition or specify the unitName for each reference to a persistence unit.
at org.jboss.as.jpa.container.PersistenceUnitSearch.ambiguousPUError(PersistenceUnitSearch.java:172)
at org.jboss.as.jpa.container.PersistenceUnitSearch.findWithinDeployment(PersistenceUnitSearch.java:152)
at org.jboss.as.jpa.container.PersistenceUnitSearch.findWithinApplication(PersistenceUnitSearch.java:86)
at org.jboss.as.jpa.container.PersistenceUnitSearch.findPersistenceUnitSupplier(PersistenceUnitSearch.java:76)
at org.jboss.as.jpa.container.PersistenceUnitSearch.resolvePersistenceUnitSupplier(PersistenceUnitSearch.java:63)
at org.jboss.as.jpa.processor.JPAAnnotationParseProcessor.getPersistenceUnit(JPAAnnotationParseProcessor.java:357)
at org.jboss.as.jpa.processor.JPAAnnotationParseProcessor.getBindingSource(JPAAnnotationParseProcessor.java:288)
at org.jboss.as.jpa.processor.JPAAnnotationParseProcessor.processMethod(JPAAnnotationParseProcessor.java:201)
at org.jboss.as.jpa.processor.JPAAnnotationParseProcessor.processPersistenceAnnotations(JPAAnnotationParseProcessor.java:138)
at org.jboss.as.jpa.processor.JPAAnnotationParseProcessor.deploy(JPAAnnotationParseProcessor.java:95)
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:116) [jboss-as-server-7.1.3.Final-redhat-4.jar:7.1.3.Final-redhat-4]
... 5 more
persistence.xml (Note: I have 2 persistence units in my xml and Spring doesn't support that)
<?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="data01">
<jta-data-source>java:/MySqlDataDS</jta-data-source>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.cache.use_second_level_cache"
value="false" />
<property name="hibernate.id.new_generator_mappings" value="false" />
</properties>
</persistence-unit>
<persistence-unit name="cpaudit">
<jta-data-source>java:/MySqlAuditDS</jta-data-source>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.cache.use_second_level_cache"
value="false" />
<property name="hibernate.id.new_generator_mappings" value="false" />
</properties>
</persistence-unit>
</persistence>
You can have 2 persistence units. There are problems with your config (combo of using JBoss + Spring + JPA (Hibernate) + JTA). The proper configuration will depend on your version of JBoss and Spring.
No matter what you will need to have an xml file to define your JPA config with two entity managers.
Try something like this in a application-jpa-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:transaction="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<beans>
<bean id="entityManagerFactorData01" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaProperties">
<map>
<entry key="hibernate.cache.use_second_level_cache" value="false"/>
<entry key="hibernate.id.new_generator_mappings" value="false"/>
<entry key="hibernate.transaction.jta.platform" value-ref="jtaPlatform"/>
</map>
</property>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jtaDataSource">
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}"/>
<property name="password" value="${database.data01.password}"/>
<property name="url" value="${database.data01.url}"/>
<property name="username" value="${database.data01.user}"/>
</bean>
</property>
<property name="packagesToScan" value="com.app.entites.data01"/>
</bean>
<bean id="entityManagerFactoryCpaudit"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaProperties">
<map>
<entry key="hibernate.cache.use_second_level_cache" value="false"/>
<entry key="hibernate.id.new_generator_mappings" value="false"/>
<entry key="hibernate.transaction.jta.platform" value-ref="jtaPlatform"/>
</map>
</property>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jtaDataSource">
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}"/>
<property name="password" value="${database.cpaudit.password}"/>
<property name="url" value="${database.cpaudit.url}"/>
<property name="username" value="${database.cpaudit.user}"/>
</bean>
</property>
<property name="packagesToScan" value="com.app.entites.cpaudit"/>
</bean>
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" id="jpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/>
</bean>
<context:annotation-config/>
<jpa:repositories base-package="com.app.repo.data01" entity-manager-factory-ref="entityManagerFactorData01"/>
<jpa:repositories base-package="com.app.repo.cpaudit" entity-manager-factory-ref="entityManagerFactoryCpaudit"/>
<!-- ************ JpaTransactionManager *********** -->
<!--
This will depend on your JBoss and Spring version and your application.
You will need to work this out.
Getting your transactionManager correct could be difficult.
See the following project for more ideas:
https://github.com/manish-in-java/spring-data-jta/blob/master/src/main/resources/springContext.xml
-->
<transaction:annotation-driven/>
<bean class="java.lang.String" id="jtaPlatform">
<constructor-arg value="org.hibernate.engine.transaction.jta.platform.internal.JBossStandAloneJtaPlatform"/>
</bean>
<bean class="org.springframework.transaction.jta.JtaTransactionManager" id="transactionManager">
<property name="transactionManager">
<bean class="com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple"/>
</property>
<property name="userTransaction">
<bean class="com.arjuna.ats.jta.UserTransaction" factory-method="userTransaction"/>
</property>
</bean>
<!-- ************ JpaTransactionManager *********** -->
</beans>
</beans>

java.lang.ClassCastException: org.apache.xerces.parsers.SAXParser cannot be cast to org.xml.sax.XMLReader Hibernate

I am working on a project with Hibernate JPA /spring.
It throws the following exception. After doing some reading I removed all the xml-apis from dependencies but it throws the same error. Any ideas ??
java.lang.ClassCastException: org.apache.xerces.parsers.SAXParser cannot be cast to org.xml.sax.XMLReader
at org.xml.sax.helpers.XMLReaderFactory.loadClass(XMLReaderFactory.java:199)
at org.xml.sax.helpers.XMLReaderFactory.createXMLReader(XMLReaderFactory.java:150)
at org.dom4j.io.SAXHelper.createXMLReader(SAXHelper.java:83)
at org.dom4j.io.SAXReader.createXMLReader(SAXReader.java:894)
at org.dom4j.io.SAXReader.getXMLReader(SAXReader.java:715)
at org.dom4j.io.SAXReader.setFeature(SAXReader.java:218)
at org.hibernate.internal.util.xml.MappingReader.setValidationFor(MappingReader.java:114)
at org.hibernate.internal.util.xml.MappingReader.readMappingDocument(MappingReader.java:77)
at org.hibernate.cfg.Configuration.add(Configuration.java:478)
at org.hibernate.cfg.Configuration.add(Configuration.java:474)
at org.hibernate.cfg.Configuration.add(Configuration.java:647)
at org.hibernate.cfg.Configuration.addInputStream(Configuration.java:685)
at org.hibernate.ejb.Ejb3Configuration.addClassesToSessionFactory(Ejb3Configuration.java:1248)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1048)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:693)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:225)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
while I am trying to initialise the web context in jetty web server it throw the above exception.[Spring (3.0.6.Release) & hibernate (4.1.10.final) ]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<import resource="classpath*:/META-INF/spring-orchestra-init.xml"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:persistenceUnitName="persistenceUnit">
<property name="dataSource" ref="dataSource"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="false"/>
</bean>
</property>
<property name="loadTimeWeaver">
<bean class="org.faces.controller.jpa.JpaLoadTimeWeaver"/>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="conversation.access">
<bean class="org.apache.myfaces.orchestra.conversation.spring.SpringConversationScope">
<property name="advices">
<list>
<ref bean="persistentContextConversationInterceptor" />
</list>
</property>
</bean>
</entry>
</map>
</property>
</bean>
<bean id="jpaPersistentContextFactory" class="org.apache.myfaces.orchestra.conversation.spring.JpaPersistenceContextFactory">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="persistentContextConversationInterceptor" class="org.apache.myfaces.orchestra.conversation.spring.PersistenceContextConversationInterceptor">
<property name="persistenceContextFactory" ref="jpaPersistentContextFactory" />
</bean>
<bean name="org.apache.myfaces.orchestra.conversation.AccessScopeManagerConfiguration"
class="org.apache.myfaces.orchestra.conversation.AccessScopeManagerConfiguration"
scope="singleton" lazy-init="true">
<property name="ignoreViewIds">
<set>
<value>/__ADFv__.xhtml</value>
</set>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#rum:1541:CHEZTST" />
<property name="username" value="username" />
<property name="password" value="password" />
</bean>
After removing the loadtimeweaver property it worked fine.
<property name="loadTimeWeaver">
<bean class="org.faces.controller.jpa.JpaLoadTimeWeaver"/>
</property>
this is the link that shows that, although it is quite old it works
https://jira.springsource.org/browse/SPR-2596

JBoss AS7 + Oracle 11g + Spring 3.1 + JPA 2 - Multiple DSs, PUs, EMs, TMs

I'm building an application that needs CRUD operations on two separate databases. The transactions are applied to one database or the other (never both...so no need for JTA is my understanding). My setup is pretty close to what is found here: Multiple database with Spring+Hibernate+JPA
The problem: My server (JBoss AS7) starts up fine. The application reads from both datasources, say DS1 and DS2, BUT it can only manipulate data from DS1. I can see sequences (Oracle 11g) being updated but no table updates. There are no errors/exceptions thrown. I suspect one of my transaction managers isn't committing.
Below is a list of technologies used and configuration settings...
Tech Stack
JBoss AS7
Oracle 11g
Spring 3.1
JPA 2
Hibernate 4.1
persistence-ds1.xml
<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="pu1">
<class>com.somepackage.EntityA</class>
<class>com.somepackage.EntityB</class>
<class>com.somepackage.EntityC</class>
<validation-mode>CALLBACK</validation-mode>
<properties>
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.DefaultNamingStrategy" />
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
</properties>
</persistence-unit>
</persistence>
persistence-ds2.xml
<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="pu2">
<class>com.somepackage.EntityD</class>
<class>com.somepackage.EntityE</class>
<class>com.somepackage.EntityF</class>
<validation-mode>CALLBACK</validation-mode>
<properties>
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.DefaultNamingStrategy" />
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
</properties>
</persistence-unit>
</persistence>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee.xsd">
<jee:jndi-lookup id="ds1" jndi-name="java:jboss/datasources/DS1"
expected-type="javax.sql.DataSource" />
<jee:jndi-lookup id="ds2" jndi-name="java:jboss/datasources/DS2"
expected-type="javax.sql.DataSource" />
<bean id="em1" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="emf1" />
<property name="persistenceUnitName" value="pu1" />
</bean>
<bean id="em2" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="emf2" />
<property name="persistenceUnitName" value="pu2" />
</bean>
<bean id="emf1" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence-ds1.xml"/>
<property name="dataSource" ref="ds1" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
</bean>
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
<bean id="emf2" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence-ds2.xml"/>
<property name="dataSource" ref="ds2" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
</bean>
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
<tx:annotation-driven transaction-manager="txm1" />
<tx:annotation-driven transaction-manager="txm2" />
<bean id="txm1" class="org.springframework.orm.jpa.JpaTransactionManager">
<qualifier value="txMgr1"/>
<property name="entityManagerFactory" ref="emf1" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
<bean id="txm2" class="org.springframework.orm.jpa.JpaTransactionManager">
<qualifier value="txMgr2"/>
<property name="entityManagerFactory" ref="emf2" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
</beans>
In my DAOs, I reference the transaction managers at the class-level as follows.
#Transactional("txm1")
public class DAO1 { ... }
#Transactional("txm2")
public class DAO2 { ... }
I resolved my issue!
In my applicationContext.xml, I removed the following.
<tx:annotation-driven transaction-manager="txm1" />
<tx:annotation-driven transaction-manager="txm2" />
And used the following instead.
<tx:annotation-driven />
But here's what I believe was the kicker (main problem). In my DAOs, I was assigning the two transaction managers at the class-level. But then I was overriding them with the way I was declaring my methods.
#Transactional(readOnly = false, value = "txm1")
public abstract class AbstractJpaDAO1<T extends Serializable> {
...
#Transactional(readOnly = true)
public T findById(final Long id) {...}
#Transactional
public boolean insert(final T entity) {...}
As you can see, the #Transaction annotations on the methods were overriding the the one at the class-level. And because there was no transaction manager specified on the methods, Spring defaulted to "transactionManager", which I didn't (and still don't) have declared in my applicaitonContext.xml. So, it was trying to commit using a transaction manager that didn't exist.
For the resolution, I just removed the #Transitional annotations on the methods, and kept the one at the class-level.
#Transactional(readOnly = false, value = "txm1")
public abstract class AbstractJpaDAO1<T extends Serializable> {
...
public T findById(final Long id) {...}
public boolean insert(final T entity) {...}
Now everything works! I can read/write to two separate databases.

Spring, OpenJPA, multiple persistence unit

There is a spring no-web application Apache James (Java Mail server).
It uses openjpa. It has a persistence unit and datasource and entitymanager factory definition.
I must manipulate it to use one more persistence unit, for an external DB.
I added one more unit into persistence.xml
<persistence-unit name="James" transaction-type="RESOURCE_LOCAL">
<!-- Mailbox stuff-->
<class>org.apache.james.mailbox.jpa.mail.model.JPAMailbox</class>
<class>org.apache.james.mailbox.jpa.mail.model.JPAUserFlag</class>
<class>org.apache.james.mailbox.jpa.mail.model.openjpa.AbstractJPAMessage</class>
<class>org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMessage</class>
<class>org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMessage</class>
<class>org.apache.james.mailbox.jpa.mail.model.JPAProperty</class>
<class>org.apache.james.mailbox.jpa.user.model.JPASubscription</class>
<class>org.apache.james.domainlist.jpa.model.JPADomain</class>
<class>org.apache.james.user.jpa.model.JPAUser</class>
<class>org.apache.james.rrt.jpa.model.JPARecipientRewrite</class>
<properties>
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
<property name="openjpa.jdbc.MappingDefaults" value="ForeignKeyDeleteAction=cascade, JoinForeignKeyDeleteAction=cascade"/>
<property name="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)"/>
<property name="openjpa.jdbc.QuerySQLCache" value="false"/>
</properties>
</persistence-unit>
<persistence-unit name="myPU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>package.EmailAddress</class>
<class>package.Message</class>
<properties>
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="root" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/kepsDb" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="hibernate.hbm2ddl.auto" value="none" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.dialect" value=" org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.max_fetch_depth" value="0" />
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="false" />
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory" />
<property name="hibernate.ejb.naming_strategy" value="web.app.persistence.util.AppImprovedNamingStrategy"/>
</properties>
</persistence-unit>
I do not define a second entity manager factory in spring-server.xml, instead, i generate my own entitymanager factory inline with:
EntityManagerFactory emf=Persistence.createEntityManagerFactory("myPU");
EntityManager entityManager=emf.createEntityManager();
entityManager.getTransaction().begin();
But i am getting exception:
Caused by: org.springframework.beans.FatalBeanException: Unable to execute lifecycle method on beanmailetcontext; nested exception is <openjpa-2.1.0-r422266:1071316 nonfatal user error> org.apache.openjpa.persistence.InvalidStateException: This operation cannot be performed while a Transaction is active.
myPU is configured to use JTA transaction. Calling entityManager.getTransaction() when using JTA will cause exception as this method is supposed to use with RESOURCE_LOCAL transaction type .
I don't know if your posted exception messages is due to this , but you can try to change the <persistence-unit> of myPU to :
<persistence-unit name="myPU" transaction-type="RESOURCE_LOCAL">
Please note that if you have to access both databases in the same transaction , you must use JTA .
Following code explains how to configure multiple persistence units with JPA + spring:
First of all, we define two persistence units in the persistence.xml, lets call them unit1 and unit2 respectively:
<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_1_0.xsd"
version="1.0">
<persistence-unit name="Unit1" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver" />
<property name="hibernate.connection.url" value="jdbc:oracle:thin:#my.company.com:1522:D1" />
<property name="hibernate.connection.password" value="my_user" />
<property name="hibernate.connection.username" value="my_password" />
</properties>
</persistence-unit>
<persistence-unit name="Unit2" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver" />
<property name="hibernate.connection.url" value="jdbc:oracle:thin:#my.company.com:1522:D2" />
<property name="hibernate.connection.password" value="my_user" />
<property name="hibernate.connection.username" value="my_password" />
</properties>
</persistence-unit>
</persistence>
Since we dealt with a stand-alone Java applicatie, we defined our data sources in the Spring application context, but for web applicaties one typically defines JNDI references to these datasources in the persistence.xml file itself.
From within the application-context.xml these persisetence units are referred to like so:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:annotation-config />
<tx:annotation-driven />
<bean id="dataSource1" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
<property name="jdbcUrl" value="jdbc:oracle:thin:#my.company.com:1521:D1" />
<property name="user" value="my_user" />
<property name="password" value="my_password" />
</bean>
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#my.company.com:1521:D2" />
<property name="username" value="my_user" />
<property name="password" value="my_password" />
</bean>
<!-- DEFINITION OF BOTH ENTITY MANAGER FACTORIES -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource1" />
<property name="persistenceUnitName" value="Unit1" />
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform"
value="org.hibernate.dialect.Oracle10gDialect" />
</bean>
</property>
</bean>
<bean id="entityManagerFactory2"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource2" />
<property name="persistenceUnitName" value="Unit2" />
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform"
value="org.hibernate.dialect.Oracle10gDialect" />
</bean>
</property>
</bean>
<!-- PERSISTENCE UNIT MANAGER and TRANSACTION MANAGERS -->
<bean id="persistenceUnitManager"
class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="dataSources">
<map>
<entry key="d1" value-ref="dataSource1" />
<entry key="d2" value-ref="dataSource2" />
</map>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager"
p:entity-manager-factory-ref="entityManagerFactory" />
<bean id="abwTransactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager"
p:entity-manager-factory-ref="entityManagerFactory2" />
</beans>
Now all that is left to do is denote the #PersistenceContext in your DAOs like so:
#Required
#PersistenceContext(unitName = "Unit1")
public void setEntityManager(final EntityManager entityManager) {
this.entityManager = entityManager;
}

Resources