#Transactional in Spring+Hibernate - spring

I an using Spring 3.1 + Hibernate 4.x in my web application.
In my DAO, i am saving User type object as following
sessionFactory.getCurrentSession().save(user);
But getting following exception:
org.hibernate.HibernateException: save is not valid without active transaction
I googled and found similar question on SO, with following solution:
Session session=getSessionFactory().getCurrentSession();
Transaction trans=session.beginTransaction();
session.save(entity);
trans.commit();
That solves the problem. But in that solution, there is lot of mess of beginning and committing the transactions manually.
Can't i use sessionFactory.getCurrentSession().save(user); directly without begin/commit of transactions manually?
I try to use #Transactional on my service/dao methods too, but the problem persists.
EDIT : Here is my Spring Config File:
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
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.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${db.driverClassName}" p:url="${db.url}"
p:username="${db.username}" p:password="${db.password}" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.myapp.entities" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
</beans>
I am using following Hibernate 4 dependencies:
<!-- Hibernate Dependency -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.1.7.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.1.1.Final</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>${cglib.version}</version>
<scope>runtime</scope>
</dependency>
Please help.

Basically what needs to be done is to remove from the applicationContext.xml file the following line for Hibernate properties:
<prop key="hibernate.current_session_context_class">thread</prop>
Once that is remove, Hibernate makes use of Spring for transaction management
Good luck to you all.

i think you are using Hibernate 4.x then why you are using hibernate 3 transaction manager in application context file?
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
i think it should be
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
just try to use hibernate 4 transaction manager along with #Transactional attribute it should work.

Using your working version of the Spring XML, and the #Transactional annotated DAO class, are you defining the DAO in your Spring XML ? (Perhaps as a prototype) Because if you're not, then so far as I can see, your DAO is not going to be AOP'ed for transactional aspects. I think that's the easiest way. This example is from the Spring 3 Doc, section 10.5.6 Using #Transactional.
<!-- this is the service object that we want to make transactional -->
<bean id="fooService" class="x.y.service.DefaultFooService"/>
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="txManager"/>
...where you might substitute DefaultFooService for your DAO.

Related

Spring MessageListener not invoked in Tomcat Server when trying to read a Foriegn Weblogic JMS Topic

I have deployed an application in Tomcat7 to read messages from Foreign JMS Topic in Weblogic 11g. This is my spring application context xml. I have included wlthint3client.jar in my classpath.
<?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:context="http://www.springframework.org/schema/context"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Uncomment and add your base-package here: <context:component-scan base-package="org.springframework.samples.service"/> -->
<tx:jta-transaction-manager/>
<bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager" p:connectionFactory-ref="clarifyconnectionFactory"/>
<bean id="clarifyTopic" class="org.springframework.jndi.JndiObjectFactoryBean"
p:jndiName="jms/ATomcatClarifyTopic"
p:proxyInterface="javax.jms.Destination"
p:jndiTemplate-ref="jndiTemplate"/>
<bean id="messageAdapter" class="org.springframework.jms.listener.adapter.MessageListenerAdapter" p:defaultListenerMethod="receive">
<constructor-arg>
<bean class="com.jnpr.clarify.jms.DefaultTextMessageDelegate"/>
</constructor-arg>
</bean>
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
<prop key="java.naming.provider.url">t3://weblogichost:8001</prop>
</props>
</property>
</bean>
<!-- Lookup JMS Connection Factory -->
<bean id="clarifyconnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"
p:jndiName="jms/TestTopicConnectionFactory" p:proxyInterface="javax.jms.TopicConnectionFactory"
p:jndiTemplate-ref="jndiTemplate"
p:exposeAccessContext="true"/>
<!-- Configuring JMS Template -->
<bean id='jmsTemplate' class="org.springframework.jms.core.JmsTemplate"
c:_0-ref="clarifyconnectionFactory" />
<!-- Configuring Topic Listener -->
<bean id="topicListener" class="com.jnpr.clarify.jms.TopicListener" />
<!-- Configuring MessageListenerContainer -->
<bean id="JMSMessageListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer"
p:destination-ref="clarifyTopic" p:connectionFactory-ref="clarifyconnectionFactory"
p:messageListener-ref="messageAdapter" p:transactionManager-ref="jmsTransactionManager"
p:durableSubscriptionName="TomcatClarify"/>
</beans>
In this i have used MessageListenerAdapter as JMS Listener. I have
also tried witha a bean implementing javax.jms.MessageListener. But
still getting same exception.
I am not using any transaction management in my code but still configured Transaction manager to check if that fixes the issue.
Am getting below exception in tomcat server log.
WARNING: Setup of JMS message listener invoker failed for destination 'JUN_JMS_SOA_Module!ATomcatClarifyTopic' - trying to recover. Cause: [JMSClientExceptions:055142]Foreign destination, JMS_SOA_Module!TomcatClarifyTopic
Jan 01, 2015 7:09:13 PM org.springframework.jms.listener.DefaultMessageListenerContainer refreshConnectionUntilSuccessful
INFO: Successfully refreshed JMS Connection
Please help if am doing anything wrong.
The above code working when message listener container configured using jms namespace as below instead of regular spring bean.
<jms:listener-container container-type="default" acknowledge="auto"
connection-factory="clarifyconnectionFactory" destination-type="durableTopic"
destination-resolver="jmsDestinationResolver">
<jms:listener destination="jms/ATomcatClarifyTopic" ref="topicListener"/>
</jms:listener-container>
<bean id="jmsDestinationResolver"
class="org.springframework.jms.support.destination.JndiDestinationResolver">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="cache">
<value>true</value>
</property>
</bean>

Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: sessionFactory

I am getting following error
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'roleDAOImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory com.quad.dao.RoleDAOImpl.sessionFactory; nested exception is java.lang.NoClassDefFoundError: Lorg/hibernate/cache/CacheProvider;
My sessionFactory configuration in mvc-dispatcher-servlet.xml is
<bean id="sessionFactory class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"><property name="dataSource" ref="dataSource" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> </props> </property> </bean>
i am using sessionFactory in RoleDAOImpl
my full mvc-dispatcher-servlet.xml is
<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"
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">
<context:component-scan base-package="com.quad.controller" />
<context:component-scan base-package="com.quad.dao" />
<context:component-scan base-package="com.quad.entity" />
<context:component-scan base-package="com.quad.service" />
<context:property-placeholder location="classpath:database.properties" />
<!-- <context:property-placeholder location="classpath:spring-security.xml" /> -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
</bean>
please help .
This is definitely a problem with mismatched dependency versions.
org.hibernate.cache.CacheProvider was removed in Hibernate 4 (a different caching standard was created)
Your session factory class specified is:
org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
which is specific to Hibernate 3.
This implies you're using hibernate 4 related dependencies with the wrong session factory class.
As long as you're using Spring 3.1.0.RELEASE or higher, the hibernate 4 classes are available in spring-orm (as are the hibernate3 versions).
You have two options then:
Change back to Hibernate 3
This depends on how your project is built. If it's using Maven, this would involve changing the hibernate-core dependencies
Change your spring configuration to Hibernate 4
This will only work for Spring 3.1.0.RELEASE or higherFor this change the above mentioned AnnotationSessionFactoryBean to:org.springframework.orm.hibernate4.LocalSessionFactoryBean
Whenever you are injecting sessionFactory you must provide its setter and getter methods. it will resolve your problem

Spring 3.2 + Hibernate 4.2 : "The application must supply JDBC connections" - What is wrong with my configuration?

I'm struggling to understand how to properly configure Spring 3.2 and Hibernate 4.2. After working through several issues over the last few days, I ran into this exception while trying to execute a query in my DAO:
java.lang.UnsupportedOperationException: The application must supply JDBC connections
org.hibernate.service.jdbc.connections.internal.UserSuppliedConnectionProviderImpl.getConnection(UserSuppliedConnectionProviderImpl.java:62)
org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:292)
org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:214)
org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:157)
org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:67)
org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:160)
org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1426)
org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:59)
com.bsj.demo.rest.dao.DemoUserDaoImpl.getAllDemoUsers(DemoUserDaoImpl.java:41)
Here are my Spring and Hibernate files:
context.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:property-placeholder location="classpath:spring/data-access.properties"/>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/restdemo"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="persistenceUnitManager">
<bean class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="defaultDataSource" ref="dataSource" />
</bean>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
<context:component-scan base-package="com.bsj.demo.rest.*">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
</context:component-scan>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<context:spring-configured />
<context:annotation-config />
<bean class="com.bsj.demo.rest.spring.config.AppConfig"/>
</beans>
persistence.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="RESTDemoJPA" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
</properties>
</persistence-unit>
What am I missing? My understanding is that with Spring defining the datasource and persistence unit, there should be very little configuration needed in the persistence.xml. Am I completely wrong here?
Server is Tomcat 7, dependencies managed by Maven. I understand this is a commonly asked question on SO, but after trying several solutions I have not found a way to resolve this problem.
Have a look over here. Might be it can resolve your issue.
https://github.com/abdulwaheed18/Spring-HIbernate-Integration/blob/master/src/beans.xml
Alright, I figured out the problem and it wasn't really related to configuration. The problem was how I was instantiating the EntityManager in my code.
In the configuration, I needed to add the following to the entityManager bean definition:
<property name="persistenceUnitName" value="RESTDemoJPA" />
The bigger problem was that I was creating the EntityManager in each DAO by getting an instance from the EntityManagerFactory. Instead, I should have been allowing Spring to inject it via the PersistenceContext annotation as follows:
#PersistenceContext(unitName="RESTDemoJPA")
private EntityManager em;
After doing that, I removed all calls to em.getTransaction(), annotated the class as #Transactional and the exceptions went away. After that, I could query the database.
TL;DR: Configuration was correct minus defining the Persistence Unit name in the entityManager definition. Changed EntityManager instantiation from manual to Spring injection.

Change hibernate.connection.url from within Spring

I am using Hibernate in combination with Spring. As database I am currently using HSQL, which stores its data in a file (like SQLite). The path to the HSQL file is currently hard-coded in the persistence.xml. How can I access and change this value at runtime, so a user can load and save from/to an arbitrary HSQL file?
persistence.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_1_0.xsd"
version="1.0">
<persistence-unit name="something-unit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
<property name="hibernate.connection.url" value="jdbc:hsqldb:file:~/something-db/somethingdb" />
<property name="hibernate.connection.username" value="sa" />
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
Spring 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:context="http://www.springframework.org/schema/context"
xmlns:data="http://www.springframework.org/schema/data/jpa"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
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-2.5.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- Database Setup -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="something-unit" />
</bean>
<data:repositories base-package="com.something.playlist"/>
<!-- Transaction Setup -->
<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
</beans>
Thanks for any hint!
You can specify a JNDI datasource and pass it to Hibernate. Or you can define your own plugin strategy for obtaining JDBC connections by implementing the interface org.hibernate.connection.ConnectionProvider
For more hints see: http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html
Edit 2/16: There is an example on StackOverflow on creating a custom ConnectionProvider: How can I set Datasource when I'm creating Hibernate SessionFactory?
If you are going to change the data source on the fly, rather than at the startup, you will have to restart the Hibernate session factory. To do it correctly, you will have to make sure that no transactions are running in it at the time of the restart. Following question/answers would help you with that: Hibernate Sessionfactory restart | Spring
A commonly used strategy is to define all runtime configurations in one or several *.properties files and use spring's PropertyPlaceholderConfigurer to load the values and substitute the placeholder in applicationContext.xml, read more here: Best ways to deal with properties values in XML file in Spring, Maven and Eclipses.
app.properties:
# Dadabase connection settings:
hibernate.connection.driver_class=org.hsqldb.jdbcDriver
hibernate.connection.url=jdbc:hsqldb:file:~/something-db/somethingdb
hibernate.connection.username=sa
hibernate.connection.password=changeit
hibernate.dialect=org.hibernate.dialect.HSQLDialect
hbm2ddl.auto=update
... ...
applicationContext-dataStore.xml:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- Default location inside war file -->
<value>classpath:app.properties</value>
<!-- Environment specific location, a fixed path on deployment server -->
<value>file:///opt/my-app/conf/app.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true"/>
</bean>
... ...
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${hibernate.connection.driver_class}" />
<property name="url" value="${hibernate.connection.url}" />
<property name="username" value="${hibernate.connection.username}" />
<property name="password" value="${hibernate.connection.password}" />
</bean>
One problem here is the PropertyPlaceholderConfigurer doesn't parse persistence.xml, the solution is to move all hibernate configuration into Spring's applicationContext.xml, as it is not necessary to set them in persistence.xml. read more here: loading .properties in spring-context.xml and persistence.xml.
persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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="JPAService" transaction-type="RESOURCE_LOCAL"/>
</persistence>
applicationContext-datSource.xml:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${hibernate.connection.driver_class}"/>
<property name="url" value="${hibernate.connection.url}"/>
<property name="username" value="${hibernate.connection.username}"/>
<property name="password" value="${hibernate.connection.password}"/>
</bean>
... ...
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:./META-INF/persistence.xml"/>
<property name="persistenceUnitName" value="JPAService"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${hibernate.dialect}"/>
<property name="showSql" value="true" />
<property name="generateDdl" value="true"/>
</bean>
</property>
<property name="jpaProperties">
<!-- set extra properties here, e.g. for Hibernate: -->
<props>
<prop key="hibernate.hbm2ddl.auto">${hbm2ddl.auto}</prop>
</props>
</property>
</bean>
Note that the web application need to be restarted every time you alter the configuration in /opt/my-app/conf/app.properties, in order to make changes take effect.
Hope this helps.
If you wish to use hibernate via the JPA Abstraction you can we-write your code or service to use an javax.persistence.EntityManagerFactory. Autowire one of these and call createEntityManager(Map map); You can provide a datasource in the map. You could wrap the entity manager with your own implementation that pulls the parameter off a thread-local for creating the datasource.
EDIT: Mis-read the context and saw you are using an EntityManagerFactory. In which case just read the last part where you wrap the Factory with a delegate that creates the correct datasource from a threadlocal.

Spring + Spring Data JPA Configuration

currently I'm fooling around with a Spring setup. My goal is to use JPA to get access to a Websphere datasource using it's JNDI name. I'm using Spring Data JPA to make life easier for me and worked through some tutorials to get the basic idea.
Bad thing: none of those is talking about the Spring configuration for my JPA szenario + I never worked with JPA / JDBC before.
So I hope you can help me out here. I got 2 configuration files:
applicationContext.xml
<bean id="txManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<bean id="eManager" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"></bean>
Since i'm using the #Transactual annotion within my code, i'm using the annotation-driven tag for the txManager. I'm just not really sure what else i should configure for the txManager and what the sessionFactory tag is doing. Is there any documentation for all supported XML tags? Am I missing a importent tag for my szenario?
Same about eManager - not sure if thats right in any way.
persistence.xml
<persistence version="1.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_1_0.xsd">
<persistence-unit name="spring-jpa">
<jta-data-source>jdbc/myJNDI</jta-data-source>
</persistence-unit>
</persistence>
Same thing here: don't really know what i'm doing. I know i need a persistence unit / provider. I know that many are using hibernate for this, but i would like to stay native and use pure JavaEE / Spring if possible.
I'm just not sure how to configure that.
Currently my project is crashing, telling me: "JPA PersistenceProvider returned null"
The best way is to obtain the EntityManagerFactory from the JNDI via Spring's JNDI support:
<jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/myPersistenceUnit" />
<jpa:repositories base-package="com.acme.repositories" />
<tx:jta-transactionManager />
This will cause the transaction manager being used from the application server as well. You can also try to setup a JpaTransactionManager and wire the EntityManagerFactory obtained from JNDI into it. You can pull even more configuration into your Spring config files if you only lookup the datasource through an <jee:jndi-lookup /> namespace element and follow the further configuration instructions in the Spring Data JPA reference documentation. Nevertheless it's usually better to use the container resources you can actually get if you decide to use container resources at all.
I just started working with Spring, jpa mysql etc... and I might be able to help you out.
I'll show you the way that I have my configuration right know.
I'm using hibernate by the way for my database connection, I've never did it without so no help from me there :)
My configuration:
Spring-config.xml:
<context:component-scan base-package="com.MYPACKAGE"/>
<!-- To find all your controllers -->
<tx:annotation-driven/>
<!-- This will pickup all your #Transactional annotations-->
<import resource="../database/DataSource.xml"/>
<import resource="../database/Hibernate.xml"/>
<!-- These are my database config files-->
Datasource.xml:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/DATABASENAME"/>
<property name="username" value="USERNAME"/>
<property name="password" value="PASSWORD"/>
</bean>
Hibernate.xml:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false"/>
<property name="generateDdl" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
</bean>
</property>
</bean>
I left out the standard xml text that you need to include at the top of your .xml files, but I trust you to work that out yourself ;)
This setup works for me and I hope it can help you out!
If you have any question regarding this post please let me know!
Good luck!
for those using JBoss, the jndi names can be set in persistence.xml properties like this:
<persistence-unit name="punit" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/myDS/jta-data-source>
<class>com.company.model.Document</class>
<class>com.company.model.DocumentIndividual</class>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create" />
<!-- <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/> -->
<property name="javax.persistence.logging.level" value="INFO" />
<property name="hibernate.show_sql" value="true" />
<property name="jboss.entity.manager.jndi.name" value="java:/my_em"/>
<property name="jboss.entity.manager.factory.jndi.name" value="java:/my_emf"/>
</properties>
</persistence-unit>
as described in here section 4.4.2

Resources