简体   繁体   English

如何在oibernate中将oracle timestamp映射到适当的java类型?

[英]How to map oracle timestamp to appropriate java type in hibernate?

I am new to hibernate and I am stumped. 我是新来的冬眠,我很难过。 In my database I have tables that have a columns of TIMESTAMP(6) . 在我的数据库中,我有一些列有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 . 我正在使用Netbeans 6.5.1,当我生成hibernate.reveng.xmlhbm.xml filespojo files它将列设置为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: 我在hibernate论坛上发现这篇帖子说要放置:

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

in the hibernate.reveng.xml file. 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 this it 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 this stackoverflow 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 ojdbc14.jar版本10.2.0.4.0
  • ojdbc6.jar version 11.2.0.1.0 ojdbc6.jar版本11.2.0.1.0

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. 问题本身似乎围绕着Netbeans 6.5(以及我之前的版本到目前为止)不允许您从现有的hibernate.reveng.xml文件对数据库进行逆向工程的事实。 This is slated to be available in version 7. 这将在版本7中提供。

The work around I found is to create an ant task to recreate the hbm.xml and pojo java files. 我找到的工作是创建一个ant任务来重新创建hbm.xml和pojo java文件。 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. 要在执行清理和构建时完成此操作,但需要编辑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. 您应该已经在机器上安装了hibernate-tools.jar,hibernate3.jar和ojdbc14.jar文件。 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. 需要下载freemaker.jarjtidy-r938.jar ,因为我没有这些。

Below this in the build.xml you 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. 删除部分将在重新创建之前删除现有的hbm和pojo文件。
  • The configurationfile points to your main configuration file. configurationfile点到你的主配置文件。
  • The package name is the dot separated package you want them created in ( com.stackoverflow.pojo for example). 包名称是您希望它们创建的点分隔包(例如com.stackoverflow.pojo )。
  • The revengfile is the reverse engineering xml file to use when creating the hbm and pojo files. revengfile是在创建hbm和pojo文件时使用的反向工程xml文件。
  • The hbm2hbmxml will create the hbm.xml files of your tables. hbm2hbmxml将创建表的hbm.xml文件。
  • The hbm2java will create the java pojo files of your tables. hbm2java将创建表的java pojo文件。

Now to get the Oracle Timestamps to be something other than Serializable , edit the hibernate.reveng.xml file and add: 现在要使Oracle Timestamps不是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.Timestamp instead of Serializable objects. 所以一个干净的构建和时间戳将不是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.xml file (I think). 这是我所知道的一个很长的答案,但这也应该适用于您必须在hibernate.reveng.xml文件中设置的任何其他更改(我认为)。 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. 更新:所以经过一些谷歌搜索后,我发现这个网站关于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. 所以我只是简单地将目标的名称更改为gen-dao ,现在每次执行clean和build时它都不会运行,就在我专门调用它时。

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.Types for these types,hence they are mapping to seralizable. TIMESTAMP_WITH_TIMEZONE和TIMESTAMP_WITH_LOCAL_TIMEZONE类型的SqlTypes是-101和-102.And由于java.sql.Types中没有针对这些类型的hibernate映射类型,因此它们映射到可序列化。

So Wrote my own RevengNamingStrategy,which converts these type to Timestamp.Which intern converts to hibernate TimeStampType. 所以写了我自己的RevengNamingStrategy,它将这些类型转换为Timestamp.Which实习生转换为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;
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM