4

我是新来的冬眠,我很难过。在我的数据库中,我的表具有TIMESTAMP(6). 我使用的是 Netbeans 6.5.1,当我生成hibernate.reveng.xml,时hbm.xml filespojo files它会将列设置为Serializable. 这不是我所期望的,也不是我想要的。

我在hibernate论坛上找到了这篇文章,说要放置:

<sql-type jdbc-type="OTHER" hibernate-type="java.sql.Timestamp" />

hibernate.reveng.xml文件中。

在 Netbeans 中,您无法从该文件生成映射(它每次都会创建一个新映射),并且它似乎也无法从该文件重新生成它们(至少根据这个它被定为在版本 7 中可用)。

所以我想弄清楚该怎么做。我更倾向于相信我做错了什么,因为我对此并不陌生,而且对于其他人来说,这似乎是一个普遍的问题。

  • 那么我做错了什么?
  • 如果我没有做错任何事,我该如何解决这个问题?

我正在使用 Netbeans 6.5、Oracle 10G,而且我相信 Hibernate 3(它与我的 netbeans 一起提供)。

编辑:意思是说我发现了这个stackoverflow问题,但这确实是一个不同的问题。

更新: 我使用的 oracle jdbc 驱动程序(ojdbc14.jar)是 9.0.2.0.0 我现在也尝试过:

  • ojdbc14.jar 版本 10.2.0.4.0
  • ojdbc6.jar 版本 11.2.0.1.0
4

2 回答 2

2

我找到了解决这个问题的方法。问题本身似乎围绕着这样一个事实,即 Netbeans 6.5(以及到目前为止的更高版本)不允许您从现有hibernate.reveng.xml文件对数据库进行逆向工程。这将在版本 7 中提供。

我发现的解决方法是创建一个 ant 任务来重新创建hbm.xml和 pojo java 文件。我目前在进行清理和构建时会发生这种情况,但是我将尝试找到一种方法将其完全分开,因为它只需要在数据库架构更改时运行。

build.xml尽管您需要编辑文件,但要在进行清理和构建时完成此操作。

第一部分是您需要的库。所以添加:

<path id="toolslib">
        <path location="lib/hibernate-support/hibernate-tools.jar" />
        <path location="lib/hibernate-support/hibernate3.jar" />
        <path location="lib/hibernate-support/freemarker.jar" />
        <path location="lib/hibernate-support/jtidy-r938.jar" />
        <path location="lib/ojdbc14.jar" />
</path>

您的机器上应该已经有了 hibernate-tools.jar、hibernate3.jar 和 ojdbc14.jar 文件。所以只需改变他们的路径。freemaker.jar和jtidy -r938.jar需要下载,因为我没有这些。

在此下方,build.xml您需要添加:

<taskdef name="hibernatetool"
     classname="org.hibernate.tool.ant.HibernateToolTask"
     classpathref="toolslib">
    <classpath>
        <fileset dir="lib">
            <include name="**/*.jar"/>
        </fileset>
    </classpath>
</taskdef>

您需要的最后一部分是在清洁后部分运行的设置:

<target name="-post-clean">
        <delete dir="src/*Put the foler where your pojos and hbm.xml files are located*"/>
        <hibernatetool>
            <jdbcconfiguration
                configurationfile="src\hibernate.cfg.xml"
                packagename="*the package where you want them recreated*"
                revengfile="src\hibernate.reveng.xml"
                detectmanytomany="true"
            />
            <hbm2hbmxml destdir="src" />
            <hbm2java  destdir="src" />
        </hibernatetool>
</target>
  • 删除部分将删除现有的 hbm 和 pojo 文件,然后再重新创建它们。
  • configurationfile指向您的主配置文件。
  • 包名称是您希望在其中创建它们的点分隔包(com.stackoverflow.pojo例如)。
  • revengfile是创建 hbm 和 pojo 文件时使用的逆向工程 xml 文件。
  • hbm2hbmxml将创建hbm.xml您的表的文件。
  • hbm2java将创建您的表的 java pojo 文件。

现在要使 Oracle Timestamps 不是Serializable,请编辑hibernate.reveng.xml文件并添加:

<type-mapping>
        <sql-type jdbc-type="OTHER" hibernate-type="java.sql.Timestamp" />
</type-mapping>

就在模式选择标签之后。

所以一个干净的构建和时间戳不会java.sql.Timestamp代替Serializable对象。

我知道这是一个很长的答案,但这也适用于您必须在hibernate.reveng.xml文件中设置的任何其他更改(我认为)。我不是休眠专家,因此您的里程可能会因此而有所不同。

更新: 所以经过一番谷歌搜索后,我发现了这个关于 Netbeans 中自定义 ant 任务的网站。所以我只是将目标的名称更改为gen-dao,现在它不会在我每次进行清理和构建时运行,只是在我专门调用它时。

于 2010-03-19T15:00:36.230 回答
2

我遇到了类似的问题,并通过编写自己的 RevengNamingStrategy 解决了它。

我有一个表有两列作为 TIMESTAMP_WITH_TIMEZONE 和 TIMESTAMP_WITH_LOCAL_TIMEZONE 并且在逆向工程过程中它们映射到可序列化。

TIMESTAMP_WITH_TIMEZONE 和 TIMESTAMP_WITH_LOCAL_TIMEZONE 类型的 SqlTypes 分别是 -101 和 -102。由于这些类型在java.sql.Types中没有休眠映射类型,因此它们映射到可序列化。

所以写了我自己的 RevengNamingStrategy,它将这些类型转换为时间戳。实习生转换为休眠时间戳类型。

public class OracleRevengNamingStrategy extends DefaultRevengNamingStrategy {

    private static final Integer TIMESTAMP_WITH_TIMEZONE_SQL_CODE = -101;

    private static final Integer TIMESTAMP_WITH_LOCAL_TIMEZONE_SQL_CODE = -102;


    public OracleRevengNamingStrategy(ReverseEngineeringStrategy delegate) {
        super(delegate);
    }

    // Converts Timestamp with tomezone and Time stamp with local time zone to Timestamp
    @Override
    public String columnToHibernateTypeName(TableIdentifier table, String columnName, int sqlType, int length, int precision, int scale,
                                            boolean nullable, boolean generatedIdentifier) {
        String type;

        if (sqlType == TIMESTAMP_WITH_TIMEZONE_SQL_CODE || sqlType == TIMESTAMP_WITH_LOCAL_TIMEZONE_SQL_CODE) {
            type = "timestamp";
        } else {
            type = super.columnToHibernateTypeName(table, columnName, sqlType, length, precision, scale, nullable, generatedIdentifier);
        }

        return type;
    }

}
于 2015-07-10T14:07:54.427 回答