I have a project with Spring 4 and we have a lot of #Transactional classes and methods over there. Everything works perfectly, but I can not to provide transactions driven by Spring 3 until I add AspectJ libs and special XML configs in context file. So I would like to know if Spring 4 implements something like AspectJ natively or am I doing something wrong?
UPDATED
this is xml file for 3d Spring
<?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"
xmlns:aop="http://www.springframework.org/schema/aop" 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.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:annotation-config />
<aop:config proxy-target-class="true" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="saveService" class="com.promptlink.stbtp.dao.billing.SaveService" />
<bean id="billingDaoImpl" class="com.promptlink.stbtp.dao.billing.BillingDaoImpl" />
<bean id="dbParams" class="com.promptlink.stbtp.dao.util.SessionManager"
factory-method="getDbParams">
</bean>
<bean id="url" factory-bean="dbParams" factory-method="getBillingUri" />
<bean id="user" factory-bean="dbParams" factory-method="getUser" />
<bean id="pass" factory-bean="dbParams" factory-method="getPassword" />
<bean id="driver" factory-bean="dbParams" factory-method="getDriver" />
<bean id="dialect" factory-bean="dbParams" factory-method="getDialect" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" ref="driver" />
<property name="url" ref="url" />
<property name="username" ref="user" />
<property name="password" ref="pass" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>com.promptlink.stbtp.dao.billing</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">#{dialect}</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<beans profile="webapp">
<bean id="billingDatabaseProcessor"
class="com.promptlink.stbtp.dao.statistics.billingReport.BillingDatabaseProcessorImpl"></bean>
</beans>
</beans>
UPDATED
For Spring 4 I have something like this for Hibernate
import org.hibernate.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
public class HibernateConfiguration {
#Bean
public HibernateTransactionManager transactionManager() {
return new HibernateTransactionManager(sessionFactory());
}
#Bean
public SessionFactory sessionFactory() {
return SessionManager.getSessionFactory();
}
}
And standard AnnotationConfigApplicationContext initializer
Related
Namastey,
We have a class and its methods as below-
#Service
#Component
public class ReqServiceImpl implements ReqService {
#Autowired
private SubmitDAO submitDAO;
#Override
#Transactional(readOnly = false, rollbackFor = { CustomException.class },propagation=Propagation.REQUIRES_NEW)
public Map initiateSubmission(DetailsDTO vo) CustomException{
//it has two method defined within the same class
if(condition){
Map resultMap = submitRequest1(map,vo.isTestMode());
}else{
Map result = (HashMap) submitRequest2(map,flag,vo.isTestMode());
}
}
#Transactional(readOnly = false, rollbackFor = { CustomException.class }, propagation=Propagation.REQUIRED)
public void submitRequest1(Map map,boolean testMode) CustomException{
submitDAO.simpleTableInsert1(map);
submitDAO.simpleTableInsert2(map);
submitDAO.procedureCall(map);
if(!"success".equalIgnorecase(map.get("output"))){
throw new CustomException("Service Layer | submitRequest1 | Proc Not successs");
}
}
#Transactional(readOnly = false, rollbackFor = { CustomException.class },
propagation=Propagation.REQUIRED)
public void submitRequest2(Map map,boolean testMode) throws CustomException{
submitDAO.simpleTableInsert1(map);
submitDAO.simpleTableInsert2(map);
submitDAO.procedureCall(map);
}
}
Below is our spring-servlet.xml file
In this, we have added our configuration for annotation, proxy and default advice to proxy.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns="http://www.springframework.org/schema/beans"
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.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/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:annotation-config />
<context:component-scan base-package="com.company,com.company.security.filter,org.springframework.jdbc" />
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg index="0" name="defaultCharset"
value="UTF-8" />
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
<aop:aspectj-autoproxy proxy-target-class="true"/>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
<property name="proxyTargetClass" value="true" />
</bean>
<bean id="LogAspect" class="com.company.common.aop.LogAspect">
</bean>
<bean id="PerfAspect" class="com.company.common.aop.PerfAspect">
</bean>
<bean id="SessionAspect" class="com.company.common.aop.SessionAspect">
</bean>
<bean id="mailProperties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" >
<list>
<value>classpath:db.properties</value>
<value>classpath:dSource.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
<bean id="myDataSource" class="org.springframework.jndi.JndiObjectFactoryBean" primary="true">
<property name="jndiName" value="${DEVJNDI}"></property>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="myDataSource" />
</bean>
<bean id="DataSourceCo" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${JNDINAMECOM}"></property>
</bean>
<bean id="transactionManager1"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="DataSourceCo" />
</bean>
<bean id="myDataSourceI" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${JNDINAMEI}"></property>
</bean>
<bean id="transactionManager2"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="myDataSourceI" />
</bean>
<!-- Create a proxy to generate session-scope -->
<bean id="userBean"
class="com.company.common.session.UserDetailsSessionBean"
scope="session">
<aop:scoped-proxy />
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
/>`enter code here`
</beans>
The method 'procedureCall' which is in another class has a procedure call inside.
The procedure does not have any commit inside.
After, the procedure return with any error, we throw an exception, but all in vain. The insert done by procedure still gets committed and transaction does not rollback.
The proc gives output "error" or "succcess", if there was any error.
If we get any error "error", then we throw the customized exception.
It should rollback everything done inside proc, but that does not happen.
Kindly suggest.
When I try to save data to DB the SessionFactory is null. Find the code below.
Spring configuration
<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:mvc="http://www.springframework.org/schema/mvc" 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/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Specifying base package of the Components like Controller, Service, DAO -->
<context:component-scan base-package="com.service.jaxws" />
<!-- Getting Database properties -->
<!-- <context:property-placeholder location="classpath:application.properties" /> -->
<mvc:annotation-driven />
<!-- Specifying the Resource location to load JS, CSS, Images etc -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- View Resolver -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- DataSource -->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource"
id="dataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/hrms"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="packagesToScan" value="com.service.jaxws"></property>
</bean>
<!-- Transaction -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
Repository Bean
#Repository
public class UserDAOImpl implements UserDAO {
#Autowired
private SessionFactory sessionFactory;
#Override
public void addUser(UserBO user) {
if (sessionFactory != null) {
sessionFactory.getCurrentSession().save(user);
} else {
System.out.println("Null");
}
}
}
When debugging each and every time the SessionFactory is null. Could anyone please tell me what I am missing?
Thanks in advance
Serin
Matt the issue has been resolved. The main problem was with the #Autowired. it was not working as expected. I tried this in my #Webservice class. After using the extends SpringBeanAutowiringSupport it is working properly. Anyway thanks for your support.
Well, I looked at all questions related to my problem in the forum, but I could not solve my problem. So I'm asking for help from anyone who can help me with my problem.
In case, everything was working without using the #Transactional annotation, however I want to make it work this way, waiting for comments.
This is my persistence.xml:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<!-- Persistence Unit -->
<persistence-unit name="databaseEstoque" transaction-type="RESOURCE_LOCAL">
<!-- Implements to JPA, in this case Hibernate -->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<!-- Here you can see all entities -->
<class>com.systemhaus.examples.domain.Produto</class>
<class>com.systemhaus.examples.domain.Gaveta</class>
<class>com.systemhaus.examples.domain.AbstractOperacao</class>
<class>com.systemhaus.examples.domain.AdicionaQuantidade</class>
<class>com.systemhaus.examples.domain.RetiraQuantidade</class>
<properties>
<!-- JDBC properties -->
<!-- Hibernate specific settings -->
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
This is my 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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config />
<bean id="myEmf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="databaseEstoque" />
<property name="dataSource" ref="dataSource"/>
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<bean id="gavetaDAO" class="com.systemhaus.examples.infraestructure.GavetaDBDAO" />
<bean id="produtoDAO" class="com.systemhaus.examples.infraestructure.ProdutoDBDAO" />
<bean id="operacaoDAO" class="com.systemhaus.examples.infraestructure.OperacaoDBDAO" />
<bean id="notaFiscalDAO" class="com.systemhaus.examples.infraestructure.NotaFiscalDBDAO" />
<bean id="compraFacade" class="com.systemhaus.examples.application.CompraFacade">
<constructor-arg ref="produtoDAO" />
<constructor-arg ref="gavetaDAO" />
<constructor-arg ref="operacaoDAO" />
<constructor-arg ref="estoque" />
</bean>
<bean id="vendaFacade" class="com.systemhaus.examples.application.VendaFacade">
<constructor-arg ref="produtoDAO" />
<constructor-arg ref="gavetaDAO" />
<constructor-arg ref="operacaoDAO" />
<constructor-arg ref="estoque" />
</bean>
<bean id="notaFiscalFacade" class="com.systemhaus.examples.domain.NotaFiscalFacade">
<constructor-arg ref="produtoDAO" />
<constructor-arg ref="gavetaDAO" />
<constructor-arg ref="operacaoDAO" />
<constructor-arg ref="notaFiscalDAO" />
<constructor-arg ref="estoque" />
</bean>
<bean id="estoque" class="com.systemhaus.examples.domain.Estoque">
<constructor-arg ref="estoqueRepositoryDB" />
</bean>
<bean id="estoqueRepositoryDB"
class="com.systemhaus.examples.infraestructure.EstoqueRepositoryDB">
<constructor-arg ref="gavetaDAO" />
<constructor-arg ref="produtoDAO" />
<constructor-arg ref="operacaoDAO" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:/home/pauloprass/eclipse-workspace/Java_Spring_Examples/lib/databaseEstoque" />
<property name="username" value="Paulo" />
<property name="password" value="1" />
</bean>
</beans>
And this is my method:
private EntityManagerFactory emf;
#PersistenceUnit
public void setEntityManagerFactory(EntityManagerFactory emf) {
this.emf = emf;
}
#Override
#Transactional
public void saveGaveta(Gaveta gaveta) {
EntityManager em = emf.createEntityManager();
em.persist(gaveta);
em.flush();
}
I was able to solve my problem, it happens that it was a first time I created a Maven project. So I had made the imports of the JARs that were in my lib, but I was using a pom.xml, and even if I was changing my pom.xml dependencies he was using the classes imported from my lib, well, mine solution was to clean up what was compiled and remove all JARS from the lib and add the dependencies in pom.xml.
I am using Spring 3.2 mvc and Hibernate 4 in my project.
hibernate.cfg.xml
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.autocommit">true</property>
<property name="show_sql">true</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<property name="hibernate.validator.apply_to_ddl">false</property>
<property name="hibernate.validator.autoregister_listeners">false</property>
servlet-context.xml
<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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<security:global-method-security pre-post-annotations="enabled"/>
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<context:annotation-config />
<context:component-scan base-package="com.abc" />
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
</beans:beans>
DaoImpl Class:
public void add(Entity entity) {
try {
this.sessionFactory.getCurrentSession().save(entity);
this.sessionFactory.getCurrentSession().flush();
} catch (Exception e) {
logger.error("Exception occured " + e);
}
}
This is my project configuration and dao impl class file.
root-context.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:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!-- <tx:annotation-driven transaction-manager="transactionManager" /> -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:component-scan base-package="com.abc" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<!-- <property name = "dataSource" ref = "dataSource"></property> -->
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="entityInterceptor" ref ="auditLogInterceptor"/>
</bean>
Issue
As of now in hibernate.cfg.xml, I have mentioned hibernate.connection.autocommit = true and in daoimpl while saving entity I need to call flush after .save .
If I remove hibernate.connection.autocommit = true and .flush from daoimpl class, I observed that .save method in daoimpl is not working, means my data is not inserting and even I cannot see insert query executed by hibernate on console.
hibernate.connection.autocommit = true should not be there in hibernate cfg xml as if I doing operation on multiple table in same transaction and if some error occurred then rollback will not happen.
I want that .save in daoimpl should work even I don't write hibernate.connection.autocommit = true in hibernate cfg xml and .flush.
I am using #Transactional annotation for transaction.
You haven't added any TransactionManager to your configuration:
Remove the following properties:
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.autocommit">true</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
Add a connection pooling DataSource (DBCP2 is a much better alternative than C3P0)
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="your-oracle-driver-url"/>
<property name="username" value="your-username"/>
<property name="password" value="your-password"/>
</bean>
Now add the Sessionfactory Spring proxy:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
</bean>
Add the TransactionManager bean
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="dataSource" ref="dataSource" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Update
If you have the transaction manager set in a separate spring application context (e.g. root-context.xml), then move these lines from your web context to where the back-end context:
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:component-scan base-package="com.abc.service" />
<context:component-scan base-package="com.abc.dao" />
And only allow the web context to scan its own beans:
<context:component-scan base-package="com.abc.web" />
It's not good to mix the web and the back-end contexts responsibilities.
My problem solved, I just wrote the annotation #Transactional in the
#Repository
#Transactional
public class AbstractHibernateDao<T extends Serializable> {
private Class<T> clazz;
#Autowired
private SessionFactory sessionFactory;
And that solved that I couldnt Delete or Save without using Flush.
I create the configuration of Spring + JPA/Hibernate/c3p0 on this way:
Spring-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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<context:component-scan base-package="com.nassoft.erpweb"/>
<mvc:resources mapping="/resources/**" location="/WEB-INF/resources/" />
<mvc:annotation-driven />
<mvc:interceptors>
<bean class="com.nassoft.erpweb.login.interceptor.AuthenticatorInterceptor" />
</mvc:interceptors>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="packagesToScan" value="com.nassoft.erpweb.*" />
<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.MySQL5Dialect</prop>
</props>
</property>
</bean>
<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/nsm_erp" />
<property name="user" value="root" />
<property name="password" value="1234" />
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="20" />
<property name="maxStatements" value="50" />
<property name="idleConnectionTestPeriod" value="3000" />
<property name="loginTimeout" value="300" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven />
<bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
</beans>
I'm not using persistence.xml because I read in some places its not necessary in Spring 4 with Hibernate.
When I start the server it still loading and don't start in 45s (nor 180s) in Tomcat7.
I create a factory of EntityManager to use in my project:
package com.nassoft.erpweb.factory;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceUnit;
public class ConnectionFactory {
#PersistenceUnit
private static EntityManagerFactory entityManagerFactory;
public static EntityManager getEntityManager(){
if (entityManagerFactory == null){
entityManagerFactory = Persistence.createEntityManagerFactory("ERPWeb");
}
return entityManagerFactory.createEntityManager();
}
}
I think my configuration is not correct, but I don't found any places with a good text about it.
Can someone help-me?
Edited.
Problem solved!
First: I applied Dependency Injection in each controller to bring the DAOs with IoC.
Second: I use the annotation #Repository to create a repository in each DAO that will receive my databases methods.
Third: I created the EntityManage in this way for each DAO:
#PersistenceContext
private EntityManager manager;
This is not a complete answer. I"m just pointing you to a direction.
Spring cannot find the ConnectionFactory class of yours, so it will not inject the entityManagerFactory. Its not required for you to again create a singleton for passing the entityManager, so no ConnectionFactory class is required. Spring will do it for you by injecting into the DAO or Controller etc., for example you have the following DAO that gets the data.
#Service
public class SomeDAO {
#AutoWire -- i'm not sure what you call for the entityManager.
private static EntityManagerFactory entityManagerFactory;
}
There is more info here. Instead of #autowiring he is using manual injection. I your case ,you can try with autowiring.
Also make sure that you have these classes in the <spring:component-scan /> path of the application context file or else the spring wont be able to recognize and inject the entity manager.