We have run into the #22224 bug trying to migrate a working Hiberate 5 application from Glassfish 4 to Glassfish 5. Therefore we are attempting deployment in other JPA containers.
TomEE 7 is such a JPA container and we have Tomcat experience on our team. However, the primary difference between Glassfish and TomEE seems to be the definition of the datasource via the an XML file in the WAR rather than defining it via an admin console.
Our attempt to configure said datasource is resulting in what seems to be the creation and linkage to our application, but then an immediate call to destroy the datasource which fails and unloads our application.
resources.xml =
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<Resource id="topazDS" type="javax.sql.DataSource">
jdbcDriver = oracle.jdbc.OracleDriver
jdbcUrl = jdbc:oracle:thin:#dacracot.net:1521:DCCDB
password = password
passwordCipher = PlainText
userName = topaz
</Resource>
</resources>
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="topazDB" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>topazDS</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<shared-cache-mode>ALL</shared-cache-mode>
<properties>
<property name="hibernate.ejb.entitymanager_factory_name" value="topaz"/>
<property name="hibernate.connection.release_mode" value="auto" />
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.SunONETransactionManagerLookup"/>
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/>
<property name="hibernate.current_session_context_class" value="jta"/>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.use_sql_comments" value="false" />
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory" />
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
<property name="hibernate.cache.provider_configuration_file_resource_path" value="hibernate-ehcache.xml" />
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.cache.generate_statistics" value="true" />
<property name="hibernate.cache.use_structured_queries" value="false" />
<property name="hibernate.cache.use_minimal_puts" value="false" />
<property name="hibernate.max_fetch_depth" value="3" />
</properties>
</persistence-unit>
</persistence>
catalina.out =
02-Aug-2018 08:01:59.702 INFO [localhost-startStop-1] sun.reflect.DelegatingMethodAccessorImpl.invoke Deploying web application archive [/Users/dacracot/Desktop/TopazDev/apache-tomee-plume-7.0.5/webapps/topaz.war]
02-Aug-2018 08:01:59.708 INFO [localhost-startStop-1] org.apache.tomee.catalina.TomcatWebAppBuilder.init ------------------------- localhost -> /topaz
02-Aug-2018 08:01:59.710 INFO [localhost-startStop-1] org.apache.openejb.util.JarExtractor.extract Extracting jar: /Users/dacracot/Desktop/TopazDev/apache-tomee-plume-7.0.5/webapps/topaz.war
02-Aug-2018 08:02:01.019 INFO [localhost-startStop-1] org.apache.openejb.util.JarExtractor.extract Extracted path: /Users/dacracot/Desktop/TopazDev/apache-tomee-plume-7.0.5/webapps/topaz
02-Aug-2018 08:02:01.039 WARNING [localhost-startStop-1] org.apache.catalina.startup.SetContextPropertiesRule.begin [SetContextPropertiesRule]{Context} Setting property 'antiJARLocking' to 'true' did not find a matching property.
02-Aug-2018 08:02:09.714 INFO [localhost-startStop-1] org.apache.openejb.config.ConfigurationFactory.configureApplication Configuring enterprise application: /Users/dacracot/Desktop/TopazDev/apache-tomee-plume-7.0.5/webapps/topaz
02-Aug-2018 08:02:11.513 INFO [localhost-startStop-1] org.apache.openejb.config.ConfigurationFactory.configureService Configuring Service(id=topaz/topazDS, type=Resource, provider-id=Default JDBC Database)
02-Aug-2018 08:02:11.518 INFO [localhost-startStop-1] org.apache.openejb.assembler.classic.Assembler.createRecipe Creating Resource(id=topaz/topazDS)
02-Aug-2018 08:02:12.986 INFO [localhost-startStop-1] org.apache.openejb.config.ConfigurationFactory.configureService Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container)
02-Aug-2018 08:02:12.986 INFO [localhost-startStop-1] org.apache.openejb.config.AutoConfig.createContainer Auto-creating a container for bean topaz.Comp1690781744: Container(type=MANAGED, id=Default Managed Container)
02-Aug-2018 08:02:12.987 INFO [localhost-startStop-1] org.apache.openejb.assembler.classic.Assembler.createRecipe Creating Container(id=Default Managed Container)
02-Aug-2018 08:02:12.998 INFO [localhost-startStop-1] org.apache.openejb.core.managed.SimplePassivater.init Using directory /Users/dacracot/Desktop/TopazDev/tomee/temp for stateful session passivation
02-Aug-2018 08:02:13.017 INFO [localhost-startStop-1] org.apache.openejb.config.AutoConfig.processResourceRef Auto-linking resource-ref 'jdbc/topaz' in bean topaz.Comp1690781744 to Resource(id=topazDS)
02-Aug-2018 08:02:13.017 INFO [localhost-startStop-1] org.apache.openejb.config.AutoConfig.processResourceRef Auto-linking resource-ref 'openejb/Resource/topaz/topazDS' in bean topaz.Comp1690781744 to Resource(id=topaz/topazDS)
02-Aug-2018 08:02:13.018 INFO [localhost-startStop-1] org.apache.openejb.config.AutoConfig.processResourceRef Auto-linking resource-ref 'openejb/Resource/topazDS' in bean topaz.Comp1690781744 to Resource(id=topaz/topazDS)
02-Aug-2018 08:02:13.018 INFO [localhost-startStop-1] org.apache.openejb.config.AutoConfig.deploy Configuring PersistenceUnit(name=topazDB, provider=org.hibernate.jpa.HibernatePersistenceProvider)
02-Aug-2018 08:02:13.019 INFO [localhost-startStop-1] org.apache.openejb.config.AutoConfig.logAutoCreateResource Auto-creating a Resource with id 'topaz/topazDSNonJta' of type 'DataSource for 'topazDB'.
02-Aug-2018 08:02:13.019 INFO [localhost-startStop-1] org.apache.openejb.config.AutoConfig.deploy Configuring Service(id=topaz/topazDSNonJta, type=Resource, provider-id=topaz/topazDS)
02-Aug-2018 08:02:13.019 INFO [localhost-startStop-1] org.apache.openejb.assembler.classic.Assembler.createRecipe Creating Resource(id=topaz/topazDSNonJta)
02-Aug-2018 08:02:13.691 INFO [localhost-startStop-1] org.apache.openejb.config.AutoConfig.setJtaDataSource Adjusting PersistenceUnit topazDB <jta-data-source> to Resource ID 'topaz/topazDS' from 'topazDS'
02-Aug-2018 08:02:13.691 INFO [localhost-startStop-1] org.apache.openejb.config.AutoConfig.setNonJtaDataSource Adjusting PersistenceUnit topazDB <non-jta-data-source> to Resource ID 'topaz/topazDSNonJta' from 'null'
02-Aug-2018 08:02:13.705 INFO [localhost-startStop-1] org.apache.openejb.util.OptionsLog.info Using 'javax.persistence.provider=org.hibernate.ejb.HibernatePersistence'
02-Aug-2018 08:02:13.729 INFO [localhost-startStop-1] org.apache.openejb.config.AppInfoBuilder.build Enterprise application "/Users/dacracot/Desktop/TopazDev/apache-tomee-plume-7.0.5/webapps/topaz" loaded.
02-Aug-2018 08:02:13.734 INFO [localhost-startStop-1] org.apache.openejb.assembler.classic.Assembler.createApplication Assembling app: /Users/dacracot/Desktop/TopazDev/apache-tomee-plume-7.0.5/webapps/topaz
02-Aug-2018 08:02:13.761 INFO [localhost-startStop-1] org.apache.openejb.assembler.classic.ReloadableEntityManagerFactory.createDelegate PersistenceUnit(name=topazDB, provider=org.hibernate.ejb.HibernatePersistence) - provider time 1ms
02-Aug-2018 08:02:13.761 INFO [localhost-startStop-1] org.apache.openejb.assembler.classic.Assembler.destroyApplication Undeploying app: /Users/dacracot/Desktop/TopazDev/apache-tomee-plume-7.0.5/webapps/topaz
02-Aug-2018 08:02:13.765 SEVERE [localhost-startStop-1] sun.reflect.NativeMethodAccessorImpl.invoke ContainerBase.removeChild: destroy:
org.apache.catalina.LifecycleException: An invalid Lifecycle transition was attempted ([before_destroy]) for component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/topaz]] in state [STARTING_PREP]
at org.apache.catalina.util.LifecycleBase.invalidTransition(LifecycleBase.java:402)
at org.apache.catalina.util.LifecycleBase.destroy(LifecycleBase.java:292)
at org.apache.catalina.core.ContainerBase.removeChild(ContainerBase.java:856)
at org.apache.tomee.catalina.TomcatWebAppBuilder.undeploy(TomcatWebAppBuilder.java:1651)
at org.apache.tomee.catalina.TomcatWebAppBuilder.undeploy(TomcatWebAppBuilder.java:1631)
at org.apache.tomee.catalina.TomcatWebAppBuilder.undeployWebApps(TomcatWebAppBuilder.java:764)
at org.apache.openejb.assembler.classic.Assembler.destroyApplication(Assembler.java:2374)
at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:1092)
at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:757)
at org.apache.tomee.catalina.TomcatWebAppBuilder.startInternal(TomcatWebAppBuilder.java:1303)
at org.apache.tomee.catalina.TomcatWebAppBuilder.configureStart(TomcatWebAppBuilder.java:1125)
at org.apache.tomee.catalina.GlobalListenerSupport.lifecycleEvent(GlobalListenerSupport.java:133)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:94)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5154)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:754)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:985)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
which version of hibernate did you add to tomee? Maybe ensure it is aligned on the JPA spec provided by TomEE (and you dont use a JPA 2.2 impl for the JPA 2.1 API for instance). Also, in some versions, hibernate has a chicken egg bug in its lifecycle between CDI and JPA so you can need to set the datasource as lazy (Lazy=true in its definition/properties).
Maybe also check logs/ folder, you should get a more precise reason for the error cause here it seems the application deployment is reverted cause of an issue which doesn't appear in the "out" log but should appear in log files.
Romain
My kar file contains the following bundles:
a)common-bundle(contains hibernate as the JPA provider)
b)client-bundle(accesses the entityManagerFactory present inside common-bundle and execute business logic)
I've a strange problem while executing hot deploy of kar file on karaf container.
If I try to do a normal deploy(i.e. by stopping the karaf container,putting the kar file into deploy folder and re-starting karaf container),both the bundles get up and running without any problem.
However,when I try to hot deploy the kar file on karaf container,it throws me the following exception:
Dec 06 13:50:50 INFO 141 HHH000204: Processing PersistenceUnitInfo [
name: MyModelClass
...]
Dec 06 13:50:51 INFO 141 HHH000130: Instantiating explicit connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider
Dec 06 13:50:51 ERROR 187 The DataSource osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/ds) required by bundle common-bundle/0.0.1.SNAPSHOT could not be found.
javax.naming.NameNotFoundException: osgi:service/javax.sql.DataSource/"(osgi.jndi.service.name=jdbc/ds)"
at org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:113)[66:org.apache.aries.jndi.url:1.1.0]
at org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:138)[66:org.apache.aries.jndi.url:1.1.0]
at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)[64:org.apache.aries.jndi.core:1.0.2]
at javax.naming.InitialContext.lookup(InitialContext.java:417)[:1.8.0_141]
at org.apache.aries.jpa.container.unit.impl.JndiDataSource.getDs(JndiDataSource.java:66)[187:org.apache.aries.jpa.container:1.0.4]
at org.apache.aries.jpa.container.unit.impl.DelayedLookupDataSource.getConnection(DelayedLookupDataSource.java:36)[187:org.apache.aries.jpa.container:1.0.4]
at org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider.getConnection(InjectedDataSourceConnectionProvider.java:70)[213:org.hibernate.entitymanager:4.2.21.Final]
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcServicesImpl.java:242)[212:org.hibernate.core:4.2.21.Final]
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:117)[212:org.hibernate.core:4.2.21.Final]
at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:85)[212:org.hibernate.core:4.2.21.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:184)[212:org.hibernate.core:4.2.21.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:156)[212:org.hibernate.core:4.2.21.Final]
at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1827)[212:org.hibernate.core:4.2.21.Final]
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1785)[212:org.hibernate.core:4.2.21.Final]
at org.hibernate.ejb.EntityManagerFactoryImpl.(EntityManagerFactoryImpl.java:96)[213:org.hibernate.entitymanager:4.2.21.Final]
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:915)[213:org.hibernate.entitymanager:4.2.21.Final]
at org.hibernate.osgi.OsgiPersistenceProvider.createContainerEntityManagerFactory(OsgiPersistenceProvider.java:99)[214:org.hibernate.osgi:4.2.21.Final]
at org.apache.aries.jpa.container.impl.EntityManagerFactoryManager.createEntityManagerFactories(EntityManagerFactoryManager.java:432)[187:org.apache.aries.jpa.container:1.0.4]
at org.apache.aries.jpa.container.impl.EntityManagerFactoryManager.registerEntityManagerFactories(EntityManagerFactoryManager.java:292)[187:org.apache.aries.jpa.container:1.0.4]
at org.apache.aries.jpa.container.impl.EntityManagerFactoryManager.access$000(EntityManagerFactoryManager.java:74)[187:org.apache.aries.jpa.container:1.0.4]
at org.apache.aries.jpa.container.impl.EntityManagerFactoryManager$1.call(EntityManagerFactoryManager.java:203)[187:org.apache.aries.jpa.container:1.0.4]
at org.apache.aries.jpa.container.impl.EntityManagerFactoryManager$1.call(EntityManagerFactoryManager.java:199)[187:org.apache.aries.jpa.container:1.0.4]
at java.util.concurrent.FutureTask.run(FutureTask.java:266)[:1.8.0_141]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)[:1.8.0_141]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)[:1.8.0_141]
at java.lang.Thread.run(Thread.java:748)[:1.8.0_141]
Dec 06 13:50:51 WARN 187 Error creating EntityManagerFactory
java.lang.RuntimeException: The DataSource osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/ds) required by bundle common-bundle/0.0.1.SNAPSHOT could not be found.
at org.apache.aries.jpa.container.unit.impl.JndiDataSource.getDs(JndiDataSource.java:87)[187:org.apache.aries.jpa.container:1.0.4]
at org.apache.aries.jpa.container.unit.impl.DelayedLookupDataSource.getConnection(DelayedLookupDataSource.java:36)[187:org.apache.aries.jpa.container:1.0.4]
at org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider.getConnection(InjectedDataSourceConnectionProvider.java:70)[213:org.hibernate.entitymanager:4.2.21.Final]
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcServicesImpl.java:242)[212:org.hibernate.core:4.2.21.Final]
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:117)[212:org.hibernate.core:4.2.21.Final]
at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:85)[212:org.hibernate.core:4.2.21.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:184)[212:org.hibernate.core:4.2.21.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:156)[212:org.hibernate.core:4.2.21.Final]
at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1827)[212:org.hibernate.core:4.2.21.Final]
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1785)[212:org.hibernate.core:4.2.21.Final]
at org.hibernate.ejb.EntityManagerFactoryImpl.(EntityManagerFactoryImpl.java:96)[213:org.hibernate.entitymanager:4.2.21.Final]
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:915)[213:org.hibernate.entitymanager:4.2.21.Final]
at org.hibernate.osgi.OsgiPersistenceProvider.createContainerEntityManagerFactory(OsgiPersistenceProvider.java:99)[214:org.hibernate.osgi:4.2.21.Final]
at org.apache.aries.jpa.container.impl.EntityManagerFactoryManager.createEntityManagerFactories(EntityManagerFactoryManager.java:432)[187:org.apache.aries.jpa.container:1.0.4]
at org.apache.aries.jpa.container.impl.EntityManagerFactoryManager.registerEntityManagerFactories(EntityManagerFactoryManager.java:292)[187:org.apache.aries.jpa.container:1.0.4]
at org.apache.aries.jpa.container.impl.EntityManagerFactoryManager.access$000(EntityManagerFactoryManager.java:74)[187:org.apache.aries.jpa.container:1.0.4]
at org.apache.aries.jpa.container.impl.EntityManagerFactoryManager$1.call(EntityManagerFactoryManager.java:203)[187:org.apache.aries.jpa.container:1.0.4]
at org.apache.aries.jpa.container.impl.EntityManagerFactoryManager$1.call(EntityManagerFactoryManager.java:199)[187:org.apache.aries.jpa.container:1.0.4]
at java.util.concurrent.FutureTask.run(FutureTask.java:266)[:1.8.0_141]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)[:1.8.0_141]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)[:1.8.0_141]
at java.lang.Thread.run(Thread.java:748)[:1.8.0_141]
Caused by: javax.naming.NameNotFoundException: osgi:service/javax.sql.DataSource/"(osgi.jndi.service.name=jdbc/ds)"
at org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:113)[66:org.apache.aries.jndi.url:1.1.0]
at org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:138)[66:org.apache.aries.jndi.url:1.1.0]
at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)[64:org.apache.aries.jndi.core:1.0.2]
at javax.naming.InitialContext.lookup(InitialContext.java:417)[:1.8.0_141]
at org.apache.aries.jpa.container.unit.impl.JndiDataSource.getDs(JndiDataSource.java:66)[187:org.apache.aries.jpa.container:1.0.4]
... 21 more
Dec 06 13:50:51 INFO 141 HHH000204: Processing PersistenceUnitInfo [
name: MyModelClass
...]
Dec 06 13:50:52 INFO 141 HHH000130: Instantiating explicit connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider
Dec 06 13:50:55 INFO 141 HHH000400: Using dialect: org.hibernate.dialect.Oracle10gDialect
Dec 06 13:50:55 INFO 141 HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory
Dec 06 13:50:55 INFO 141 HHH000397: Using ASTQueryTranslatorFactory
Dec 06 13:50:56 WARN 141 HHH000008: JTASessionContext being used with JDBCTransactionFactory; auto-flush will not operate correctly with getCurrentSession()
Following are the most important contents of the bundles:
common-bundle:
Persistence.xml:
<persistence version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="my-persistent-unit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/ds)</non-jta-data-source>
<class>MyModelClass</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
blueprint.xml:
<cm:property-placeholder persistent-id='my-persistent-id'
update-strategy='reload'
placeholder-prefix="${"
placeholder-suffix="}">
<cm:default-properties>
<cm:property name="driver" value="undefined"/>
<cm:property name="url" value="undefined"/>
<cm:property name="username" value="undefined"/>
<cm:property name="password" value="undefined"/>
</cm:default-properties>
</cm:property-placeholder>
<jasypt:property-placeholder encryptor-ref="encryptor"/>
<reference id="encryptor" interface="org.jasypt.encryption.StringEncryptor" availability="mandatory"/>
<bean id='myDs'
class="CustomConnection">
<property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource"/>
<property name="URL" value="${url}"/>
<property name="user" value="${username}"/>
<property name="password" value="${password}"/>
<property name="validateConnectionOnBorrow" value="true"/>
</bean>
<service ref='myDs' interface='javax.sql.DataSource'>
<service-properties>
<entry key='osgi.jndi.service.name' value='jdbc/ds'/>
</service-properties>
</service>
client-bundle:
blueprint.xml
<bean id="myController"
class="MyController">
<argument ref="entityManagerFactory"/>
</bean>
<reference id="entityManagerFactory"
interface="javax.persistence.EntityManagerFactory"
filter="(osgi.unit.name=my-persistent-unit)"
availability="mandatory"/>
Please help.
Apparently every bundle is using a datasource but no one is creating it.
javax.naming.NameNotFoundException: osgi:service/javax.sql.DataSource/"(osgi.jndi.service.name=jdbc/ds)"
You need to create this datasource, for example by dropping a simple XML file into deploy dir:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/yourdb"/>
<property name="username" value="XXX"/>
<property name="password" value="XXX"/>
</bean>
<service interface="javax.sql.DataSource" ref="dataSource">
<service-properties>
<entry key="osgi.jndi.service.name" value="jdbc/ds"/>
</service-properties>
</service>
</blueprint>
You will need jdbc and jndi features installed.
I have connection issues since i decided to use c3p0 pooling.
persistence.xml
<property name="hibernate.connection.url" value="jdbc:mysql://***.***.***.***:****/*****"/>
<property name="hibernate.connection.username" value="****"/>
<property name="hibernate.connection.password" value="****"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.show_sql" value="true" />
<!-- <property name="hibernate.connection.provider_class" value="org.hibernate.c3p0.internal.C3P0ConnectionProvider" /> -->
<!-- <property name="hibernate.c3p0.min_size" value="1"/> -->
<!-- <property name="hibernate.c3p0.max_size" value="50"/> -->
<!-- <property name="hibernate.c3p0.timeout" value="10000"/> -->
<!-- <property name="hibernate.c3p0.max_statements" value="100"/> -->
<!-- <property name="hibernate.c3p0.idle_test_period" value="300"/> -->
With this config everything works fine. When i uncomment the c3p0 properties i cant even connect to my application.
try {
user = UserDAO.connect(login,Tools.encode(password));
}
catch (SQLException e) {
e.printStackTrace();
logger.error(utils.Constants.GENERAL_ERROR);
message=utils.Constants.LOGIN_KO;
}
finally{
//some code
}
I tried to run this code in debug. I have a break point on each block. The program directly go from the try to the finally.
Here are the logs:
2015-08-26 15:27:50 INFO LogHelper:46 - HHH000204: Processing PersistenceUnitInfo [
name: ****
...]
2015-08-26 15:27:53 INFO Version:54 - HHH000412: Hibernate Core {4.3.6.Final}
2015-08-26 15:27:53 INFO Environment:239 - HHH000206: hibernate.properties not found
2015-08-26 15:27:53 INFO Environment:346 - HHH000021: Bytecode provider name : javassist
2015-08-26 15:27:56 INFO Version:66 - HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
2015-08-26 15:27:56 INFO ConnectionProviderInitiator:190 - HHH000130: Instantiating explicit connection provider: org.hibernate.c3p0.internal.C3P0ConnectionProvider
2015-08-26 15:27:56 INFO C3P0ConnectionProvider:117 - HHH010002: C3P0 using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://***.***.***.***:****/*****
2015-08-26 15:27:56 INFO C3P0ConnectionProvider:118 - HHH000046: Connection properties: {user=****, password=****}
2015-08-26 15:27:56 INFO C3P0ConnectionProvider:121 - HHH000006: Autocommit mode: false
I see there is this line in the logs
Environment:239 - HHH000206: hibernate.properties not found
But i dont understand where it comes from and if it is the reason of the issue.
I already looked at
how to fix the error: "INFO: HHH000206: hibernate.properties not found"?
and similar posts
#Maciej Dobrowolski
I dont use Maven so i dont have pom.xml (i wont explain why here it is not related)
Here are the jars i have in the classpath:
/WebContent/WEB-INF/lib/hibernate-c3p0-5.0.0.Final.jar
/WebContent/WEB-INF/lib/hibernate-commons-annotations-4.0.5.Final.jar
/WebContent/WEB-INF/lib/hibernate-core-4.3.6.Final.jar
/WebContent/WEB-INF/lib/hibernate-entitymanager-4.3.6.Final.jar
/WebContent/WEB-INF/lib/hibernate-jpa-2.1-api-1.0.0.Final.jar
/WebContent/WEB-INF/lib/c3p0-0.9.5.1.jar
It could be silly but i think you need to add:
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
to your configuration, i hope this works for you,
Couldn't find what is wrong with inserting data in mySQL database using Spring data, JPA, hibernate and mySQL. It is inserting data twice in database.
The root-context.xml file is:
<?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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<context:component-scan base-package="com.project.db">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<jdbc:embedded-database type="HSQL" id="dataSource"/>
<!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/jpa"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</bean> -->
<!-- <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="database" value="MYSQL"/>
</bean> -->
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="packagesToScan" value="com.project.db.entity"></property>
<property name="dataSource" ref="dataSource"></property>
<!-- <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/> -->
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider"/>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<jpa:repositories base-package="com.project.db.repository"/>
</beans>
The servlet-context.xml file is:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.project.db" />
</beans:beans>
My #Entity class is:
#Entity
public class User {
#Id
#GeneratedValue
private Integer id ;
private String name ;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
JPA repository is:
import org.springframework.data.jpa.repository.JpaRepository;
import com.project.entity.User;
public interface UserRepository extends JpaRepository<User, Integer> {
}
And, finally, #Service class is:
import javax.annotation.PostConstruct;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.project.entity.User;
import com.project.repository.UserRepository;
#Transactional
#Service
public class InitDbService {
#Autowired
private UserRepository userRepository;
#PostConstruct
public void init() {
User user = new User();
user.setName("Ali");
userRepository.save(user);
}
}
The above code works without errors/exceptions; database/table is also created but data is inserted into Entity/table twice when I see that in mySQL database.
Project is at github.
Console output is:
INFO: Spring WebApplicationInitializers detected on classpath: [com.project.db.WebAppInitializer#1867584]
Sep 2, 2015 12:50:17 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization started
INFO : org.springframework.web.context.support.XmlWebApplicationContext - Refreshing Root WebApplicationContext: startup date [Wed Sep 02 12:50:17 PKT 2015]; root of context hierarchy
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/root-context.xml]
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
Hibernate: drop table if exists users
Hibernate: create table users (id integer not null auto_increment, name varchar(255), primary key (id))
Hibernate: insert into users (name) values (?) // first time inserting here and
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 5633 ms
Sep 2, 2015 12:50:23 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring FrameworkServlet 'springDispatcher'
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'springDispatcher': initialization started
INFO : org.springframework.web.context.support.XmlWebApplicationContext - Refreshing WebApplicationContext for namespace 'springDispatcher-servlet': startup date [Wed Sep 02 12:50:23 PKT 2015]; parent: Root WebApplicationContext
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/appServlet/servlet-context.xml]
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.project.db.HomeController.home(java.util.Locale,org.springframework.ui.Model)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - Looking for #ControllerAdvice: WebApplicationContext for namespace 'springDispatcher-servlet': startup date [Wed Sep 02 12:50:23 PKT 2015]; parent: Root WebApplicationContext
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - Looking for #ControllerAdvice: WebApplicationContext for namespace 'springDispatcher-servlet': startup date [Wed Sep 02 12:50:23 PKT 2015]; parent: Root WebApplicationContext
INFO : org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/resources/**] onto handler 'org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0'
Hibernate: insert into users (name) values (?) // Second time inserting here
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'springDispatcher': initialization completed in 1483 ms
Sep 2, 2015 12:50:25 PM org.apache.catalina.core.StandardContext reload
INFO: Reloading Context with name [/db] is completed
Taking a chance here since I see that you are using Spring MVC.
With Spring MVC, you have a servlet-context which defines the controllers, and an applicationContext for other beans. It might be that you are scanning for beans other than controllers in the servlet-context, which in turn will give you two beans of InitDbService, both running their #PostConstruct-method, inserting into the database.
This can be solved by defining component-scan like this:
servlet-context (after placing controllers and controllers only in a separate package):
<context:component-scan base-package="com.my.project.controller" />
applicationContext:
<context:component-scan base-package="com.my.project">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
You have to enable DEBUG logging to check that your initailizing bean isn't created twice, as Tobb mentioned before your bean is probabbly created in both contexts. Log stands clearly that first insert is executed during root context initialization (witch is correct) and second time during servlet context initialization (which is wrong)
I have found solution to your problem: You have to add commponent scan without default filters to your root-context
<context:component-scan base-package="com.project.db" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
and servlet-context is
<context:component-scan base-package="com.project.db" />
I have tested your project and its working fine with this change.
I'm trying to persist an entity using. My test case works (data are persisted in db) when I handle my transaction myself.
public User saveUser(User user) {
getEm().getTransaction().begin();
getEm().persist(user);
getEm().getTransaction().commit();
return user;
}
(entity manager comes from a template class which my DAO class extends)
It stops persisiting data when I configure spring to handle transactions.
test-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="domainPU" />
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://192.168.5.111/testdb" />
<property name="username" value="sdgdsgs" />
<property name="password" value="sdfgdsg" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory">
<ref local="entityManagerFactory" />
</property>
</bean>
</beans>
UsersRepositoryTest:
#ContextConfiguration(locations = { "classpath:test-context.xml", "classpath:module-context.xml" })
#TransactionConfiguration(defaultRollback=false)
public class UsersRepositoryTest extends AbstractTransactionalTestNGSpringContextTests {
#Autowired
private UsersRepository usersRepository;
#Test(dependsOnMethods = {"findUserByLogin"})
public void registerUser() throws DataAccessException {
User myUser = getUserHomer();
usersRepository.saveUser(myUser);
User returnedUser = usersRepository.getUserByLogin(myUser.getLogin());
assertNotNull(returnedUser);
...
}
}
stacktrace:
2012-10-22 08:26:26 org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean createNativeEntityManagerFactory
INFO: Building JPA container EntityManagerFactory for persistence unit 'domainPU'
2012-10-22 08:26:26 org.hibernate.annotations.common.Version <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.1.Final}
2012-10-22 08:26:26 org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.1.6.Final}
2012-10-22 08:26:26 org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
2012-10-22 08:26:26 org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
2012-10-22 08:26:26 org.hibernate.ejb.Ejb3Configuration configure
INFO: HHH000204: Processing PersistenceUnitInfo [
name: domainPU
...]
2012-10-22 08:26:26 org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator instantiateExplicitConnectionProvider
INFO: HHH000130: Instantiating explicit connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider
2012-10-22 08:26:27 org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
2012-10-22 08:26:27 org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
2012-10-22 08:26:27 org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory
2012-10-22 08:26:27 org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
2012-10-22 08:26:27 org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
INFO: Bean 'entityManagerFactory' of type [class org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2012-10-22 08:26:27 org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
INFO: Bean 'hibernateTranslator' of type [class org.springframework.orm.hibernate4.HibernateExceptionTranslator] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2012-10-22 08:26:27 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#5c28305d: defining beans [org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,entityManagerFactory,dataSource,transactionManager,org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0,hibernateTranslator,usersDao,zoneDao,usersRepository,zoneRepository,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy
2012-10-22 08:26:27 org.springframework.test.context.transaction.TransactionalTestExecutionListener startNewTransaction
INFO: Began transaction (1): transaction manager [org.springframework.orm.jpa.JpaTransactionManager#3341b736]; rollback [false]
Hibernate: select user0_.id as id0_, user0_.active as active0_, user0_.creation_date as creation3_0_, user0_.email as email0_, user0_.last_login_date as last5_0_, user0_.login as login0_, user0_.password as password0_, user0_1_.AVATAR as AVATAR1_, user0_1_.FIRST_NAME as FIRST2_1_, user0_1_.ID as ID1_, user0_1_.LAST_NAME as LAST4_1_, case when user0_1_.id is not null then 1 when user0_.id is not null then 0 end as clazz_ from user user0_ left outer join client user0_1_ on user0_.id=user0_1_.id where user0_.login=?
Hibernate: select phone0_.id as id2_0_, phone0_.phone_number as phone2_2_0_, phone0_.user_id as user3_2_0_ from phone phone0_ where phone0_.id=?
Hibernate: select address0_.ID as ID6_0_, address0_.apartment_number as apartment2_6_0_, address0_.city as city6_0_, address0_.country as country6_0_, address0_.house_number as house5_6_0_, address0_.post_code as post6_6_0_, address0_.street as street6_0_ from address address0_ where address0_.ID=?
Hibernate: select user0_.id as id0_, user0_.active as active0_, user0_.creation_date as creation3_0_, user0_.email as email0_, user0_.last_login_date as last5_0_, user0_.login as login0_, user0_.password as password0_, user0_1_.AVATAR as AVATAR1_, user0_1_.FIRST_NAME as FIRST2_1_, user0_1_.ID as ID1_, user0_1_.LAST_NAME as LAST4_1_, case when user0_1_.id is not null then 1 when user0_.id is not null then 0 end as clazz_ from user user0_ left outer join client user0_1_ on user0_.id=user0_1_.id where user0_.login=?
2012-10-22 08:26:27 org.springframework.test.context.transaction.TransactionalTestExecutionListener endTransaction
INFO: Committed transaction after test execution for test context [[TestContext#63edf84f testClass = UsersRepositoryTest, testInstance = pl.eports.zonen.user.repository.UsersRepositoryTest#7e3bc473, testMethod = findUserByLogin#UsersRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration#1c493dca testClass = UsersRepositoryTest, locations = '{classpath:test-context.xml, classpath:module-context.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader']]]
2012-10-22 08:26:27 org.springframework.test.context.transaction.TransactionalTestExecutionListener startNewTransaction
INFO: Began transaction (2): transaction manager [org.springframework.orm.jpa.JpaTransactionManager#3341b736]; rollback [false]
Hibernate: select user0_.id as id0_, user0_.active as active0_, user0_.creation_date as creation3_0_, user0_.email as email0_, user0_.last_login_date as last5_0_, user0_.login as login0_, user0_.password as password0_, user0_1_.AVATAR as AVATAR1_, user0_1_.FIRST_NAME as FIRST2_1_, user0_1_.ID as ID1_, user0_1_.LAST_NAME as LAST4_1_, case when user0_1_.id is not null then 1 when user0_.id is not null then 0 end as clazz_ from user user0_ left outer join client user0_1_ on user0_.id=user0_1_.id where user0_.login=?
2012-10-22 08:26:27 org.springframework.test.context.transaction.TransactionalTestExecutionListener endTransaction
INFO: Committed transaction after test execution for test context [[TestContext#63edf84f testClass = UsersRepositoryTest, testInstance = pl.eports.zonen.user.repository.UsersRepositoryTest#7e3bc473, testMethod = registerUser#UsersRepositoryTest, testException = java.lang.AssertionError: expected object to not be null, mergedContextConfiguration = [MergedContextConfiguration#1c493dca testClass = UsersRepositoryTest, locations = '{classpath:test-context.xml, classpath:module-context.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader']]]
PASSED: findUserByLogin
FAILED: registerUser
java.lang.AssertionError: expected object to not be null
at org.testng.Assert.fail(Assert.java:94)
...
As you can see from the stacktrace, transaction seems to be started and finished, but no sql inserts are produced and no data are inserted into db (data rollback is set to false)
I've tried force flushing data after persist() but spring managed transaction seems to be finished by then.
I've looked for a similar issue on forums but none works.
I can provide some more code if necessary.
I'm using Spring 3.1.2 and Hibernate 4.1.6.Final
update:
DAO: (#Transactional annotation is put here instead on service layer temporarily)
#Repository
public class JpaUsersDAO extends JpaDAOTemplate<User> implements UsersDAO {
public JpaUsersDAO(EntityManagerFactory factory) {
super(factory.createEntityManager(), User.class);
}
#Transactional
public User saveUser(User user) {
getEm().persist(user);
return user;
}
}
DAOTemplate:
public abstract class JpaDAOTemplate<T extends Serializable> {
private EntityManager em;
private Class<T> clazz;
public JpaDAOTemplate(EntityManager em, final Class<T> clazz) {
this.em = em;
this.clazz = clazz;
}
public EntityManager getEm() {
return em;
}
public T getById(Integer id) {...}
...
}
bean definition:
<bean id="usersDao"
class="pl.package.user.dao.impl.JpaUsersDAO">
<constructor-arg ref="entityManagerFactory" />
</bean>
It seems that the transaction is lost somewhere after selects and before calling getEm().persist() - org.hibernate.ejb.TransactionImpl#tx is null when calling persist() but it was org.hibernate.engine.transaction.internal.jdbc.JDBCTransaction before the call (when sql select statements calls were made)
update 2
debug level stacktrace:
[2012-10-23 11:15:14,546]DEBUG 38629[main] - org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:365) - Creating new transaction with name [registerUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
[2012-10-23 11:15:33,252]DEBUG 57335[main] - org.hibernate.internal.SessionImpl.<init>(SessionImpl.java:316) - Opened session at timestamp: 13509837332
[2012-10-23 11:15:33,252]DEBUG 57335[main] - org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:368) - Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl#18025c5c] for JPA transaction
[2012-10-23 11:15:40,085]DEBUG 64168[main] - org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:158) - begin
[2012-10-23 11:15:40,101]DEBUG 64184[main] - org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:295) - Obtaining JDBC connection
[2012-10-23 11:15:40,101]DEBUG 64184[main] - org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:301) - Obtained JDBC connection
[2012-10-23 11:15:40,101]DEBUG 64184[main] - org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:69) - initial autocommit status: true
[2012-10-23 11:15:40,101]DEBUG 64184[main] - org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:71) - disabling autocommit
[2012-10-23 11:16:06,934]DEBUG 91017[main] - org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:407) - Not exposing JPA transaction [org.hibernate.ejb.EntityManagerImpl#18025c5c] as JDBC transaction because JpaDialect [org.springframework.orm.jpa.DefaultJpaDialect#5f343722] does not support JDBC Connection retrieval
[2012-10-23 11:16:06,934]DEBUG 91017[main] - org.springframework.test.context.transaction.TransactionalTestExecutionListener.isRollback(TransactionalTestExecutionListener.java:357) - No method-level #Rollback override: using default rollback [false] for test context [[TestContext#5809fdee testClass = UsersRepositoryTest, testInstance = pl.eports.zonen.user.repository.UsersRepositoryTest#3fde891b, testMethod = registerUser#UsersRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration#77fe4169 testClass = UsersRepositoryTest, locations = '{classpath:test-context.xml, classpath:module-context.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader']]]
[2012-10-23 11:16:06,934] INFO 91017[main] - org.springframework.test.context.transaction.TransactionalTestExecutionListener.startNewTransaction(TransactionalTestExecutionListener.java:275) - Began transaction (1): transaction manager [org.springframework.orm.jpa.JpaTransactionManager#37977909]; rollback [false]
[2012-10-23 11:17:08,103]DEBUG152186[main] - org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:245) - Returning cached instance of singleton bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0'
[2012-10-23 11:17:08,118]DEBUG152201[main] - org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource.getTransactionAttribute(AbstractFallbackTransactionAttributeSource.java:106) - Adding transactional method 'saveUser' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
[2012-10-23 11:17:08,118]DEBUG152201[main] - org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:245) - Returning cached instance of singleton bean 'txManager'
[2012-10-23 11:17:27,073]DEBUG171156[main] - org.springframework.orm.jpa.JpaTransactionManager.doGetTransaction(JpaTransactionManager.java:331) - Found thread-bound EntityManager [org.hibernate.ejb.EntityManagerImpl#18025c5c] for JPA transaction
[2012-10-23 11:18:04,031]DEBUG208114[main] - org.springframework.transaction.support.AbstractPlatformTransactionManager.handleExistingTransaction(AbstractPlatformTransactionManager.java:470) - Participating in existing transaction
Final update:
Problem was in the way I injected EntityManagerFactory to my DAO. I used applicationContext.xml configuration file to inject it (this way EMF does not participate in transaction). To have it working I changed my DAO class to:
#Repository
public class JpaUsersDAO extends JpaDAOTemplate<User> implements UsersDAO {
#PersistenceContext
private EntityManager em;
...
}
You are using Spring 3.0.
I am not clear your coding public User saveUser(User user) method. Even If you use Spring 3.0, you handel the transaction your self(Bean Management Transaction).
It just need to use #Transactional(propagation = Propagation.REQUIRED) annotation. Change propagation type based on your process.
Example DAO :
GroupDAO.java
#Repository("GroupDAO")
public class GroupDAO {
#PersistenceContext
protected EntityManager em;
#Transactional(propagation = Propagation.REQUIRED)
public void insert(Group group) {
try {
em.persist(group);
em.flush();
} catch (PersistenceException pe) {
}
}
}
spring-bean.xml with EclipseLink JPA <-- just for reference.
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:faces="http://www.springframework.org/schema/faces"
xmlns:int-security="http://www.springframework.org/schema/integration/security"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:sec="http://www.springframework.org/schema/security"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/integration/security http://www.springframework.org/schema/integration/security/spring-integration-security-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/faces http://www.springframework.org/schema/faces/spring-faces-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<context:annotation-config/>
<context:component-scan base-package="your-package"/>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.5.111/testdb"/>
<property name="username" value="your-username"/>
<property name="password" value="your-password"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- <property name="dataSource" ref="dataSource"/>-->
<property name="persistenceUnitName" value="domainPU"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect"/>
</property>
<property name="jpaPropertyMap">
<props>
<prop key="eclipselink.weaving">false</prop>
</props>
</property>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver">
</bean>
</property>
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="databasePlatform" value="org.eclipse.persistence.platform.database.MySQLPlatform"/>
<!-- <property name="databasePlatform" value="org.eclipse.persistence.platform.database.OraclePlatform" />-->
<property name="generateDdl" value="false"/>
<property name="showSql" value="true"/>
</bean>
</beans>