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
How to map oracle timestamp to appropriate java type in hibernate?
提问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 files,pojo 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.jar和jtidy-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 thehbm.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;
}
}

