升级原因
- 我司目前的架构是11年左右的架构,目前时间过于久远,且最初的架构人员也已离职。
- jdk8从发布到现在也有不少时间了,已经趋于稳定,且提供了很多新特性。
- 目前我司准备新起产品线,准备用最新的一些技术,但是老产品的业务功能也不能丢,所以准备给老产品集成Dobbo。以前技术太老,不方便这些组件的扩展。
升级步骤
各种删除,各种替换,这个不多说,说一下注意的点:
- 一定要引入:classmate.jar,不然会有奇怪的错(没记录了,就不好贴异常栈了)。
- javassist.jar 如果版本太低,建议升级,否则也会出错
- jboss-logging.jar 也需要引入,spring3不需要
- 我用到了redis,所以jedis.jar也顺便升了个级
- 记得把引入org.springframework.orm.hibernate3下面类的地方都改为:org.springframework.orm.hibernate4
以上相关jar包我都没放版本号,版本请根据自己的spring、hibernate的版本进行下载,maven请无视
升级过程中的坑
-
jbpm3错误:java.lang.AbstractMethodError: at UserType.nullSafeSet()
这个问题坑了我不少时间,最后才发现是因为hibernate更新了接口. spring3接口:
public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws HibernateException, SQLExceptionspring4的接口:
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException可以发现多了个参数。jbpm3实现该方法的类是:
org.jbpm.db.hibernate.ConverterEnumType我们重写一下它:
public class ConverterEnumType implements UserType { // 这是spring4的 @Override public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException { return nullSafeGet(rs,names,owner); } // 这是spring4的 @Override public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException { nullSafeSet(st,value,index); } public Object deepCopy(Object o) throws HibernateException { return o; } public boolean isMutable() { return false; } public Serializable disassemble(Object o) throws HibernateException { return (Serializable) o; } public Object assemble(Serializable s, Object o) throws HibernateException { return s; } public Object replace(Object original, Object target, Object owner) { return target; } public int[] sqlTypes() { return SQLTYPES; } public Class returnedClass() { return Converter.class; } // spring3的 public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException { String converterDatabaseId = resultSet.getString(names[0]); return Converters.getConverterByDatabaseId(converterDatabaseId); } // spring3的 public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws HibernateException, SQLException { String converterDatabaseId = Converters.getConverterId((Converter) value); preparedStatement.setString(index, converterDatabaseId); } } -
jbpm3的错误:java.lang.NoSuchMethodError: org.hibernate.SessionFactory.openSession()Lorg/hibernate/classic/Session
这个问题和上面那个问题一样,都是属于hibernate更改了接口,所以我们只需要找到对应的类,重写一下。调用该方法的位置在:
org.jbpm.persistence.db.DbPersistenceService#getSession我们来重写一下:
public class DbPersistenceService implements Service, PersistenceService { public Session getSession() { if ( (session==null) && (getSessionFactory()!=null) ) { Connection connection = getConnection(false); if (isCurrentSessionEnabled) { log.debug("using current hibernate session"); session = getSessionFactory().getCurrentSession(); mustSessionBeClosed = false; mustSessionBeFlushed = false; mustConnectionBeClosed = false; } else if (connection!=null) { log.debug("creating hibernate session with connection "+connection); // hibernate4直接就写openSession(),不过可能会造成资源浪费 session = getSessionFactory().openSession(); // hibernate3这里可以传一个connection //session = getSessionFactory().openSession(connection); mustSessionBeClosed = true; mustSessionBeFlushed = true; mustConnectionBeClosed = false; } else { log.debug("creating hibernate session"); session = getSessionFactory().openSession(); mustSessionBeClosed = true; mustSessionBeFlushed = true; mustConnectionBeClosed = false; } if (isTransactionEnabled) { beginTransaction(); } } return session; } }
总结
现在还在测试,中途还有很多之前基于spring3做的一些开发需要调整,反正都是坑,
续
- openSession的问题好似有一个更优雅的解决方式
// 还是像spring3一样,根据连接创建session
session = getSessionFactory().withOptions().connection(connection).openSession();