Статьи

Обновление Spring 3.x и Hibernate 3.x до Spring Platform 1.0.1 (Spring + hibernate 4.x)

Недавно я вызвался обновить наш новейший проект до последней версии Spring Platform. Spring Platform предоставляет вам управление зависимостями и плагинами во всем наборе библиотек Spring Framework.

Так как мы немного отстали, апгрейд поднял немного веселья. Вот вещи, с которыми я столкнулся:

Maven:

Наши файлы pom все еще ссылались на:
hibernate.jar
ehcache.jar

Эти артефакты не выходят из последней версии, поэтому замените их на hibernate-core.jar и ehcache-core.jar .

Мы также все еще используем плагин hibernate tools + maven run для обратной разработки нашего объекта db. Это мне нужно было обновить до версии кандидата:

1
<hibernate-tools .version="">4.3.1.CR1</hibernate-tools>

Hibernate:

Код: «Hibernate.createBlob»… больше не существует

заменено на:

1
2
3
private Blob createBlob(final byte[] bytes) {
return NonContextualLobCreator.INSTANCE.wrap(NonContextualLobCreator.INSTANCE.createBlob(bytes));
}

В HibernateTemplate теперь возвращаются типы возврата List; не элемент … Поэтому необходимо добавить приведение к спискам, которые будут возвращены.

1
import org.hibernate.classic.Session;

заменено на:

1
import org.hibernate.Session;

Обратный инженер работает немного по-другому…
Назначает Long числовому …
Добавлено:

1
2
3
4
5
6
7
8
9
<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>

Возможные ошибки:

  • Причина: org.hibernate.service.UnknownUnwrapTypeException: Невозможно развернуть запрошенный тип [javax.sql.DataSource]

Добавьте зависимость для c3p0:

1
2
3
4
5
<dependency>
 <groupid>org.hibernate</groupId>
 <artifactid>hibernate-c3p0</artifactId>
 <version>${hibernate.version}</version>
</dependency>

И настройте параметры в cfg.xml для этого:

1
2
3
4
5
<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>
  • Вызывается: java.lang.ClassNotFoundException: org.hibernate.engine.FilterDefinition

Вероятно, все еще где-то используется ссылка на hibernate3 factory / bean, замените на hibernate4:

1
2
org.springframework.orm.hibernate3.LocalSessionFactoryBean
org.springframework.orm.hibernate3.HibernateTransactionManager
  • Причина: java.lang.ClassNotFoundException: Не удалось загрузить запрошенный класс: org.hibernate.hql.classic.ClassicQueryTranslatorFactory. В новых API есть незначительное изменение, поэтому это можно исправить, заменив значение свойства на:
1
org.hibernate.hql.<b>internal</b>.classic.ClassicQueryTranslatorFactory.

Весна:

Удивительно, что некоторые из наших файлов контекста приложения все еще ссылаются на Spring DTD… заменены на XSD:

Весной добавлены конфиги для c3p0:

1
2
3
4
5
<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 удалил «local» =: так что нужно просто изменить это на «ref» =

Spring HibernateDaoSupport больше не имеет: «releaseSession (session);», что хорошо, поэтому он был вынужден обновить код для работы внутри транзакции.

Возможные ошибки:

  • getFlushMode недействителен без активной транзакции; Вложенное исключение — org.hibernate.HibernateException: getFlushMode недопустим без активной транзакции.

Удалено из свойств спящего режима:

1
<prop key="hibernate.current_session_context_class">thread</prop>

Предоставьте собственную стратегию для определения объема «текущей» Session . См. Раздел 2.5, «Контекстные сессии» для получения дополнительной информации о встроенных стратегиях.

  • org.springframework.dao.InvalidDataAccessApiUsageException: операции записи не разрешены в режиме только для чтения (FlushMode.MANUAL): превратите ваш сеанс в FlushMode.COMMIT / AUTO или удалите маркер readOnly из определения транзакции.

Другой вариант:

1
2
3
4
<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

Обновление версии сервлета:

1
2
3
4
5
<dependency>
 <groupid>javax.servlet</groupId>
 <artifactid>servlet-api</artifactId>
 <version>3.0.1</version>
</dependency>
  • Затем развертывание на weblogic javassist: $$ _ javassist_ не может быть преобразован в javassist.util.proxy.Proxy

Проблема здесь заключалась в том, что были разные версии javassist, которые вводили в ухо. Я удалил все ссылки со всех наших poms, так что вернулась верная версия из Spring / Hibernate…

а затем настроил weblogic, чтобы предпочесть нашу версию:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<?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>