I am working on a messy web java project, with hibernate and tomcat server. First time i deploy the war on the server i can see the following log:
...
ContextLoader:273 - Root WebApplicationContext: initialization started XmlWebApplicationContext:495 - Refreshing Root WebApplicationContext: startup date [Wed Aug 06 14:18:37 COT 2014]; root of context hierarchy
XmlBeanDefinitionReader:315 - Loading XML bean definitions from ServletContext resource [/WEB-INF/applicationContext.xml]
DefaultListableBeanFactory:557 - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#4fba4e8c: defining beans [dataSource,sessionFactory,jdbcExceptionTranslator,hibernateTemplate,transactionManager,AbstractSpringDao,.......]; root of factory hierarchy
Environment:514 - Hibernate 3.2.5
Environment:547 - hibernate.properties not found
Environment:681 - Bytecode provider name : cglib
Environment:598 - using JDK 1.4 java.sql.Timestamp handling
HbmBinder:300 - Mapping class: co.com...bean1...
HbmBinder:300 - Mapping class: co.com...bean2...
HbmBinder:300 - Mapping class: co.com...bean3...
HbmBinder:300 - Mapping class: co.com...bean4...
...
but every time i open the home page on a new browser window.... i see this log:
FileSystemXmlApplicationContext:495 - Refreshing org.springframework.context.support.FileSystemXmlApplicationContext#4f8e9bee: startup date [Wed Aug 06 14:40:30 COT 2014]; root of context hierarchy
XmlBeanDefinitionReader:315 - Loading XML bean definitions from file [/home/david/Documents/INTERKONT/siccu/siente/build/web/WEB-INF/applicationContext.xml]
DefaultListableBeanFactory:557 - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#6b8616ff: defining beans [dataSource,sessionFactory,jdbcExceptionTranslator,hibernateTemplate,transactionManager,AbstractSpringDao .......]; root of factory hierarchy
HbmBinder:300 - Mapping class: co.com....bean1...
HbmBinder:300 - Mapping class: co.com....bean2...
HbmBinder:300 - Mapping class: co.com....bean3...
...
Any ideas????
this is my 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: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/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<!-- DataSource Definition -->
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName">
<value>org.postgresql.Driver</value>
</property>
<property name="url">
<value>jdbc:postgresql:DBDBDBDBDB</value>
</property>
<property name="username">
<value>XXXX</value>
</property>
<property name="password">
<value>YYYYYYYY</value>
</property>
</bean>
<!-- Hibernate SessionFactory Definition -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>co/com/....bean1.hbm.xml</value>
<value>co/com/....bean2.hbm.xml</value>
<value>co/com/....bean3.hbm.xml</value>
...
...
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.bytecode.use_reflection_optimizer">false</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
</props>
</property>
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<!-- Spring Data Access Exception Translator Defintion -->
<bean id="jdbcExceptionTranslator"
class="org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<!-- Hibernate Template Defintion -->
<bean id="hibernateTemplate"
class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
<property name="jdbcExceptionTranslator">
<ref bean="jdbcExceptionTranslator" />
</property>
</bean><!-- Hibernate Transaction Manager Definition -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<bean id="AbstractSpringDao" abstract="true" class="cobra.dao.AbstractSpringDao" scope="prototype">
<property name="hibernateTemplate">
<ref bean="hibernateTemplate" />
</property>
</bean>
...
...
it seems you are creating application context in your controller.
move this code outside of the controller.
ApplicationContext ctx = new FileSystemXmlApplicationContext("WEB-INF/applicationContext.xml");
and configure in your web.xml similer to below
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
In the first block off log lines, you see the correct way to configure spring in a web application: the context is loaded through the ContextLoader either from a listener or from a (Dispatcher)Servlet.
In the second block, the same application context is loaded again directly from disk. This is not correct.
The second load probably happens in a Servlet.service(...) method.
Instead of reloading the application context on every request, you could use WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); to access the one loaded previously.
This is not the preferred way to use spring in a web application (You should read about spring web), but it is probably the easiest way to fix your setup.
Related
I'm developing a simple standalone Java application using Spring and Hibernate to try to learn them.
I'm having some problems in the configuration of Spring and Hibernate, in order to really create some "useful" result from the code...
I've tried to follow the examples as reported in the book "Beginning Hibernate 2nd edition" and "Pro Spring 3", but i'm having , regarding Hibernate, this problem (i'm using log4j for the logging) :
1824 [main] INFO org.springframework.beans.factory.support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#38638273: defining beans [dataSource,sessionFactory,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,personaDao,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [app-context.xml]: Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'driverClassName' threw exception; nested exception is java.lang.IllegalStateException: Could not load JDBC driver class [${jdbc.driverClassName}]
It seems that the placeholder is ignored in the parsing of the configuration files
Here i've have copied an extract of them :
app-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:tx="http://www.springframework.org/schema/tx"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-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/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-3.2.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" >
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven/>
<bean id="personaDao" class="org.bladela.dataaccess.persona.PersonaDaoImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="show_sql">true</property>
<mapping class="org.bladela.dataaccess.persona.Persona"/>
</session-factory>
</hibernate-configuration>
jdbc.properties :
jdbc.driverClassName=org.postgresql.Driver
jdbc.dialect=org.hibernate.dialect.PostgreSQLDialect
jdbc.databaseurl=jdbc:postgresql://localhost:5432/employeemanagementdb
jdbc.username=bladela
jdbc.password=password
if i substitute all the placeholders with their values, the program goes on and it connects to the db (if i substitute only one...the error "goes" to the next one)
then it return an incorrect result (an empty list when it should return a list with one element) but maybe i'll ask about it later, if i can't solve it.
Any suggestion?
I don't see any PropertyPlaceholderConfigurer declared in your context. How are property placeholders supposed to be resolved?
One solution is to add
<context:property-placeholder location="classpath:jdbc.properties"/>
to your context.
I have a small application using Spring3, Hibernate4 and JSF2.
So far in my application I do not have hibernate.cfg.xml file, I have used Spring applicationContext.xml for scanning classes and annotations for Entity class.
applicationContext.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"
xmlns:context="http://www.springframework.org/schema/context"
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:component-scan base-package="net.test" />
<!-- Data Source Declaration -->
<bean id="DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="oracle.jdbc" />
<property name="jdbcUrl"
value="jdbc:oracle:thin:#server:1521:TEST" />
<property name="user" value="scott" />
<property name="password" value="tiger" />
<property name="maxPoolSize" value="10" />
<property name="maxStatements" value="0" />
<property name="minPoolSize" value="5" />
</bean>
<!-- Session Factory Declaration -->
<bean id="SessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="DataSource" />
<property name="annotatedClasses">
<list>
<value>net.test.model.Employees</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- Enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="txManager" />
<!-- Transaction Manager is defined -->
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="SessionFactory" />
</bean>
</beans>
What I would like to do is add hibernate.cfg.xml into my application, I know it is not mandatory if I have applicaionContext.xml exists.
The reason why I would want to include is because I would like to specify the following in hibernate.cfg.xml in order to resolve the issue of
org.hibernate.QueryException: ClassNotFoundException:
org.hibernate.hql.internal.ast.HqlToken
See this for details of exceptions I am getting
<property name="hibernate.query.factory_class" value="org.hibernate.hql.classic.ClassicQueryTranslatorFactory">
</property>
As I already have the following in applicationContext.xml, how best I could use hibernate.cfg.xml? Any help is highly appreciable.
<property name="annotatedClasses">
<list>
<value>net.test.model.Request</value>
</list>
</property>
Update 1
Error creating bean with name 'requestDAOImpl': Injection of autowired dependencies
failed; nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private org.hibernate.SessionFactory
net.test.request.dao.RequestDAOImpl.sessionFactory; nested exception is
org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'SessionFactory' defined in ServletContext resource
[/WEB-INF/applicationContext.xml]: Invocation of init method failed;
nested exception is org.hibernate.HibernateException: could not
instantiate QueryTranslatorFactory:
org.hibernate.hql.classic.ClassicQueryTranslatorFactory
.
Have you tried to set *hibernate.query.factory_class* property using Spring's application.xml like this?:
<bean id="SessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
...
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.query.factory_class">org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory</prop>
</props>
</property>
</bean>
It seems to me that this should work without explicitly using hibernate.cfg.xml.
I'm trying to use Hibernate in my Spring application but i've got an error on the project's deployment
Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/dispatcher-servlet.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Class' for property 'configurationClass'; nested exception is java.lang.IllegalArgumentException: Cannot find class [org.hibernate.cfg.AnnotationConfiguration].
Here my dispatcher-servlet with the bean session factory :
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
default-autowire="byName">
<context:component-scan base-package="hibernateTest" />
<context:annotation-config/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<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="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
And my hibernate-cfg.xml :
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="hibernateTest.web.InventoryController" />
</session-factory>
</hibernate-configuration>
I've many jars in my classpath and i thoutgh it doesn't miss anyone. Could you help me finding an issue ?
Thanks
You need to put the hibernate-annotations.jar on the classpath.
Cannot find class [org.hibernate.cfg.AnnotationConfiguration]
This is the reason, Can you check for this class in classpath.
org.hibernate.cfg.AnnotationConfiguration is deprecated,
and all its functionality has been moved to org.hibernate.cfg.Configuration.
change your code
<property name="configurationClass">
<value>org.hibernate.cfg.Configuration</value>
</property>
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-->
<bean id="projectService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="target">
<bean class="com.company.project.company.services.ServiceImpl" init-method="init">
<property name="HRappsdao" ref="HRappsdao"/>
<property name="projectdao" ref="projectdao"/>
</bean>
</property>
<property name="transactionAttributes">
<props>
<prop key="store*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="bulkUpdate*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</bean>
i have 2 datasource HRappsdao and projectdao, both are using different sessionFactory. in this case, my transactionmanager should be using which sessionfactory? (hrappsdao or projectdao) ?
editted
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" > //my HRappsdao using same
<ref local="sessionFactory"/>
</property>
</bean>
Actually, you're not showing the configuration of your transaction manager so I'm not really sure of what your are currently using but, quoting the documentation:
JTA (usually through JtaTransactionManager) is necessary for accessing multiple transactional resources within the same transaction.
With Spring 2.5, consider using the "new" <tx:jta-transaction-manager/> configuration element for automatic detection of the underlying JTA-based transaction platform (works with most app servers). See the chapter 9.8. Application server-specific integration for more details on this.
If you are using an older version of Spring, you'll need to configure your JtaTransactionManager manually. This will require some knowledge of your application server as the JNDI location of the JTA TransactionManager is specific to each J2EE server.
Please provide more details (like the version of Spring and the application server you are using if you need more guidance).
UPDATE: As I said, when using multiple datasources, you need to use the JtaTransactionManager and not the HibernateTransactionManager (see the javadoc). If you are using Spring 2.5, update your Spring configuration as below:
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<tx:jta-transaction-manager />
<!--
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
//my HRappsdao using same
<ref local="sessionFactory" />
</property>
</bean>
-->
...
</beans>
Note that you'll need something like JOTM with Tomcat or Jetty. You should maybe consider moving to a J2EE app server like JBoss or Glassfish.