休止状態でOracleタイムスタンプを適切なJavaタイプにマップするにはどうすればよいですか?
-
21-09-2019 - |
質問
私は冬眠するのが初めてで、困惑しています。私のデータベースには、次の列を持つテーブルがあります。 TIMESTAMP(6)
. 。Netbeans 6.5.1 を使用していますが、 hibernate.reveng.xml
, hbm.xml files
, 、 そして pojo 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
解決
この問題の回避策を見つけました。この問題自体は、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 タイムスタンプを別のものにします。 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
そして今では、クリーンとビルドを行うたびに実行されるのではなく、特に呼び出したときにのみ実行されます。
他のヒント
私も同様の問題に直面しましたが、独自の RevengNamingStrategy を作成することで解決しました。
Timestamp_with_timezoneおよびTimestamp_with_local Zoneとして2つの列を持つテーブルがあり、リバースエンジニアリングプロセスでは、セラリゼーション可能にマッピングしています。
TIMESTAMP_WITH_TIMEZONE および TIMESTAMP_WITH_LOCAL_TIMEZONE タイプの SqlTypes は -101 および -102 です。また、Hibernate マッピング タイプが存在しないため、 java.sql.Types これらの型の場合、シリアル化可能にマッピングされます。
そこで、これらの型を Timestamp に変換する独自の RevengNamingStrategy を書きました。インターンは休止状態の 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;
}
}