如何在hibernate中将oracle时间戳映射到适当的java类型?

发布于 2024-08-25 16:20:58 字数 1220 浏览 7 评论 0 原文

我是冬眠新手,我很困惑。在我的数据库中,我有一些表,其中包含 TIMESTAMP(6) 列。我使用的是 Netbeans 6.5.1,当我生成 hibernate.reveng.xmlhbm.xml 文件pojo 文件 时,它会设置列的类型为可序列化。这不是我所期望的,也不是我想要的。

我在 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

I am new to hibernate and I am stumped. In my database I have tables that have a columns of TIMESTAMP(6). I am using Netbeans 6.5.1 and when I generate the hibernate.reveng.xml, hbm.xml files, and pojo files it sets the columns to be of type Serializable. This is not what I expected, nor what I want them to be.

I found this post on the hibernate forums saying to place:

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

in the hibernate.reveng.xml file.

In Netbeans you are not able to generate the mappings from this file (it creates a new one every time) and it does not seem to have the ability to re-generate them from the file either (at least according to this it is slated to be available in version 7).

So I am trying to figure out what to do. I am more inclined to believe I am doing something wrong since I am new to this, and it seems like it would be a common problem for others.

  • So what am I doing wrong?
  • If I am not doing anything wrong, how do I work around this?

I am using Netbeans 6.5, Oracle 10G, and I believe Hibernate 3 (it came with my netbeans).

Edit: Meant to say I found this stackoverflow question, but it is really a different problem.

UPDATE:
The oracle jdbc driver I was using (ojdbc14.jar) is 9.0.2.0.0
I have now also tried:

  • ojdbc14.jar version 10.2.0.4.0
  • ojdbc6.jar version 11.2.0.1.0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

对你再特殊 2024-09-01 16:20:58

我找到了解决这个问题的方法。这个问题本身似乎是围绕这样一个事实展开的: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.jarjtidy-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>

您需要的最后一部分是在 post-clean 部分中运行的设置:

<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 时间戳不是可序列化的,请编辑 hibernate.reveng.xml 文件并

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

在 schema-selection 标记后面添加:。

因此,干净的构建和时间戳将不是 java.sql.Timestamp 而不是 Serialized 对象。

我知道这是一个很长的答案,但这也应该适用于您必须在 hibernate.reveng.xml 文件中设置的任何其他更改(我认为)。我不是冬眠方面的专家,所以你的情况可能会有所不同。

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

I found a work around for this problem. The issue itself seems to revolve around the fact that Netbeans 6.5 (and I later versions up to this point) do not allow you to reverse engineer a database from an existing hibernate.reveng.xml file. This is slated to be available in version 7.

The work around I found is to create an ant task to recreate the hbm.xml and pojo java files. I currently have this hooked to happen when I do a clean and build, but I am going to try to find a way to to have it completely separate, since it will only need to be ran when the database schema changes.

To accomplish this when you do a clean and build though you need to edit your build.xml file.

The first part is the libraries you will need. So add:

<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>

You should already have the hibernate-tools.jar, hibernate3.jar, and ojdbc14.jar files on you machine. So just change the path to them. The freemaker.jar and jtidy-r938.jar will need to be downloaded, as I did not have those.

Below this in the build.xml you will need to add:

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

The last section you will need is the set to run in the post-clean section:

<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>
  • The delete portion will delete the existing hbm and pojo files, before they are re-created.
  • The configurationfile points to your main configuration file.
  • The package name is the dot separated package you want them created in (com.stackoverflow.pojo for example).
  • The revengfile is the reverse engineering xml file to use when creating the hbm and pojo files.
  • The hbm2hbmxml will create the hbm.xml files of your tables.
  • The hbm2java will create the java pojo files of your tables.

Now to get the Oracle Timestamps to be something other than Serializable, edit the hibernate.reveng.xml file and add:

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

just after the schema-selection tag.

So a clean and build and the timestamps will not be java.sql.Timestamp instead of Serializable objects.

This is a long answer I know, but this should also work for any other changes that you would have to set in the hibernate.reveng.xml file (I think). I am no expert in hibernate, so your mileage may vary with this.

UPDATE:
So after some googling I found this site about custom ant tasks in Netbeans. So I simply changed the name of the target to be gen-dao and now it does not run every time I do a clean and build, just when I specifically invoke it.

哥,最终变帅啦 2024-09-01 16:20:58

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

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

TIMESTAMP_WITH_TIMEZONE 和 TIMESTAMP_WITH_LOCAL_TIMEZONE 类型的 SqlType 为 -101 和 -102。由于 java.sql.Types 中没有这些类型的 hibernate 映射类型,因此它们映射到可序列化。

所以写了我自己的 RevengNamingStrategy,它将这些类型转换为 Timestamp。Which intern 转换为 hibernate TimeStampType。

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;
    }

}

I faced similar issue and resolved it by writing my own RevengNamingStrategy.

I have a table having two columns as TIMESTAMP_WITH_TIMEZONE and
TIMESTAMP_WITH_LOCAL_TIMEZONE and in reverse engineering process they
are mapping to seralizable.

SqlTypes of TIMESTAMP_WITH_TIMEZONE and TIMESTAMP_WITH_LOCAL_TIMEZONE types are -101 and -102.And As there is no hibernate mapping types in java.sql.Types for these types,hence they are mapping to seralizable.

So Wrote my own RevengNamingStrategy,which converts these type to Timestamp.Which intern converts to hibernate TimeStampType.

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;
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文