Upgrading Spring 3.x and Hibernate 3.x to Spring Platform 1.0.1 (Spring + hibernate 4.x)
I recent volunteered to upgrade our newest project to the latest version of Spring Platform. What Spring Platform gives you is dependency & plugin management across the whole Spring framework’s set of libraries.
Since we had fallen behind a little the upgrade did raise some funnies. Here are the things I ran into:
Maven:
Our pom files were still referencing:
hibernate.jar
ehcache.jar
These artefacts don’t exit on the latest version, so replaced those with hibernate-core.jar and ehcache-core.jar.
We also still use the hibernate tools + maven run plugin to reverse engineer our db object. This I needed to update to a release candidate:
<hibernate-tools .version="">4.3.1.CR1</hibernate-tools>
Hibernate:
The code: “Hibernate.createBlob”… no longer exists
replaced with:
private Blob createBlob(final byte[] bytes) { return NonContextualLobCreator.INSTANCE.wrap(NonContextualLobCreator.INSTANCE.createBlob(bytes)); }
On the HibernateTemplate return types are now List; not element…So needed to add casts for the lists being returned.
import org.hibernate.classic.Session;
replaced with:
import org.hibernate.Session;
Reverse engineer works a little differently…
Assigns Long to numeric…
Added:
<type-mapping> <sql-type jdbc-type="NUMERIC" precision="4" hibernate-type="java.lang.Integer" /> <sql-type jdbc-type="NUMERIC" precision="6" hibernate-type="java.lang.Integer" /> <sql-type jdbc-type="NUMERIC" precision="8" hibernate-type="java.lang.Integer" /> <sql-type jdbc-type="NUMERIC" precision="10" hibernate-type="java.lang.Long" /> <sql-type jdbc-type="DECIMAL" precision='4' scale='0' hibernate-type="java.lang.Integer" not-null="true"/> <sql-type jdbc-type="DECIMAL" precision='6' scale='0' hibernate-type="java.lang.Integer" not-null="true"/> <sql-type jdbc-type="DATE" hibernate-type="java.util.Date"/> </type-mapping>
Possible Errors:
- Caused by: org.hibernate.service.UnknownUnwrapTypeException: Cannot unwrap to requested type [javax.sql.DataSource]
Add a dependency for c3p0:
<dependency> <groupid>org.hibernate</groupId> <artifactid>hibernate-c3p0</artifactId> <version>${hibernate.version}</version> </dependency>
And configure the settings in the cfg.xml for it:
<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>
- Caused by: java.lang.ClassNotFoundException: org.hibernate.engine.FilterDefinition
Probably still using a reference to hibernate3 factory / bean somewhere, change to hibernate4:
org.springframework.orm.hibernate3.LocalSessionFactoryBean org.springframework.orm.hibernate3.HibernateTransactionManager
- Caused by: java.lang.ClassNotFoundException: Could not load requested class : org.hibernate.hql.classic.ClassicQueryTranslatorFactory There is minor change in new APIs, so this can be resolved by replacing property value with:
org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory.
Spring:
Amazingly some of our application context files still referenced the Spring DTD … replaced with XSD:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
In Spring configs added for c3p0:
<prop key="hibernate.c3p0.min_size">5</prop> <prop key="hibernate.c3p0.max_size">20</prop> <prop key="hibernate.c3p0.timeout">300</prop> <prop key="hibernate.c3p0.max_statements">50</prop> <prop key="hibernate.c3p0.idle_test_period">3000</prop>
Spring removed the “local”=: so needed to just change that to “ref”=
Spring HibernateDaoSupport no longer has: “releaseSession(session);”, which is a good thing so was forced to update the code to work within a transaction.
Possible Errors:
- getFlushMode is not valid without active transaction; nested exception is org.hibernate.HibernateException: getFlushMode is not valid without active transaction
Removed from hibernate properties:
<prop key="hibernate.current_session_context_class">thread</prop>
Supply a custom strategy for the scoping of the “current”Session . See Section 2.5, “Contextual sessions” for more information about the built-in strategies |
- 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.
Another option is :
<bean id ="productHibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate"> <property name="sessionFactory" ref="productSessionFactory"/> <property name="checkWriteOperations" value="false"/> </bean>
- java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig
Servlet version update:
<dependency> <groupid>javax.servlet</groupId> <artifactid>servlet-api</artifactId> <version>3.0.1</version> </dependency>
- Then deploying on weblogic javassist: $$_javassist_ cannot be cast to javassist.util.proxy.Proxy
The issue here was that there were different versions of javassist being brought into the ear. I all references removed from all our poms, so that the correct version gets pulled in from from Spring/Hibernate…
and then configured weblogic to prefer our version:
<?xml version="1.0" encoding="UTF-8"?> <weblogic-application> <application-param> <param-name>webapp.encoding.default</param-name> <param-value>UTF-8</param-value> </application-param> <prefer-application-packages> <package-name>javax.jws.*</package-name> <package-name>org.apache.xerces.*</package-name> <package-name>org.apache.xalan.*</package-name> <package-name>org.apache.commons.net.*</package-name> <package-name>org.joda.*</package-name> <package-name>javassist.*</package-name> </prefer-application-packages> </weblogic-application>
Reference: | Upgrading Spring 3.x and Hibernate 3.x to Spring Platform 1.0.1 (Spring + hibernate 4.x) from our JCG partner Brian Du Preez at the Zen in the art of IT blog. |
Hi,
I just did the same kind of migration, I also removed [hibernate.current_session_context_class] but not sure why, I had a try-change-try approach and noticed that {absent} property looks (now?) like a distinct value, different from what was default [thread]. Do you know something more about this ?
Thanks