Hibernate + JodaTime映射不同的类型

时间:2014-06-02 17:53:48

标签: java hibernate reverse-engineering jodatime hibernate-tools

我正在使用hibernate逆向工程并尝试将我的Timestamps映射到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映射文件将获得hibernate.reveng.xml文件设置,java对象将从自定义策略文件中获取设置......但事实并非如此。映射文件和Object都是“org.joda.time.DateTime”类型,这不是我想要的。

我如何实现目标?另外,我没有使用注释。

  • Hibernate 3.6
  • JodaTime 2.3
  • JodaTime-Hibernate 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。

2 个答案:

答案 0 :(得分:1)

JodaTime-Hibernate库已被弃用,可能是您问题的根源。不要因为有(更好的)替代品而感到绝望。

您需要使用JadiraTypes库从Hibernate创建正确的JodaTime对象。将库which can be found here添加到项目类路径中,然后将类型更改为org.jadira.usertype.dateandtime.joda.PersistantDateTime。所有JodaTime对象在该包中都有相应的映射,因此如果您决定更改为另一个对象,则只需更新您的类型。

这应确保正确创建对象。

我应该在我的回答中添加一个警告,即我从未在Hibernate 3中使用JadiraTypes库。如果它只支持Hibernate 4(我不明白为什么会这样,但是......)让我知道我会删除我的答案。

答案 1 :(得分:0)

Hibernate Tools似乎没有将Hibernate类型与Java类型分开。如果您要使用注释,这将更加清晰,因为在这种情况下您需要一个@Type注释,Hibernate根本不会生成。所以使用暴露的API在这里没有帮助。

幸运的是,Hibernate允许您在进行处理之后插入实际代码(或XML)生成。您可以通过替换它用于生成XML和Java代码的Freemarker模板来实现。但是,您需要使用Ant进行逆向工程。

要开始为此目的使用Ant(如果您还没有这样做),您可以使用依赖管理器将Hibernate Tools作为构建时依赖项或下载JAR。将jar放在Ant的类路径中,但也从中提取模板文件:由于您使用的是XML配置,因此您对/hbm目录感兴趣。然后使用<taskdef>添加任务,假设您将模板解压缩到TPL_PATH/hbm/*.ftl,请使用<hibernatetool templatepath="TPL_PATH" ...>进行调用。 (有关详细信息,请参阅下面的文档链接)。使用Ant还有助于实现自动化,例如在您无法获得Eclipse的CI服务器上。

您希望将hibernate-type="org.joda.time.DateTime"保留在hibernate.reveng.xml中,以便正确生成Java文件,但在生成的XML中将其替换为org.joda.time.contrib.hibernate.PersistentDateTime。为此,请修改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清洁。

这一点在http://docs.jboss.org/tools/archive/3.2.1.GA/en/hibernatetools/html/codegen.html#d0e6349的Hibernate工具文档中有所描述 - 除了文档没有告诉您需要修改哪些模板之外,您需要通过阅读模板来解决这个问题。 / p>