1

We are upgrading our project from Hibernate 3.6.10 to Hibernate 5.2.0 but getting errors while migrating. I have gone through many posts here on StackOverFlow and Google but did not found any solution.

Consider the code reference this website. I only made the database connections are to PostgreSQL database.

If I run this sample after adding these JARs (ALL Added JAR files screenshot) except the hibernate JAR is 3.6.10-final, It works totally fine. But if I make these changes for hibernate 5 upgrade:

  1. Changing JAR file added as Hibernate-core-5.2.1-Final.jar
  2. Changing reference of hibernate3 files to hibernate5(3 replacements; 1 in EmployeeDao import and another 2 in applicationContext.xml)

It throws the following error:

Exception in thread "main" 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.
at org.springframework.orm.hibernate5.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1132)
at org.springframework.orm.hibernate5.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:618)
at org.springframework.orm.hibernate5.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:615)
at org.springframework.orm.hibernate5.HibernateTemplate.doExecute(HibernateTemplate.java:340)
at org.springframework.orm.hibernate5.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:307)
at org.springframework.orm.hibernate5.HibernateTemplate.save(HibernateTemplate.java:615)
at hibernate.test.EmployeeDao.saveEmployee(EmployeeDao.java:12)
at hibernate.test.InsertTest.main(InsertTest.java:21)

And I made these changes as well but got the same error: 1. Commenting this in EmployeeDao:

/*HibernateTemplate template;  

public void setTemplate(HibernateTemplate template) {  
    this.template = template;  
}  */

and extending HibernateDaoSupport, so that it gives sessionFactory setter.

And replacing below code to:

public void saveEmployee(Employee e){  
    template.save(e);  
} 

this:

public void saveEmployee(Employee e){  
      this.getHibernateTemplate().save(e);
}  

After debugging I came to know that in HibernateTemplate class provided by Spring-orm-4.3.1 Jar is throwing the mentioned error.

Here is the snapshot.

Can anyone help me out with this :O. We have stuck here for ages. I appreciate help.

Vladimir Vagaytsev
  • 2,871
  • 9
  • 33
  • 36
  • Links to the reference above: or pic 2- http://i.stack.imgur.com/NwPwl.png for pic 3- http://i.stack.imgur.com/Zgx5d.png – RPA Consultant Jul 12 '16 at 07:16
  • First of all, I would discourage to use `HibernateTemplate`. Refer this question http://stackoverflow.com/questions/4067775/spring-hibernate-template-when-to-use-and-why . Read the Accepted answer. You've to migrate from HibernateTemplate to SessionFactory and declarative transaction management. – The Coder Jul 12 '16 at 08:00
  • @TheCoder Thanks for your reply. Here in out project, it is so huge and any new implementation can take much time. I have gone through the mentioned thread and they say that it is removed from Spring? but I am using via importing `org.springframework.orm.hibernate5.HibernateTemplate`. Anyways, please answer the above question if possible, that is all I need. Thanks. – RPA Consultant Jul 12 '16 at 09:20
  • 1
    You shouldn't be using `HibernateTemplate` anymore, it is only there for migration purpose to a plain `SessionFactory`. The old session factory did obtain a session itself when one wasn't found, the new version requires proper transaction setup as it uses `getCurrentSession` underneath. – M. Deinum Jul 12 '16 at 09:27
  • @Harpreet, I understand. But the point is, you're migrating from `Hibernate 3.6.10 -> Hibernate 5.2.0`. So you also have to migrate most of the code as per needed to work with latest hibernate version. If you worry about doing a lot of changes and just want to stick with current code, there is no point to just upgrade the version but not utilising any of the new features (SessionFactory, Declarative Transaction Management etc..). No Offense..! – The Coder Jul 12 '16 at 10:14
  • @M.Deinum Thanks but as this is a huge project based on it, we can't take a call directly. We will for sure once I understand all the changes required. **1. Can you please let me know how many changes it will demand? 2. _getCurrentSession_ was not a problem in Hibernate3, but is a prob in Hibernate5?** I don't get it and I don't get any reference or any lead to this problem. Is it like none faced this problem :O – RPA Consultant Jul 13 '16 at 11:13
  • @TheCoder Yeah, I get that, Can you please give me any reference where I can merge/upgrade basically migrate my code to get the **new features (SessionFactory, Declarative Transaction Management etc..)**. I don't get it either on the net. – RPA Consultant Jul 13 '16 at 11:16
  • For older hibernate versions there where ugly hacks/workaround to integrate with hibernate and make usage over different versions consistent. However those hacks aren't needed anymore and as such removed. Next to that the `HIbernateTemplate` isn't the `HibernateTemplate` you are used to, it is merely a thin wrapper instead of what it was. As stated you need to do proper transaction setup which I suspect you haven't nor ever had. – M. Deinum Jul 13 '16 at 11:19
  • @M.Deinum Yes, you are right. What I have gone so far here is Transaction configuration is required. I tried setting that in my project but that seems failing too. [This link](http://stackoverflow.com/questions/29618259/spring-hibernate-integration-throws-getflushmode-is-not-valid-without-active-tra) solved my POC above but the problem is this Declarative Transaction Management setting is not configured for whole project. I don't know how to cross cut the concerns for whole project? Like the code in link `expression="execution(* com.examples.service.PersonService.*(..))"`. – RPA Consultant Jul 13 '16 at 11:26
  • Just write the correct expression that matches all your services. – M. Deinum Jul 13 '16 at 11:32
  • Okay. I am working on that. Thanks. @M.Deinum – RPA Consultant Jul 13 '16 at 11:41
  • How did u need it? Java based configuration or XML based configuration? – The Coder Jul 13 '16 at 20:42
  • My project is having HBM xml files. No java based configuration yet. We have a plan to upgrade that as well. @M.Deinum – RPA Consultant Jul 14 '16 at 07:05

1 Answers1

0

create DataSource.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">  

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location">
        <value>classpath:properties/database.properties</value>
    </property>
</bean>

<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>

create sessionFactory using the a seperate hibernate.xml file as given 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: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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">  

<!-- Hibernate session factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">

    <property name="dataSource">
      <ref bean="dataSource"/>
    </property>

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

    <property name="annotatedClasses">
    <list>
        <value>com.rapidtech.rapidtechorganic.model.Lot</value>
        <value>com.rapidtech.rapidtechorganic.model.ProductAvailable</value>
        <value>com.rapidtech.rapidtechorganic.model.Client</value>
        <value>com.rapidtech.rapidtechorganic.model.Invoice</value>
        <value>com.rapidtech.rapidtechorganic.model.ProductBuyed</value>
    </list>
    </property>

</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

Include both the xml file in your servel-context.xml

<!-- Database Configuration -->
<beans:import resource="classpath:database/DataSource.xml"/>
<beans:import resource="classpath:database/Hibernate.xml"/>

Then in your Abstract class inject sessionFactory

@Resource
private SessionFactory sessionFactory;
public void save(Entity entity){
   Session session = sessionFactory.openSession();
   session.beginTransaction();
   session.save(entity);
   session.getTransaction().commit();
   session.close();
}
tinku
  • 331
  • 4
  • 14
  • Thanks for your answer, You don't actually have to post the whole code, I have checked this already. What needed was to **modify Sample code** to create openSession, that is what you are actually doing but that was not the expected answer. HibernateTemplate throws errors on line `session = getSessionFactory().getCurrentSession();` in doExecute method, which means any configuration problem. – RPA Consultant Jul 12 '16 at 09:28
  • Actually I am using hibernate 5 and spring 4. Earlier I was facing this same problem but after changing it to the code that I posted here everything is going fine. – tinku Jul 12 '16 at 09:34
  • make sure that in your classpath you have hibernate-entitymanager jar file – tinku Jul 12 '16 at 09:42
  • Thanks @Tinku. Yes, I understand that. So I actually told you the solution which works with me, but it is not considered as solution by all. Configuration needs to be updated. – RPA Consultant Jul 12 '16 at 09:43