Spring Hibernate session issue - java

Hi I'm having a problem setting up hibernate on spring. I was able to make it work but it creates a lot of session on the database. From What i have notice it creates session for every bean on my spring.xml. Since I have 6 beans declared I also have 6 session on the database on application start Here is my code
<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"
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.xsd"
xmlns:tx="http://www.springframework.org/schema/tx"
>
<!-- Uncomment and add your base-package here: <context:component-scan base-package="org.springframework.samples.service"/> -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:" />
<property name="username" value="Use" />
<property name="password" value="Pass" />
</bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.model" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<!-- <prop key="hibernate.current_session_context_class">managed</prop> -->
<prop key="hibernate.show_sql">true</prop>
<prop key="format_sql">true</prop>
</props>
</property>
</bean>
<bean id="PDao" class="com.PDaoImpl">
<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</bean>
<bean id="PService" class="com.PServiceImpl">
<property name="pDao" ref="PDao" />
</bean>
<bean id="MNDao" class="com.MNDaoImpl">
<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</bean>
<bean id="MNService" class="com.MNServiceImpl">
<property name="MNDao" ref="MNDao" />
</bean>
<bean id="SWDao" class="com.SWDaoImpl">
<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</bean>
<bean id="SWService" class="com.SWServiceImpl">
<property name="SWDao" ref="SWDao" />
</bean>

You need to use transactionManager to manage session for you.
Add the following lines of code to your spring.xml
....
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="yourSessionFactory" />
</bean>
....
Then you have to annotate your service impl classes #Transactional("transactionManager") to make transactionManager managing transactions through session
#Transactional("transactionManager")
public class PServiceImpl implements PServiceImpl{
....
Just an advice you can replace XML config for the DI by annotations to make it easy
in spring.xml, remove all your beans declarations (xxservice and xxxdao) and replace them by: <context:component-scan base-package="put here the package where your services and daos are lacated" />
your service must look like this :
#Service
#Transactional("transactionManager")
public class XXXServiceImpl implements XXXService{
#Autowired
private XXXDAO xxxDAO;
...
}
And your dao must look like :
#Repository
public class XXXDAOImpl implements XXXDAO {
#Autowired
private SessionFactory sessionFactory;
...
}
One more thing, add the tx schema in your file config header, your spring.xml should look like this :
<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:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
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.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">

Related

HikariCP too many Connections with jooq

When using jooq and HikariCP DataSource (Autowired) in a Spring Restful API i get the problem, that jooq is somehow not releasing the DataSource.
Some Code:
#Autowired
private DataSource dataSource;
//Further down
DSLContext create = DSL.using(dataSource, SQLDialect.MYSQL);
After using this repository/call two or three times i have too many connections open.
My dispatcher-servlet.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
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.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<context:component-scan base-package="com.rh" />
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="20971520"/> <!-- 20 MB -->
</bean>
<context:property-placeholder location="classpath:database/database.properties"/>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="springHikariCP" />
<property name="connectionTestQuery" value="SELECT 1" />
<property name="dataSourceClassName" value="${jdbc.driver}" />
<property name="maximumPoolSize" value="20" />
<property name="idleTimeout" value="20" />
<property name="dataSourceProperties">
<props>
<prop key="url">${jdbc.url}</prop>
<prop key="user">${jdbc.username}</prop>
<prop key="password">${jdbc.password}</prop>
<prop key="prepStmtCacheSize">50</prop>
<prop key="prepStmtCacheSqlLimit">50</prop>
<prop key="cachePrepStmts">true</prop>
<prop key="useServerPrepStmts">true</prop>
</props>
</property>
</bean>
<!-- HikariCP configuration -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<constructor-arg ref="hikariConfig" />
</bean>
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<!--<beans:constructor-arg value="256" />-->
<!--<beans:property name="iterations" value="1000" />-->
</bean>
<!--Different providers-->
<bean id="cloudinaryProvider" class="com.rh.bean.CloudinaryProvider"></bean>
<bean id="s3Provider" class="com.rh.bean.S3Provider"></bean>
<bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean" autowire="no">
<property name="propertyNamingStrategy" value="CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES" />
</bean>
<mvc:annotation-driven>
<mvc:path-matching suffix-pattern="false" trailing-slash="false" />
<mvc:argument-resolvers>
<bean class="com.rh.util.CurrentUserHandlerMethodArgumentResolver"/>
</mvc:argument-resolvers>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<ref bean="objectMapper" />
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<security:global-method-security pre-post-annotations="enabled" secured-annotations="enabled"></security:global-method-security>
</beans>
Ok i fixed the problem:
#Autowired
private DataSource dataSource;
//Further down
Connection con=dataSource.getConnection();
DSLContext create = DSL.using(con, SQLDialect.MYSQL);
//Execute code here
con.close();
So instead of directly using the DataSource i used a connection and released it.

Hibernate not creating tables with HSQL and Spring

anybody has idea why hibernate is not creating tables in my example ?
Here's my web.xml - http://pastebin.com/ZaseSaBS
mvc-dispatcher-servlet.xml - http://pastebin.com/LbdxMSAb
applicationContext.xml - http://pastebin.com/bAHMaVNX
console logs - http://pastebin.com/tTZZbxkX
I have similiar project with almost the same configuration and everything seems to run just fine on the other project. Any ideas why it's not creating tables here?
I've one test enity in com.calculator.enity with #Entity #GeneratedValue annotations, i have it listed in persistence.xml file. There's also JpaRepository for this entity in com.calculator.repository
It looks like your persistence configuration is not properly done. Use this sample persistence configuration as per your requirement. This is working fine for me.
<?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:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<context:component-scan base-package="com.xxx.xxx"/>
<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryBean" />
</bean>
<bean id="entityManagerFactoryBean"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.xxx.xxx" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/test" />
<property name="username" value="postgres" />
<property name="password" value="prateek" />
</bean>
</beans>

Unable autowire SessionFactory[null] into #Transactional bean

I have faced very strange issue with autowiring Hibernate SessionFactory bean into my Service.
I'm able to find SessionFactory bean in Spring Context object. So no issues with creating such bean.
But I can not autowire this bean into my service when it is marked with #Transactional annotation. Factory field is null.
Once I remove this annotation - everything works good.
Service Class:
#Service
#Transactional
public class ExampleRunner implements Runnable{
#Autowired
SessionFactory sessionFactory;
...
}
applicationContext.xml:
<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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:property-placeholder location="classpath:application.properties"
ignore-resource-not-found="true" />
<context:component-scan base-package="org.edu" />
<context:annotation-config />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"
value="${jdbc.driverClassName:org.hsqldb.jdbcDriver}" />
<property name="url" value="${jdbc.url:jdbc:hsqldb:mem:myAppDb}" />
<property name="username" value="${jdbc.username:sa}" />
<property name="password" value="$jdbc.password:}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="org.edu" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
${hibernate.dialect:org.hibernate.dialect.HSQLDialect}
</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto:create-drop}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql:true}</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="txManager"
proxy-target-class="true" />
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
Usage:
public static void main(String[] args) {
Runnable runner = new ClassPathXmlApplicationContext("applicationContext.xml").getBean(ExampleRunner.class);
runner.run();
}
Seems like when I make #Transactional as class level annotation Spring creates CGLib proxy bean where SessionFactory field is null.
But when I use #Transational as method level annotation everything works good.
So I just want to understand such behavior.
What have I missed from Spring documentation?
I use Spring 4.1.4.RELEASE.
I got your error actually why you getting problem here because you not allowing container to auto-wired bean for you as you using java Main method it will not auto-wired bean that's why you getting error.

TransactionRequiredException in spring webmvc framework

It's many similar, but not the same issues, so I couldn't find a solution for this one.
I have Spring + JPA(Hibernate) web-application.
Context configuration (data-context.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:jdbc="http://www.springframework.org/schema/jdbc"
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.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/db"/>
<property name="username" value="postgres"/>
<property name="password" value="1234"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="packagesToScan" value="com.myapp.mvc.logic.domain"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<context:annotation-config/>
<context:component-scan base-package="com.myapp.mvc.logic" />
DispetcherServlet configuration (servlet-context.xml):
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
">
<annotation-driven validator="validator"/>
<resources mapping="/resources/**" location="/resources/" />
<default-servlet-handler/>
<beans:bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" id="tilesViewResolver">
<beans:property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView"/>
</beans:bean>
<beans:bean class="org.springframework.web.servlet.view.tiles3.TilesConfigurer" id="tilesConfigurer">
<beans:property name="definitions">
<beans:list>
<beans:value>/WEB-INF/layouts/layouts.xml</beans:value>
<beans:value>/WEB-INF/views/**/views.xml</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<interceptors>
<beans:bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/>
</interceptors>
<beans:bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
id="messageSource"
p:basenames="classpath:META-INF/i18n/application, classpath:META-INF/i18n/validation_messages"
/>
<beans:bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver"
id="localeResolver"
p:cookieName="locale"/>
<beans:bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<beans:property name="validationMessageSource" ref="messageSource"/>
</beans:bean>
<context:component-scan base-package="com.myapp.mvc" />
Controller:
#RequestMapping("/users")
#Controller
public class BankAccountCatalogController {
#Inject
private Functions functions;
#RequestMapping(value="/update", method = RequestMethod.POST)
public String catalogBankAccountUpdate(Model uiModel) {
functions.addUser();
return "employee_cabinet/catalog_bank_account";
}
}
Functions.class:
#Service("functions")
#Repository
#Transactional
public class Functions {
#PersistenceContext
private EntityManager em;
#Transactional
public void addUser() {
User user = new User();
user.setFirstName("John");
user.setLastName("John");
user.setMiddleName("John");
user.setEmail("John#gmail.com");
user.setPhone(null);
user.setMd5Password("1234");
em.persist(user);
em.flush();
}
}
When I activate the controller, in em.flush(); line I get an error:
javax.persistence.TransactionRequiredException: no transaction is in progress
On some reason transaction don't active in addUser() function. I tried run function in JUnit environment - it works fine.
Any ideas?
Try removing the EntityManager from the controller and specifying the method as transactional on the controller.
#RequestMapping("/users")
#Controller
public class BankAccountCatalogController {
#Inject
private Functions functions;
#RequestMapping(value="/update", method = RequestMethod.POST)
#Transactional
public String catalogBankAccountUpdate(Model uiModel) {
functions.addUser();
return "employee_cabinet/catalog_bank_account";
}
}
Also make sure the Functions class is specified in the packages you are component scanning, which is com.dominform.mvc.logic.
<context:component-scan base-package="com.dominform.mvc.logic" />
Solved. It was wrong configuration of DispetcherServlet.
Instead of
<context:component-scan base-package="com.myapp.mvc" />
in servlet-context.xml, I wrote
<context:component-scan base-package="com.myapp.mvc.web.controller" />
and it works.
Helpful topic: Spring #Transactional - javax.persistence.TransactionRequiredException

Difficulty Using Spring in a JAR With Hibernate

I am attempting to split out the Hibernate DAO and Model Object layer from an existing application so they can be used across multiple applications. Unfortunately, I'm not having much success: a NoSuchBeanDefinitionException is thrown when trying to get the SessionFactory from the Application Context.
All of DAO classes extend a class called GenericDaoHibernate2. Each DAO extends this, and passes a Class in the constructor. Pretty standard Generic DAO stuff.
I figured this would be the logical place to set the session factory as well (there are ALOT of DAO classes). So, in the constructor class, I did this:
public GenericDaoHibernate2(final Class<T> persistentClass) {
ctx = new ClassPathXmlApplicationContext("META-INF/applicationContext-dao.xml");
this.sessionFactory = (SessionFactory) ctx.getBean(SessionFactory.class);
log.debug("Value of app context: " + ctx.toString());
log.debug("Value of sessionFactory: " + sessionFactory);
this.persistentClass = persistentClass;
}
Unfortunately, this blew up with the previously mentioned exception:
Caused By: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.hibernate.SessionFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:924)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:793)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:551)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
Truncated. see log file for complete stacktrace
I've also attempted this with the app context file just in the classpath, setting the value when declaring the variable, etc, etc.
I'm guessing what is happing is that as part of the Maven build, the jar isn't referencing the libraries on the classpath, but I really don't know...
UPDATE: Stupid, stupid me... forgot to show the application context file.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"
default-lazy-init="true">
<tx:annotation-driven transaction-manager="transactionManager" />
<context:component-scan base-package="org.jason.dao.hibernate" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#//192.168.1.1/db01" />
<property name="username" value="USER" />
<property name="password" value="PASSWORD" />
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibername.format_sql">true</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.jdbc.use_get_generated_keys">true</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
<prop key="hibernate.default_catalog">CATALOG</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>org.jason.model</value>
</list>
</property>
</bean>
</beans>
Another update: Was asked for a sample DAO. The interface is a "standard" generic interface, accepting the generic paramters T and PK, just like the Impl. The following one doesn't have any specific methods other than what it inherits from GenericDaoHibernate2.
#Repository("AreaOfPreferenceDAO")
public class HibernateAreaOfPreferenceDAO extends GenericDaoHibernate2<AreaOfPreference, AreaOfPreferenceCompositeId> implements AreaOfPreferenceDAO {
public HibernateAreaOfPreferenceDAO()
{
super(AreaOfPreference.class);
}
}
In order to wire in the SessionFactory into your custom generic DAO, you can go ahead and simply use #Autowire, as long as the overall Spring context is defining the SessionFactory bean.
To define the bean:
<bean id="sessionFactory" class=
"org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="org.rest" />
<property name="hibernateProperties">
...
</property>
</bean>
<bean id="dataSource" class=
"org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="restUser" />
<property name="password" value="restmy5ql" />
</bean>
And to wire, simply:
#Autowired
SessionFactory sessionFactory;
The right place to bootstrap the context is not in the constructor of your DAO; if you're working with a web application, you can go with the traditional approach:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Since this is not a web application, then the context cannot be bootstrapped in web.xml; however, the bootstrapping still needs to be external - a main class would simply need to create the XmlWebApplicationContext and configure it.
Hope this helps.
The fact that you are creating a new application context in each DAO object may be getting you into trouble.
ctx = new ClassPathXmlApplicationContext("META-INF/applicationContext-dao.xml");
This is kind of circular if you think about it. You call the context, which does a component scan for DAO's, then the DAO instantiates a new context, which does a component scan for DAO's ...
I would just autowire the sessionfactory directly as someone else had mentioned.
#Repository("AreaOfPreferenceDAO")
public class HibernateAreaOfPreferenceDAO extends GenericDaoHibernate2<AreaOfPreference, AreaOfPreferenceCompositeId> implements AreaOfPreferenceDAO {
#Autowired
public HibernateAreaOfPreferenceDAO(SessionFactory sessionFactory)
{
super(sessionFactory, AreaOfPreference.class);
}
}
No component should need to construct a new application context.
Had the same problem, unable to make injection work.
My problem was "sequence". Hibernate xml must be invoked first.
dispatcher-servlet.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<!-- init hibernate first -->
<import resource="classpath:HibernateContext.xml"/>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".jsp" />
</bean>
<mvc:annotation-driven />
<context:component-scan base-package="com.xxx.yyy" />
content of hibernateContext.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:database.properties</value>
</list>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.xxx.yyy.model" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- bean id="transactionManager" class=" org.springframework.transaction.jta.JtaTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean-->

Categories