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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2473866/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 21:21:59  来源:igfitidea点击:

How to map oracle timestamp to appropriate java type in hibernate?

javahibernateoracle10gnetbeans6.5

提问by Jacob Schoen

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 filesit sets the columns to be of type Serializable. This is not what I expected, nor what I want them to be.

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

I found thispost on the hibernate forums saying to place:

我在 hibernate 论坛上发现这篇文章说要放置:

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

in the hibernate.reveng.xmlfile.

hibernate.reveng.xml文件中。

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 thisit is slated to be available in version 7).

在 Netbeans 中,您无法从此文件生成映射(它每次都会创建一个新的映射)并且它似乎也没有能力从文件中重新生成它们(至少根据它预定在版本 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).

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

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

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

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

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

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

采纳答案by Jacob Schoen

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.xmlfile. This is slated to be available in version 7.

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

The work around I found is to create an ant task to recreate the hbm.xmland 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.

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

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

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

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.jarand jtidy-r938.jarwill need to be downloaded, as I did not have those.

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

Below this in the build.xmlyou will need to add:

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

<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 configurationfilepoints to your main configuration file.
  • The package name is the dot separated package you want them created in (com.stackoverflow.pojofor example).
  • The revengfileis the reverse engineering xml file to use when creating the hbm and pojo files.
  • The hbm2hbmxmlwill create the hbm.xmlfiles of your tables.
  • The hbm2javawill create the java pojo files of your tables.
  • 删除部分将删除现有的 hbm 和 pojo 文件,然后再重新创建它们。
  • configurationfile点到你的主配置文件。
  • 包名称是您希望在其中创建的点分隔包(com.stackoverflow.pojo例如)。
  • revengfile是在创建 hbm 和 pojo 文件时使用的逆向工程 xml 文件。
  • hbm2hbmxml将创建hbm.xml你的表格文件。
  • hbm2java会创建表的java的POJO文件。

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

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

<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.Timestampinstead of Serializableobjects.

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

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.xmlfile (I think). I am no expert in hibernate, so your mileage may vary with this.

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

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

更新:所以经过一些google搜索,我发现这个网站有关NetBeans定制Ant任务。所以我只是将目标的名称更改为gen-dao现在它不会在每次我进行清理和构建时运行,只是在我专门调用它时。

回答by Sunil Kumar

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

我遇到了类似的问题并通过编写我自己的 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.

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

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.Typesfor these types,hence they are mapping to seralizable.

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

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

所以写了我自己的 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;
    }

}