0

I have Netbeans+Hibernate4.3.x(JPA2.1)+Spring Framework 4.0.1. I have problem when writing/updating into MySql db with HibernateTemplate:

org.springframework.dao.InvalidDataAccessApiUsageException:
Write operations are not allowed in read-only mode (FlushMode.MANUAL):
Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition. 

As suggested in: solution0, solution1, solution2, I tried to config TransactionManager in my xml configuration (and adding @Transactional in my dao class). However error is still there.

Setting

hibernateTemplate.setCheckWriteOperations(false)

(suggested in solution3)does not help, hibernate does not write to db in this case. Please, help a poor student to resolve it.

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:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    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/tx
   http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">


<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName"  value="com.mysql.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://localhost:3306/ADMISSION"></property>
    <property name="username" value="root"></property>
    <property name="password" value="1234"></property>
</bean>

<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="mysessionFactory" /> 
</bean> 

<bean id="mysessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>

    <property name="mappingResources">
        <list>
            <value>beans/Course.hbm.xml</value>
            <value>beans/Student.hbm.xml</value>
            <value>beans/Result.hbm.xml</value>
        </list>
    </property>

    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>


<bean id="template" class="org.springframework.orm.hibernate4.HibernateTemplate">
    <property name="sessionFactory" ref="mysessionFactory"></property>
</bean>

<bean id="dao" class="dao.HibernateTemplateDao">
    <property name="template" ref="template"></property>
</bean>

dao:

package dao;
import beans.Course;
import java.util.*;
import org.springframework.orm.hibernate4.HibernateTemplate;
import beans.Item;
import beans.Result;
import beans.Student;
import org.hibernate.FlushMode;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

// @Transactional // not working
// @Transactional(readOnly = false) //not working either
@Transactional(propagation = Propagation.REQUIRED, readOnly = false) //same error
public class HibernateTemplateDao implements Dao{
   private HibernateTemplate template;

   public void setTemplate(HibernateTemplate template){
       this.template=template;
       //template.setCheckWriteOperations(false); // write is not working
       //template.getSessionFactory().getCurrentSession().setFlushMode(FlushMode.AUTO); EXC no session in current thread
   }

   public HibernateTemplate getTemplate(){
       return template;
    }

   //CRUD operations

   public List getAll (String tabName){
       if(tabName.equalsIgnoreCase("Student"))
           return template.loadAll(Student.class);
       if(tabName.equalsIgnoreCase("Course"))
           return template.loadAll(Course.class);
       if(tabName.equalsIgnoreCase("Result"))
           return template.loadAll(Result.class);
       return null;
   }

   public List getId (Item item){

       List l = new ArrayList();
       Item i = null;
       if(item.getClass().getSimpleName().equalsIgnoreCase("Student"))
           i = template.get(Student.class, item.getId());
       if(item.getClass().getSimpleName().equalsIgnoreCase("Course"))
           i = template.get(Course.class, item.getId());
       if(item.getClass().getSimpleName().equalsIgnoreCase("Result"))
           i = template.get(Result.class, item.getId());

       l.add(i);
       return l;
   } 


   public int save (Item item){
       template.save(item);
       return 1;
   }


   public int update (Item item){
      template.persist(item);
       return 1;
   }


   public int delete (Item item){
       template.delete(item);
       return 1;
   }

}
Community
  • 1
  • 1
Oleksa
  • 1
  • 3
  • The error suggest your transaction management isn't setup properly. You actually shouldn't be using the `HibernateTemplate` anymore (not since hibernate 3.0.1 that is) but use the plain `SessionFactory` and `getCurrentSession` instead of the template. Write plain hibernate daos instead of relying on Spring. Only use spring for injection and driving your transactions. – M. Deinum Sep 10 '16 at 06:26
  • @M.Deinum: i already have a dao implementation with manually handled hibernate transactions. I thought there should be possibility still for HibernateTemplate implementation. – Oleksa Sep 11 '16 at 03:48
  • You can but you shouldn't, as it isn't recommended to use anymore nor does it add anything for hibernate versions after 3.0.1. – M. Deinum Sep 12 '16 at 06:19

0 Answers0