Hibernate + JodaTime отображает разные типы

Я использую обратный инжиниринг в спящем режиме и пытаюсь сопоставить свои временные метки с типом JodaTime.

Я правильно настроил файл hibernate.reveng.xml

<sql-type jdbc-type="TIMESTAMP" hibernate-type="org.joda.time.contrib.hibernate.PersistentDateTime" not-null="true"></sql-type>

Проблема в том, что когда я запускаю процесс rev-eng, мои классы Java также получают элементы, созданные как объекты PersistentDateTime, но я этого не хочу, потому что они непригодны для использования. Мне нужно, чтобы объекты Java были org.joda.time.DateTime

Поэтому я попытался создать собственную инженерную стратегию

public class C3CustomRevEngStrategy extends DelegatingReverseEngineeringStrategy {

public C3CustomRevEngStrategy(ReverseEngineeringStrategy res) {
    super(res);
}

public String columnToHibernateTypeName(TableIdentifier table, String columnName, int sqlType, int length, int precision, int scale, boolean nullable, boolean generatedIdentifier) {
    if(sqlType==Types.TIMESTAMP) {
        return "org.joda.time.DateTime";
    }    else {
        return super.columnToHibernateTypeName(table, columnName, sqlType, length, precision, scale, nullable, generatedIdentifier);
    }
}

}

Я думал, что файлы отображения гибернации получат настройки файла hibernate.reveng.xml, а объекты Java получат настройки из файла пользовательской стратегии... но это не так. И файл сопоставления, и объект имеют тип «org.joda.time.DateTime», что мне не нужно.

Как я могу достичь своей цели? Кроме того, я НЕ использую аннотации.

  • Спящий режим 3.6
  • ДжодаТайм 2.3
  • JodaTime-Спящий режим 1.3

Спасибо

РЕДАКТИРОВАТЬ: Чтобы точно уточнить, в чем проблема

После обратного проектирования это то, что я получаю в своем файле сопоставления и классе POJO.

<property name="timestamp" type="org.joda.time.contrib.hibernate.PersistentDateTime">
private PersistentDateTime timestamp;

Как свойство POJO, PersistentDateTime бесполезен для меня, поскольку я не могу ничего с ним делать, например, манипулировать временем или что-то еще. Итак, это то, что я хочу после реверс-инжиниринга

<property name="timestamp" type="org.joda.time.contrib.hibernate.PersistentDateTime">
private org.joda.time.DateTime timestamp;

Использование библиотеки Jidira, как предлагается ниже, дает мне тот же результат, POJO, который я не могу использовать.


person Raymond Holguin    schedule 02.06.2014    source источник
comment
Если мой ответ не решит вашу проблему, дайте мне знать. Это может просто потребовать небольшой настройки   -  person JamesENL    schedule 03.06.2014


Ответы (2)


Библиотека JodaTime-Hibernate устарела и, вероятно, является источником вашей проблемы. Однако не отчаивайтесь, поскольку есть (лучшая) альтернатива.

Вам нужно будет использовать библиотеку JadiraTypes для создания правильных объектов JodaTime из Hibernate. Добавьте библиотеку которую можно найти здесь в путь к классам вашего проекта, а затем измените тип на org.jadira.usertype.dateandtime.joda.PersistantDateTime. Все объекты JodaTime имеют соответствующее сопоставление в этом пакете, поэтому, если вы решите перейти на другой объект, просто обновите свой тип.

Это должно гарантировать, что ваши объекты будут созданы правильно.

Я должен добавить к своему ответу предостережение: я никогда не использовал библиотеку JadiraTypes с Hibernate 3. Если она поддерживает только Hibernate 4 (я не понимаю, почему это так, но...), дайте мне знать, и я удалю свой ответ.

person JamesENL    schedule 03.06.2014
comment
К сожалению, я все еще нахожусь на квадрате 1. У меня та же проблема, что после обратного проектирования мой тип файла сопоставления и тип POJO совпадают. Мне нужно, чтобы мой файл сопоставления имел тип PersistentDateTime, а мой тип POJO — DateTime. Наличие POJO PersistentDateTime бесполезно для программирования, потому что вы ничего не можете с ним сделать. Невозможно делать какие-либо манипуляции с датами или что-то еще с ним. Возможно, я не совсем понял, чего хотел, поэтому обновлю нижнюю часть поста примером. Я ценю вашу помощь, хотя - person Raymond Holguin; 03.06.2014
comment
Есть ли что-то, что мешает вам просто обновить экземпляры в вашем фактическом POJO после завершения обратного проектирования? - person JamesENL; 04.06.2014
comment
В настоящее время это то, что я делаю, но я ищу удобства. Тем более, что этот проект все еще находится на начальной стадии, поэтому изменения требований и обновления БД происходят довольно часто. Так что, если есть способ встроить это в процесс реинжиниринга, я надеялся узнать, как сделать жизнь проще. - person Raymond Holguin; 04.06.2014
comment
Мне кажется, что расширение класса DelegatingReverseEngineeringStrategy, как я делал в своем OP, - это путь. Каким-то образом разделите процессы, которые генерируют файл POJO и Mapping, чтобы я мог делать некоторые пользовательские объявления, я только сейчас понял, как это сделать. - person Raymond Holguin; 04.06.2014

Инструменты Hibernate, похоже, не отделяют типы Hibernate от типов Java. Если бы вы использовали аннотации, это было бы более понятно, так как в этом случае вам понадобится аннотация @Type, которую Hibernate вообще не будет генерировать. Поэтому использование открытых API здесь не поможет.

К счастью, Hibernate позволяет подключиться к фактическому созданию кода (или XML) после его обработки. Вы можете сделать это, заменив шаблоны Freemarker, которые он использует для генерации кода XML и Java. Однако вам нужно будет использовать Ant для реверс-инжиниринга.

Чтобы начать использовать Ant для этой цели (если вы еще этого не делаете), вы можете либо загрузить Hibernate Tools в качестве зависимости во время сборки с помощью вашего менеджера зависимостей, либо загрузить JAR. Поместите банку в путь к классам Ant, но также извлеките из нее файлы шаблонов: поскольку вы используете конфигурацию XML, вас будет интересовать каталог /hbm. Затем добавьте задачу с помощью <taskdef> и, предполагая, что вы извлекли шаблоны в TPL_PATH/hbm/*.ftl, вызовите ее с помощью <hibernatetool templatepath="TPL_PATH" ...>. (Для получения дополнительной информации см. Ниже ссылку на документы). Использование Ant также помогает в автоматизации, например, на серверах CI, где у вас не будет Eclipse.

Вы захотите сохранить hibernate-type="org.joda.time.DateTime" в своем hibernate.reveng.xml, чтобы файлы Java генерировались правильно, но замените его на org.joda.time.contrib.hibernate.PersistentDateTime в сгенерированном XML. Для этого отредактируйте TPL_PATH/hbm/property.hbm.ftl, замените ${property.value.typeName} на ${javaType} и присвойте javaType правильное значение перед его использованием:

<#assign javaType=property.value.typeName>
<#if javaType.equals("DateTime")>
<#assign javaType="org.jadira.usertype.dateandtime.joda.PersistentDateTime">
</#if>
<property
    name="${property.name}"
    type="${javaType}"
...

Возможно, вы захотите удалить символы новой строки, чтобы сгенерированный XML оставался чистым.

Все это описано в документации по Hibernate Tools по адресу http://docs.jboss.org/tools/archive/3.2.1.GA/en/hibernatetools/html/codegen.html#d0e6349, за исключением того, что в документации не указано, какой именно шаблоны, которые вам нужно изменить, вам нужно понять это, прочитав шаблоны.

person Silviu Julean    schedule 24.07.2014