persistence.xml in a Spring application - spring

I'm used to have persistence.xml in my projects in which I define the provider to use (hibernate in most cases).
However, I'm starting a new project in which it is mandatory to use Spring framework. I've seen some blogs describing the integration of Hibernate in Spring and I've understood that I should declare a session factory in spring's beans descriptor org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
All the examples I've seen don't mention the use of persistence.xml, persistence context, entity manager...
I'm not sure I understand this point, I always thought that Hibernate is just a provider of JPA unless the factory declared in application-context.xml is doing something in background. If it is the case, I would like to understand how it is working..
thanks in advance...

AnnotationSessionFactoryBean is Factory bean implemented by Spring to create Hibernate Session Factory and shared to Spring's Application Context.if you are planning to use Direct Hibernate ( in case you dont need persistent.xml / per-cont.xml / entityManager) you can provide the properties in AnnotationSession FactoryBean. and can be injected in Any DAO.
How ever if you are planing to wire through JPA. Then you need ( persistent and persistent-context and entity Manager). In order to do that you required three steps
1. declare / configure Spring's JPA Adapter to create EntityManager instance for you
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
Inside JPA Bean declaration provide details about your database and who is ORM provider such as ( hibernate /toplink / ....) in your case Hibernate
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.Oracle9Dialect"/>
</bean>
</property>
then Provide information about your persistent entity details in persistent.xml or some way
<property name="persistenceXmlLocation" value="classpath:persistence.xml" />
if you have any specific JPA properties then
<property name="jpaProperties">
<props>
<!-- <prop key="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</prop>
-->
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.use_sql_comments">false</prop>
</props>
</property>
Bottom line, Spring provies adapters to directly to Hibernate ( in that case your dont need Jpa files such as persistent.xml and so but you need hibernate related files like hbm files) or adapters to the JPA ( in that case you have provide details about who is JPA vendor and instrut spring how to connect to the JPA vendor).
Hope the above clarifies.

Related

WebSphereUowTransactionManager returning null transactionManager

I have a legacy code that use the TransactionManager to obtain access to the transaction to associate synchronization objects to the transaction afterCommit.
When I migrate to Spring 3, the recommended transaction manager to my solution is WebSphereUowTransactionManager, in truth, I feel that it is only a factory to the real Transaction Manager. But this transaction manager always return null in the method getTransactionManager().
I'm using EJB's 2.1 (legacy, remember?) with CMT.
My configuration is Spring 3.1.2.RELEASE, Hibernate 3.6.8.Final, Websphere 6.1.0.43, my beans are:
<bean
id="transactionManager"
class="org.springframework.transaction.jta.WebSphereUowTransactionManager" />
<bean
name="auditContextManager"
class="... my class ...">
<property name="transactionManager">
<bean factory-bean="transactionManager" factory-method="getTransactionManager" />
</property>
</bean>
My hibernate configuration is:
<hibernate-configuration>
<session-factory>
<property name="hibernate.jdbc.fetch_size">200</property>
<property name="hibernate.jdbc.use_get_generated_keys">true</property>
<property name="hibernate.bytecode.use_reflection_optimizer">true</property>
<property name="hibernate.connection.datasource">java:comp/env/jdbc/ORDS</property>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle9iDialect</property>
<property name="hibernate.max_fetch_depth">3</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property>
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</property>
<property name="hibernate.show_sql">false</property>
... too much mappings to show here ...
</session-factory>
</hibernate-configuration>
And my bean auditContextManager has always transactionManager set to null.
It seems to me that WebSphereUowTransactionManager do not expose Transaction Manager intentionally. Is this alright ?
There is any way so I can get the Transaction Manager ? Since WebSphereUowTransactionManager is not really the transaction manager, but only a transaction manager factory.
It is not a factory for the TransactionManager but, as the name suggest, the UOWManager. It uses the Websphere native API for managing transactions (which has broader support for certain things than the plain JTA api).
So there isn't going to be a TransactionManager it will always be null.
Basically if you want the transactionamanager you will have to do a JNDI lookup.
com.ibm.ws.Transaction.TransactionManagerFactory is the factory you should use to get the transaction manager .

hibernate.search.default.directory_provider in spring beans rather than persistence.xml

I am in a rather nasty situation. We use compass for Hibernate search integration with Lucene and have implemented database directory search (using JdbcDirectory) instead of FSDirectoryProvider, RAMDirectoryProvider etc.
The problem is that the directory provider is passed as a property inside the META-INF/persistence.xml like the one below:
<property name="hibernate.search.default.directory_provider" value="uk.company.package.JdbcDirectoryProvider" />
We need to pass the database details to the the JdbcDirectoryProvider as JdbcDirectory requires a datasource to be passed.
We are constructing the datasource (for the directory provider) in an unconventional way using a property file (in the class path) with the database and index details.
If we have uk.company.JdbcDirectoryProvider configured as a spring bean, we can inject the datasource. This works well with Tomcat but not with OAS or Weblogic as still as we are passing the directory_provider in the persistence.xml. Probably becasue the datasource is initialized by the spring (becasue of the way classloaders work in these app servers).
My question is how can we configure the hibernate.search.default.directory_provider directly inside aSpring bean instead of the persistence.xml?
The closest place is:
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
But it only takes three properties:
<property name="showSql" value="true" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
Solution
You could pass the hibernate properties in spring bean as jpaProperties
<property name="jpaProperties">
<props>
<prop key="hibernate.search.default.directory_provider">
uk.company.package.JdbcDirectoryProvider
</prop>
</props>
</property>
I found the solution.
You could pass the hibernate properties in spring bean as jpaProperties
<property name="jpaProperties">
<props>
<prop key="hibernate.search.default.directory_provider">
uk.company.package.JdbcDirectoryProvider
</prop>
</props>
</property>

No Session found for current thread using JTA TransactionManager

I'm having some trouble migrating to hibernate 4 while using a JTA Transaction Manager.
Maybe you can help, cause I'm all out of ideas.
Software:
Spring: 3.1.1.RELEASE
Hibernate: 4.1.3.Final
Database: Oracle 11g
Application: Ejb 3.0 deployed in Websphere Application Server 7.0 (using #Interceptors(SpringBeanAutowiringInterceptor.class) to initialize the spring context)
Spring configuration:
<context:annotation-config />
<context:component-scan base-package="myServicePackage,myDaoPackage" />
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/MyDataSource" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="myModelPackage" />
<property name="mappingResources" value="queries.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
</props>
</property>
</bean>
<tx:jta-transaction-manager />
<!-- <bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager" /> -->
<tx:annotation-driven />
Service:
#Service
public class TradeService {
#Autowired
private TradeDao tradeDao;
}
Dao:
#Repository
#Transactional
public class TradeDao {
#Autowired
private SessionFactory sessionFactory;
public Trade getTrade(){
return (Trade) sessionFactory.getCurrentSession().getNamedQuery("get_trade").uniqueResult();
}
Throws:
org.hibernate.HibernateException: No Session found for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1041)
at myDaoPackage.TradeDao.getTrade(TradeDao.java:26)
Notes:
I've also tried using #Transactional on the service instead of the
dao. Same result.
Similar config, but using Spring 3.0.5.RELEASE, Hibernate 3.6.5.Final, and TradeDao extending HibernateDaoSupport works.
So, does anyone have any ideas?
I've been trying a lot of things all day today.
My head is spinning and I'm annoyed, so I must be missing something very simple, but at this point I can't really tell :)
I finally got this working.
As I was expecting I was missing just some small configuration :)
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</prop>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</prop>
</props>
</property>
I found these configuration options earlier while browsing, but for some reason they didn't work when I tried them. Probably I had something else wrong at that time... (see Transaction strategy configuration chapter)
Thank you all for trying to help!
It's probably much like the problem that this person was having: http://forum.springsource.org/showthread.php?121109-Transaction-Propagations-and-Hibernate-4
That is, HibernateDaoSupport (and, presumably, HibernateTemplate) was creating a Session if one wasn't found on the Thread, whereas it sounds like the new approach does not.
EDIT: I just realized that the included link is using a HibernateTransactionManager. I believe that if you use a JtaTransactionManager and do not use a HibernateTemplate, you have to manually apply advice around the target which creates a session.
It might also be something they missed in Spring: https://jira.springsource.org/browse/SPR-9404
By default the #Transactional annotation works on interfaces. Since you're going sans interface, you should add the proxy-target-class="true" attribute to the <tx:annotation-driven /> tag in your configuration.

Creating HibernateTemplate by org.springframework.orm.hibernate4.LocalSessionFactoryBean

I work with Spring 3.1 + Hibernate 4.
I've created the following sessionFactory:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
</props>
</property>
<property name="packagesToScan" value="com.my.company"/>
</bean>
As you see, the above sessionFactory is for Hibernate 4.
I am trying to crate a HibernateTemplate (org.springframework.orm.hibernate3.HibernateTemplate) through Java code, by that sessionFactory, but I am not sure how to do this.
I've tried the following code:
#Resource(name="sessionFactory")
public void setSessionFactory(LocalSessionFactoryBean sessionFactory) {
this.hibernateTemplate = new HibernateTemplate(sessionFactory.getObject());
}
But I'm getting the following error message:
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'sessionFactory' must be of type [org.springframework.orm.hibernate4.LocalSessionFactoryBean], but was actually of type [org.hibernate.internal.SessionFactoryImpl]
Could you show how to do this?
As from this post:
HibernateTemplate isn't recommended for use anymore (about since the
release of hibernate 3.0.1) there is no more added value so that isn't
going to be in there anymore for hibernate 4. Simply use the plain
SessionFactory and use the getCurrentSession method to obtain the
current transactional session (don't use openSession!!!!) and you are
good to go...
From the javadoc of package org.springframework.orm.hibernate4:
Contains an implementation of Spring's transaction SPI for local
Hibernate transactions. This package is intentionally rather minimal,
with no template classes or the like, in order to follow native
Hibernate recommendations as closely as possible.
You don,t need to extends any hibernate dao support class in latest version of spring. You can directly inject hibernate sessionfactory from xml/java based configuration. And it also need to be injected into transaction manger. Refer this link for better understanding:
http://hantsy.blogspot.in/2013/07/use-native-hibernate-4-api.html

Need Example Transaction handling in Spring 3

I need step by step guide to handle transactions in spring sqltemplate. Transaction handling has to be implemented in my project. Guide me. Need to use the transaction Managment with SqlTemplate.
I suggest you use #Transaction annotation than code it manually. You may follow example here. For its best practice, you may read here. If you plan to spend few hours to study Spring Data JPA, you almost no need to handle transaction manually for most cases.
Thanks.
if you are using Programmatic Transactions then use below
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref local="dataSource"/>
</property>
</bean>
Programmatic means you have transaction management code surrounding your business code.
This gives extreme flexibility, but is difficult to maintain.
Declarative means you separate transaction management from the business code.
You can use annotations or XML based configuration.
Declarative Transaction Management allows to eliminate any dependencies on the transaction framework from the Java code.
The four participants to provide the transaction support are transaction manager, proxy factory, transaction interceptor, and a set of transaction attributes. below is an example
<bean id="boxOffice" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="target">
<ref bean="boxOfficeService"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="allocate*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

Resources