1

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.

Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
VJS
  • 2,891
  • 7
  • 38
  • 70
  • Does it return any error message/exception.Which mode you are running hibernate on i.e create or update – Madusudanan Dec 02 '14 at 11:28
  • Check if you have a active transaction and if is generating any sql – André Dec 02 '14 at 11:29
  • @Madusudanan : no exception coming on console. – VJS Dec 02 '14 at 12:18
  • @ André : show sql is true but no insert query is visible in console. – VJS Dec 02 '14 at 12:18
  • @VJS Have you switched to Hibernate 4 recently? And is your entity correctly configured? – Lyrion Dec 02 '14 at 12:22
  • @Lyrion : its a new project and using hibernate 4 only. (currently I have only 1 entity ) Entity is currently configured as when auto.commit=true is there in hibernate cfg xml and flush is there after save in daoimpl then its working fine. – VJS Dec 02 '14 at 12:26
  • @VJS The reason I was asking is because we switched from hibernate 3 to 4 recently, and stuff that worked then didn't work after the switch, like saving. But this was because the entity itself was badly configured, meaning for example nullable was said to false when it was true ect... It didn't give any errors, only when JUnit ran the tests – Lyrion Dec 02 '14 at 12:29

2 Answers2

2

You haven't added any TransactionManager to your configuration:

  1. 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>
    
  2. 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>
    
  3. 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>
    
  4. 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.

Community
  • 1
  • 1
Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
  • I didn't mention root-context.xml, in this 3 and 4 point configuration is present. Even then also hibernate is not executing insert query. I am not getting any exception as well. It seems like it just ignoring save. – VJS Dec 02 '14 at 12:17
  • @ Vlad Mihalcea : Thanks. I got that somewhere solution to my problem is related to component scan. From your answer,it seems like service and dao package needs to mention in root-context.xml and controller package needs to mention in servlet-context.xml. My confusion is : 1) Entity package is also there 2) In service layer, we are doing spring autowiring for dao classes.If i mention service package in root-context.xml then how spring autowiring annotation will scan. – VJS Dec 02 '14 at 17:37
  • Entities shouldn't be scanned and should be available to both core and web. The service bean from one context can still be available in the web context. – Vlad Mihalcea Dec 02 '14 at 18:41
0

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.

diego matos - keke
  • 2,099
  • 1
  • 20
  • 11