autowire hibernate session with spring 3 and hibernate 4 - java

I want to do: #Autowire Session session. For hibernate 3, the process is described here. it uses ...hibernate3.SessionFactoryUtils.getSession. but in spring 3.2 there is no such method in ...hibernate4.SessionFactoryUtils

Great changes have taken place in Spring3.x, a few days ago I met the same problem, Through the offical document we know that Spring won't provide HibernateTemplate and HibernateDaoSupport any longer, we are advised to use Hibernate pure API, and about your confusion here is my solution:
first, define a sessionFactory bean in applicationContext.xml,
<!-- sessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="packagesToScan">
<list>
<value>com.bbs.*.entity</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
${hibernate.dialect}
</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.connection.autocommit">${hibernate.connection.autocommit}</prop>
<prop key="hibernate.connection.url">jdbc:mysql://localhost/bbs</prop>
<prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
<prop key="hibernate.connection.username">root</prop>
<prop key="hibernate.connection.password">123456</prop>
</props>
</property>
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
and then, in your DAO
#Autowired
#Qualifier("sessionFactory")
private SessionFactory sessionFactory;
public Session getSession() {
return sessionFactory.getCurrentSession();
}
in this way you'll get the hibernate session, then do what you want, just enjoy it:)

Related

Hibernate Session/Template returns null

I'm pretty new to Spring, and I probably miss something obvious here. I'm working on a project that dates back to 2008 or so, which uses Spring (v4.2.5) and Hibernate (v3.5.6). I've copied some code from another project of around the same time-period, and currently try to access the Hibernate Session from that copied code.
Some things I've tried, which all gave back null for both the HibernateTemplate and HibernateSession:
1.
org.hibernate.Session session = org.springframework.orm.hibernate3.SessionFactoryUtils
.getSession(getSessionFactory(), true);
// getSessionFactory comes from the Parent class
// org.springframework.orm.hibernate3.support.HibernateDaoSupport
2.
org.hibernate.Session session = org.springframework.orm.hibernate3.SessionFactoryUtils
.getSession(HibernateUtil.getSessionFactory(), true);
// Where HibernateUtil is our own factory-class:
import java.io.PrintStream;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
static {
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
}
3.
org.springframework.orm.hibernate3.HibernateTemplate hibernateTemplate = getHibernateTemplate();
org.hibernate.Session session = org.springframework.orm.hibernate3.SessionFactoryUtils
.getSession(hibernateTemplate.getSessionFactory(), true);
// getHibernateTemplate comes from the Parent class
// org.springframework.orm.hibernate3.support.HibernateDaoSupport
4.
org.springframework.orm.hibernate3.HibernateTemplate hibernateTemplate = getSpringHibernateTemplate();
org.hibernate.Session session = org.springframework.orm.hibernate3.SessionFactoryUtils
.getSession(hibernateTemplate.getSessionFactory(), true);
// Where getSpringHibernateTemplate is:
#InjectObject("spring:hibernateTemplate")
public abstract HibernateTemplate getSpringHibernateTemplate();
// With the following bean in our ourprojectname-general.xml:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingDirectoryLocations">
<!-- Add all Hibernate mappings to the list below -->
<list>
<value>/WEB-INF/hbm</value>
</list>
</property>
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="net.sf.ehcache.configurationResourceName">spinoff/dao/ehcache.xml</prop>
<!-- Determines the size of the JDBC fetch, that is the maximum number
of rows that are exchanged between Hibernate and the database in one go.
It's been increased to reduce overhead when searching for all entiteits -->
<prop key="hibernate.jdbc.fetch_size">500</prop>
<prop key="hibernate.dialect">spinoff.objects.spatial.oracle.OracleSpatialDialect</prop>
<prop key="hibernate.default_batch_fetch_size">25</prop>
<prop key="hibernate.generate_statistics">false</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="use_sql_comments">false</prop>
<prop key="hibernate.transaction.flush_before_completion">true</prop>
<prop key="hibernate.connection.release_mode">after_transaction</prop>
</props>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
5.
I've also tried this SO answer with the same result:
java.lang.IllegalArgumentException: No SessionFactory specified
at org.springframework.util.Assert.notNull(Assert.java:115)
...
On most other places in the code it's done like at 1, and it was also done like this in the copied code in the other project.
My guess is that I need to #InjectObject or #AutoWired a getter for the Spring-bean of either the HibernateTemplate or Session, something like I've tried at 4, but it remains returning null.
Could anyone point me to an answer? All I want is a Hibernate DB-Session in my class. If you need to see the code of any other .java or .xml files let me know.
Ok, as correctly pointed out by #M.Deinum in the comments, I was looking at my problem at the completely wrong spot. It turned out I forgot to copy a few String-beans from the other project's XML-files where I copied the java files from.
So, after copying and slightly modifying those beans it worked by just using Session session = SessionFactoryUtils.getSession(getSessionFactory(), true);
Here are the beans:
<bean id="ourDaoTarget" class="our.dao.OurDao">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<bean id="ourDao" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>plus.dao.IOurDao</value>
</list>
</property>
<property name="target" ref="ourDaoTarget" />
<property name="interceptorNames">
<list>
<value>hibernateInterceptor</value>
</list>
</property>
</bean>
<bean id="messageProcessor" class="our.plus.MessageProcessor">
<property name="ourDao" ref="ourDao" />
</bean>
And in the MessageProcessor class where the Dao was used I had to add a default constructor and getter & setter for the Dao.
Again thanks, #M.Deinum

Spring + Hibernate Transaction Management using Remote JNDI Datasource

I have a Spring application, that uses hibernate, Spring transaction management and a JNDI datasource located on Weblogic server.
Application works fine when deployed on weblogic, however it throws following error when running on local as a standalone java application (without container) -
org.hibernate.service.jndi.JndiException: Error parsing JNDI name
[javax.transaction.TransactionManager]
javax.naming.NoInitialContextException: Need to specify class name in
environment or system property
Here is the transaction manager, datasource and hibernate configuration I am using in my setup:
<bean id="transactionManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager"></bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/mydatasource"/>
<property name="jndiEnvironment" ref="weblogicJndiEnv"></property>
</bean>
<util:properties id="weblogicJndiEnv">
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
<prop key="java.naming.security.principal">weblogic</prop>
<prop key="java.naming.security.credentials">weblogic</prop>
<prop key="java.naming.provider.url">t3://#{ systemProperties['listenurl'] }</prop>
</util:properties>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="jtaTransactionManager" ref="transactionManager"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.current_session_context_class">jta</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</prop>
<prop key="hibernate.transaction.jta.platform">org.hibernate.service.jta.platform.internal.WeblogicJtaPlatform</prop>
<prop key="hibernate.connection.release_mode">auto</prop>
<prop key="hibernate.transaction.auto_close_session">true</prop>
</props>
</property>
<property name="packagesToScan" value="abc.xyz" />
</bean>
Is there anything I am missing in the above configuration?

How to create a hibernate session bean for both Annotated and hbm.xml configured entities

I have legacy hbm.xml configured persistent classes and Annotated persistent classes, so currently we have to specify per which session factory is being used in the DAO bean.
Unfortunately, that means that I'm running into an issue where we have a mix of DAO's that I'd like to use, aren't all associated to a single session factory.
I'd like to combine both into a single session factory bean since we can't just move everything over all at once.
How would I go about doing this?
Note: my current workaround is to Annotate some of the xml configured ones and then create two DAO beans: one for each Session Factory.
HBM.XML:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingLocations">
<value>hbm/path/*.hbm.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
Annotated:
<bean id="annotatedSessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="path.batch.persistent"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
Thanks M.Deinum and orid:
I was overthinking this.
There was never a need for two session factories.
So I just had to refactor the context file to:
<bean id="annotatedSessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="path.batch.persistent"/>
<property name="mappingLocations">
<value>hbm/path/*.hbm.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>

Spring multiple SessionFactory config?

I am trying to config two sessionFactories using spring. My config looks similar to the one listed here
Here's my config.xml
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url">
<value>${hibernate.connection.url}</value>
</property>
<property name="driverClassName">
<value>${hibernate.connection.driver_class}</value>
</property>
<property name="username">
<value>${hibernate.connection.username}</value>
</property>
<property name="password">
<value>${hibernate.connection.password}</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="mappingResources">
<list>
...Mappings
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
${hibernate.dialect}
</prop>
<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.default_batch_fetch_size">${hibernate.default_batch_fetch_size}</prop>
<prop key="hibernate.c3p0.min_size">${hibernate.c3p0.min_size}</prop>
<prop key="hibernate.c3p0.max_size">${hibernate.c3p0.max_size}</prop>
<prop key="hibernate.c3p0.timeout">${hibernate.c3p0.timeout}</prop>
<prop key="hibernate.c3p0.max_statements">${hibernate.c3p0.max_statements}</prop>
<prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>
</props>
</property>
</bean>
<bean id="dataSource2"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url">
<value>${hibernate.connection.mirror_url}</value>
</property>
<property name="driverClassName">
<value>${hibernate.connection.driver_class}</value>
</property>
<property name="username">
<value>${hibernate.connection.mirror_username}</value>
</property>
<property name="password">
<value>${hibernate.connection.mirror_password}</value>
</property>
</bean>
<bean id="sessionFactory2"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource2" />
</property>
<property name="mappingResources">
<list>
...Mappings
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
${hibernate.dialect}
</prop>
<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.default_batch_fetch_size">${hibernate.default_batch_fetch_size}</prop>
<prop key="hibernate.c3p0.min_size">${hibernate.c3p0.min_size}</prop>
<prop key="hibernate.c3p0.max_size">${hibernate.c3p0.max_size}</prop>
<prop key="hibernate.c3p0.timeout">${hibernate.c3p0.timeout}</prop>
<prop key="hibernate.c3p0.max_statements">${hibernate.c3p0.max_statements}</prop>
<prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>
</props>
</property>
</bean>
Then each dao gets a different sessionFactory assigned
<bean id="productDao"
class="test.dao.ProductDaoHibernate">
<property name="sessionFactory"><ref bean="sessionFactory" /></property>
</bean>
<bean id="currencyDao"
class="test.dao.CurrencyDaoHibernate">
<property name="sessionFactory"><ref bean="sessionFactory2" /></property>
</bean>
This config gets loaded when its added to the context
web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/test-data.xml /WEB-INF/classes/test-services.xml ... </param-value>
</context-param>
The problem shows whenever I start the server each sessionFactory built, but at the end of the second one this shows up:
[INFO] [org.springframework.beans.factory.support.DefaultListableBeanFactory]:? - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#97aaa6: defining beans [... Many elements...]; root of factory hierarchy
[INFO] [org.springframework.orm.hibernate3.LocalSessionFactoryBean]:? - Closing Hibernate SessionFactory
[INFO] [org.hibernate.impl.SessionFactoryImpl]:? - closing
[INFO] [org.springframework.orm.hibernate3.LocalSessionFactoryBean]:? - Closing Hibernate SessionFactory
[INFO] [org.hibernate.impl.SessionFactoryImpl]:? - closing
Any help, or lead would be appreciated, if you need more info please ask
spring4.2 & hibernate5.1.5
#Bean
public LocalSessionFactoryBean aaaSessionFactory() {
LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
localSessionFactoryBean.setDataSource(smsDataSource());
localSessionFactoryBean.setHibernateProperties(getHibernateProperties());
localSessionFactoryBean.setPackagesToScan(new String[]{"com.xxx.pojo"});
localSessionFactoryBean.setPhysicalNamingStrategy(new CustomNamingStrategy());
localSessionFactoryBean.setEntityInterceptor(new DynamicTableInterceptor());
return localSessionFactoryBean;
}
#Bean
public LocalSessionFactoryBean bbbSessionFactoryMultiple() {
LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
localSessionFactoryBean.setDataSource(smsDataSource());
localSessionFactoryBean.setHibernateProperties(getHibernateProperties());
localSessionFactoryBean.setPackagesToScan(new String[]{"com.xxx.pojo"});
localSessionFactoryBean.setPhysicalNamingStrategy(new CustomNamingStrategy());
localSessionFactoryBean.setEntityInterceptor(new DynamicTableInterceptor());
return localSessionFactoryBean;
}
public class xxx extends HibernateDaoSupport{***
#Autowired
public void anyMethodName(#Qualifier("aaaSessionFactory") SessionFactory sessionFactory) {
setSessionFactory(sessionFactory);
}
Actually this is supposed to be a comment, but don't have enough reputation (requires 50 points)
It seems you are trying to create 2 different bean id's which are of exactly same configuration. One way is to figure out whether 2 different session objects pointing to same configuration is required. Other way is to try adding the configurations in different files and load separately. Please add how you r trying to use these configurations in code.

Hibernate doesn't start

I have the following hibernate config on spring and the server starts after a long time but doesn't connect to DB (no schema on DB). So It was supose to give a error message or create the schema with <prop key="hibernate.hbm2ddl.auto">create</prop>.
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method = "close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://dburl:3306"/>
<property name="user" value="user"/>
<property name="password" value="pass!"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>waf/resources/User.hbm.xml</value>
<value>waf/resources/Post.hbm.xml</value>
<value>waf/resources/Position.hbm.xml</value>
<value>waf/resources/Comment.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<!-- C3P0 CONNECTION POOL -->
<prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>
<prop key="c3p0.acquire_increment">1</prop>
<prop key="c3p0.idle_test_period">100</prop>
<prop key="c3p0.max_size">20</prop>
<prop key="c3p0.max_statements">50</prop>
<prop key="c3p0.min_size">1</prop>
<prop key="c3p0.timeout">10</prop>
</props>
</property>
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
Can you guys help me out?
Hibernate does not create schemas with hbm2ddl.auto. It just creates | creates-drop | etc tables.
Going through the HBM files, you have given as below..
Validate instead of Create
I hope this will not create the DDL. can you please check that? Or is it a typo in question?
Adding to what others have proposed if you are using connection pool (which you are as c3po is mentioned) then while the session Factory is created it will try to use the connection pool backed datasource which in turn will connect to database to pre-create and pool connection. When you say that it does not connect to database - how do you know that ? Is there error in logs? I have seen that if Hibernate session factory is not able to configure itself it throws an error in the logs.

Categories