Hibernate saving entity not working

Refresh

March 2019

Views

786 time

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.

VJS

2 answers

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.

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.