山下寛人オフィシャルブログ

オイシックス株式会社 執行役員 システム本部長 山下寛人の公式ブログです。

HibernateToolsでEntityを自動生成

EclipseJPA機能(Dali)の中に、DBのテーブルを元に

Entityクラスを自動生成する機能があります。

よくできた機能ですが、いくつか問題があります。

・NUMBER型のフィールドがBigDecimalになる

BigDecimalなら小数も正確に計算できますが

四則演算や比較にメソッドを使うかプリミティブ型に

いちいち変換しないといけません。

・DATE型に時刻が入らない

Oracleの場合です。

DBをTIMESTAMPにする、@Temporal(TemporalType.TIMESTAMP)を

つけるといった回避策があります。

・最近のバージョンではフィールドの並び順が
アルファベット順になってしまう

フィールド並び順の問題は厳しいので

Hibernate Toolsを使うことにしました。


Hibernate Toolsの場合、型のマッピングもカスタマイズ

できます。

EclipseGUIで使うこともできるし、antで使うことも

できます。

できることはほぼ同じですがantだとその前後で

いろいろな処理をついでにできるので私はantを

使いました。


antの場合でもEclipseプラグインとしてインストール

します。

アーカイブでダウンロードもできますがどれを抜き出して

antで使うのかよくわからないのでプラグインから

取るほうがわかりやすいです。

以下のURLを指定し、Hibernate Toolsを選択してインストール

します。

http://download.jboss.org/jbosstools/updates/stable/indigo/


インストールできたら、Eclipseのインストールディレクトリの

下の

plugins\org.jboss.tools.hibernate4_0_3.5.1.v20120715-0252-H98-Final\lib

以下に必要なjarが入っているのでコピーします。


さてEntityを自動生成するには(reverse engineeringと呼びます)

hibernate.reveng.xmlファイルが必要です。


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-reverse-engineering PUBLIC "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd" >

<hibernate-reverse-engineering>
<type-mapping>
<sql-type jdbc-type="DATE"
hibernate-type="java.sql.Timestamp">
</sql-type>
<sql-type jdbc-type="NUMERIC" hibernate-type="Integer"
scale="0">
</sql-type>
</type-mapping>
<table-filter match-schema="TEST002" match-name="TBL_JUCHUU_BUNRUI"></table-filter>
<table schema="TEST002" name="TBL_JUCHUU_BUNRUI"
class="com.oisix.oisystemec.model.JuchuuBunrui">
</table>
</hibernate-reverse-engineering>


DBの型とJavaの型のマッピングをカスタマイズすることが

できます。

上記ではscale=0つまり小数点以下が0桁の場合にIntegerに

マッピングするようにしています。


設定ファイルができたらbuild.xmlを作成します。

リバースエンジニアリングにはJDBCドライバが必要なので

別途入手しておきます。

またDBの接続情報はhibernate.cfg.xmlを使用します。

build.xmlは以下のようになります。



<project default="generate">
<property name="table" value="TBL_JUCHUU_BUNRUI" />
<property name="class" value="JuchuuBunrui" />
<property name="package" value="com.oisix.oisystemec.model" />
<property name="path-package" value="com/oisix/oisystemec/model" />
<property name="src" value="../src/${path-package}" />

<path id="toolslib">
<fileset dir="lib-plugin">
<include name="**/*.jar"/>
</fileset>
<path location="lib/ojdbc6.jar" />
</path>
<taskdef name="hibernatetool" classname="org.hibernate.tool.ant.HibernateToolTask" classpathref="toolslib" />

<target name="generate" depends="make-config">
<hibernatetool destdir="generated">
<jdbcconfiguration configurationfile="lib/hibernate.cfg.test.xml" revengfile="hibernate.reveng.xml" detectmanytomany="false" detectOptimisticLock="false" />
<hbm2java jdk5="true" ejb3="true" />
</hibernatetool>
</target>
</project>



<path>でHibernate ToolsのjarとJDBCドライバのjarを

指定します。

<taskdef>でHibernate Toolsを使えるようにします。

<hibernatetool>で実際にリバースエンジニアリングをします。

<jdbcconfiguration>はDB接続の指定です。

<hbm2java>でEntityを生成します。

アノテーションで生成することも、XMLを生成することも

できます。


できたクラスは以下のようになります。



package com.oisix.oisystemec.model;
// Generated 2012/08/08 18:25:05 by Hibernate Tools 4.0.0


import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
* Todoufuken generated by hbm2java
*/
@Entity
@Table(name="M_TODOUFUKEN"
,schema="TEST002"
)
public class Todoufuken implements java.io.Serializable {


private Integer todoufukenId;
private String todoufuken;
private Integer kyakusouryou;
private Integer butsuryuusouryou;
private String shinkisakuseisha;
private Date shinkisakuseiDate;
private String saishuukoushinsha;
private Date saishuukoushinDate;

public Todoufuken() {
}


public Todoufuken(Integer todoufukenId) {
this.todoufukenId = todoufukenId;
}
public Todoufuken(Integer todoufukenId, String todoufuken, Integer kyakusouryou, Integer butsuryuusouryou, String shinkisakuseisha, Date shinkisakuseiDate, String saishuukoushinsha, Date saishuukoushinDate) {
this.todoufukenId = todoufukenId;
this.todoufuken = todoufuken;
this.kyakusouryou = kyakusouryou;
this.butsuryuusouryou = butsuryuusouryou;
this.shinkisakuseisha = shinkisakuseisha;
this.shinkisakuseiDate = shinkisakuseiDate;
this.saishuukoushinsha = saishuukoushinsha;
this.saishuukoushinDate = saishuukoushinDate;
}

@Id


@Column(name="TODOUFUKEN_ID", unique=true, nullable=false, precision=2, scale=0)
public Integer getTodoufukenId() {
return this.todoufukenId;
}

public void setTodoufukenId(Integer todoufukenId) {
this.todoufukenId = todoufukenId;
}


@Column(name="TODOUFUKEN", length=8)
public String getTodoufuken() {
return this.todoufuken;
}

public void setTodoufuken(String todoufuken) {
this.todoufuken = todoufuken;
}


@Column(name="KYAKUSOURYOU", precision=4, scale=0)
public Integer getKyakusouryou() {
return this.kyakusouryou;
}

public void setKyakusouryou(Integer kyakusouryou) {
this.kyakusouryou = kyakusouryou;
}


@Column(name="BUTSURYUUSOURYOU", precision=4, scale=0)
public Integer getButsuryuusouryou() {
return this.butsuryuusouryou;
}

public void setButsuryuusouryou(Integer butsuryuusouryou) {
this.butsuryuusouryou = butsuryuusouryou;
}


@Column(name="SHINKISAKUSEISHA", length=4)
public String getShinkisakuseisha() {
return this.shinkisakuseisha;
}

public void setShinkisakuseisha(String shinkisakuseisha) {
this.shinkisakuseisha = shinkisakuseisha;
}

@Temporal(TemporalType.TIMESTAMP)
@Column(name="SHINKISAKUSEI_DATE", length=7)
public Date getShinkisakuseiDate() {
return this.shinkisakuseiDate;
}

public void setShinkisakuseiDate(Date shinkisakuseiDate) {
this.shinkisakuseiDate = shinkisakuseiDate;
}


@Column(name="SAISHUUKOUSHINSHA", length=4)
public String getSaishuukoushinsha() {
return this.saishuukoushinsha;
}

public void setSaishuukoushinsha(String saishuukoushinsha) {
this.saishuukoushinsha = saishuukoushinsha;
}

@Temporal(TemporalType.TIMESTAMP)
@Column(name="SAISHUUKOUSHIN_DATE", length=7)
public Date getSaishuukoushinDate() {
return this.saishuukoushinDate;
}

public void setSaishuukoushinDate(Date saishuukoushinDate) {
this.saishuukoushinDate = saishuukoushinDate;
}




}


ただしこれだとまだ少し気に入らないところが

あるのでantでもう少し加工してみます。

それは次回に。