Hibernate/TIPS集
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
#topicpath
----
//ここにコンテンツを記述します。
#contents
**基本操作 [#f67e50ad]
***HQLでクエリを発行する [#r42f3f74]
SessionFactory sessionfactory = config.buildSessionFacto...
session = sessionfactory.openSession();
List list = session.find("from UserId as userid where us...
↑ 結果(UserIdクラス)の格納されたListが返ってくる
''Hibernate3.0から上のfindはdeprecatedになりました。3.0か...
Query query = session.createQuery
("from UserId as userid where userid.userId like 'Mas...
List messages = query.list();
''としてください。''
HQLの文法などはいろんなサイトで説明されているので割愛。上...
from UserId[1] as userid[2] where userid[2].userId[3] li...
↑ 意味は、[1]のクラスを検索します。条件は[3]のフィールド...
↑ [2]はエイリアスなんでなんでもよいでしょう
** Hibernateの一時オブジェクト、永続化オブジェクト、分離...
***一時オブジェクト [#x8dcba07]
通常のJavaオブジェクト。newしたヤツ。セッションで管理され...
***永続化オブジェクト [#k0097f2c]
セッションで管理されている。対応するロウがテーブルにある。
***分離オブジェクト [#l9a51efc]
セッションで管理されていない。対応するロウがテーブルにあ...
***各状態への遷移方法 [#i03ab1dd]
一時オブジェクト ---save---> 永続化オブジェクト <-------...
一時オブジェクト <--delete-- 永続化オブジェクト --evict,...
一時オブジェクト --saveOrUpdate--> 永続化オブジェクト
分離オブジェクト --saveOrUpdate--> 永続化オブジェクト
**デバッグ張って、ためしてみた [#wb545811]
当たり前の事をまとめてます。。。
***分離オブジェクトをsaveするとinsert文が走った [#bceb4462]
final SessionFactory sessionFactory = getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setName("kino");
session.save(user);
System.out.println(user);
tx.commit(); <-この処理後、insertが走る
session.flush();
session.close();
System.out.println(user);
session = sessionFactory.openSession();
tx = session.beginTransaction();
session.save(user); さっきの分離オブジェクトをsaveしてる
// session.update(user);
// user.setName("hogehoge");
tx.commit(); <-この処理後、insertが走る(updateではない)
session.flush();
session.close();
分離オブジェクトをsaveすると、insertが走った
***分離オブジェクトをupdateするとupdate文が走った(永続化...
final SessionFactory sessionFactory = getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setName("kino");
session.save(user);
System.out.println(user);
tx.commit(); <-この処理後、insertが走る
session.flush();
session.close();
System.out.println(user);
session = sessionFactory.openSession();
tx = session.beginTransaction();
//session.save(user);
session.update(user); さっきの分離オブジェクトをupdateし...
user.setName("hogehoge");
tx.commit(); <-この処理後、updateが走る。setNameしてる...
上のupdateと併せて一回だけupdateが走る
(setNameしなくても一回はupdateが走った)
session.flush();
session.close();
分離オブジェクトをupdateすると、update文が走った。ただこ...
session = sessionFactory.openSession();
tx = session.beginTransaction();
// session.save(user);
// session.update(user);
session.lock(user, LockMode.NONE); <-これ
// user.setName("hogehoge");
tx.commit();
session.flush();
session.close();
session.lockを使用します。上の例だとupdate文は走らないけ...
***分離オブジェクトをupdateしないで変更してもupdate文は走...
ちなみに
session = sessionFactory.openSession();
tx = session.beginTransaction();
// session.save(user);
// session.update(user);
// session.lock(user, LockMode.NONE);
user.setName("hogehoge");
tx.commit();
session.flush();
session.close();
この場合userは分離オブジェクトなので、これではupdate文は...
**その他 [#d3d6a0ad]
***すでに永続化オブジェクトがセッション中にロードされてい...
org.hibernate.NonUniqueObjectException: a different objec...
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setName("hogehoge");
session.save(user);
System.out.println(user);
int num = user.getId();
user = new User();
user.setId(num);
user.setName("name");
session.update(user); <-ここで例外
System.out.println(user);
tx.commit();
session.flush();
session.close();
同じ識別子の値で別のオブジェクトがすでに関連付いている、...
あ、flushしてからevictしなくちゃいけないんですね。
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setName("hogehoge");
session.save(user);
session.flush();
session.evict(user);
int num = user.getId();
user = new User();
user.setId(num);
user.setName("name");
session.update(user); <-例外は発生しなくなる
System.out.println(user);
tx.commit();
session.flush();
session.close();
これでOKでした。
***saveしたオブジェクトをすぐevictするとエラー [#ca47b323]
上のようにsaveしたあとflushしてからevictしないと、
org.hibernate.AssertionFailure - an assertion failure oc...
(this may indicate a bug in Hibernate, but is more likel...
org.hibernate.AssertionFailure: possible nonthreadsafe a...
が発生する。
***selectしてきたオブジェクトにはCGLIBで拡張されている [#...
newしてsaveしたオブジェクトは普通のクラス。session.loadな...
***複数の設定ファイルを使用したい [#l648af06]
hibernate.cfg.xmlはどうもひとつのデータベース設定しか書け...
でも場合によっては一つのデータベースだけではなく、複数の...
Configuration config = new Configuration();
// config = config.configure(); // <-通常の設定の読み...
config = config.configure(new File(
getServlet().getServletContext().getRealPath(
"/WEB-INF/lib/hibernate.cfg.hoge.xml")));
このようにすることで、ランタイムに設定ファイルを指定する...
***結合(関連)を考える [#t380b000]
#ref(fig1.gif)
- Member -> WorkGroupを表現する
JavaBeans(ここではMember)にプロパティを追加してマッピング...
<many-to-one name ="workgroup" column="GROUPNO"
class="nu.mine.kino.binding.ait.hibernate.Workgroup" ca...
update="false" insert="false" />
を追加すればよいようだ。追加しない場合はMember#getWorkgro...
Member(N) -> WorkGroup(1) なので、many-to-oneとなる
- WorkGroup -> Memberを表現する
JavaBeans(ここではWorkGroup)にプロパティを追加してマッピ...
<set name="memberList" >
<key ><column name="groupno" /></key>
<one-to-many class="nu.mine.kino.binding.ait.hibernate....
</set>
を追加すればよいようだ。追加しない場合はWorkgroup#getMemb...
WorkGroup(1) -> Member(N) なので、one-to-manyとなる
クラス設計で考えるとWorkGroup -> Member はあってもその逆...
aWorkGroup.getMembers()
はあっても
aMember.getWorkGroup()
はないことが多いように思うけど。。。
http://www.atmarkit.co.jp/fjava/rensai3/ormap05/ormap05_1...
***WEBアプリの時、設定ファイルなどはどこに置くべきか。 [#...
:hibernate.cfg.xml|classesの直下などに置いて、各リソース...
<mapping resource="nu/mine/kino/MtAuthor.hbm.xml" />
などと指定する
:各オブジェクトの設定ファイル|Javaファイルと同じ場所に置...
***middlegenで作ったhbmファイルについて [#d5bf7378]
たとえば
<id name="id" type="java.lang.Integer" column="id" >
<meta attribute="field-description">
@hibernate.id
generator-class="Increment"
type="java.lang.Integer"
column="id"
</meta>
<generator class="Increment" />
</id>
の
<meta attribute="field-description">
@hibernate.id
generator-class="Increment"
type="java.lang.Integer"
column="id"
</meta>
の部分は、コメントに使われるだけ、だと思う。
***MySQLのauto_incrementについて [#d1cfce68]
`name_id` int(10) unsigned NOT NULL auto_increment,
と定義されるカラムがあるテーブルについて、middlegenでJava...
<id
name="nameId"
type="java.lang.Object"
column="name_id"
>
<meta attribute="field-description">
@hibernate.id
generator-class="assigned"
type="java.lang.Object"
column="name_id"
</meta>
<generator class="assigned" />
</id>
実際はIntegerとマッピングして欲しいのですが、うまくいかな...
<generator class="assigned" />
を
<generator class="increment" />
に変更しました。もちろんJavaソースも作り直しました。
***複合キーを使ったテーブルのマッピング。 [#y6914635]
主キーが複数、たとえば
create table Customer3 (customer_id varchar(20) not null,
item_id varchar(20) not null,
value varchar(255),
upd_date timestamp,
primary key (customer_id, item_id));
というようにcustomer_id,item_idでユニークになるテーブルの...
XDocletなどを使ってhbm.xmlを作る場合がほとんどだと思いま...
public class Customer3Id implements Serializable {
private String customerId;
private String itemId;
public Customer3Id() {
}
/**
* @hibernate.property column = "customer_id" not-null...
*/
public String getCustomerId() {
return customerId;
}
/**
* @hibernate.property column = "item_id" not-null = "...
*/
public String getItemId() {
return itemId;
}
public String toString(){...}
public boolean equals(Object obj) {...}
public int hashCode() {...}
}
どうも、
-toString,equals,hashCodeは必ずOverrideしなくてはいけない
-implements Serializableであること
みたいです。
で、実際のレコードの方(?)のPOJOはさっきの複合オブジェク...
/**
* @hibernate.class table = customer3
*/
public class Customer3 {
private Customer3Id compositeId;
....
/**
* @return compositeId を戻します。
* @hibernate.id generator-class="assigned"
*/
public Customer3Id getCompositeId() {
return compositeId;
}
}
XDocletでhbmを生成したところ、
<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping>
<class
name="nu.mine.kino.plugin.hsqldb.hibernate.Customer3...
<composite-id name="compositeId"
class="nu.mine.kino.plugin.hsqldb.hibernate.Custom...
<key-property
name="customerId"
type="java.lang.String"
column="customer_id"
length="20"
/>
<key-property
name="itemId"
type="java.lang.String"
column="item_id"
length="20"
/>
</composite-id>
<property
name="value"
....................
</class>
</hibernate-mapping>
なんてのができあがりました。ポイントは複合キーはそのキー...
-[[複合識別子としてのコンポーネント:http://www.hibernate....
-[[Hibernate で O/Rマッピング してみる : 関係編:http://7...
***middlegenおぼえがき [#g8f87fb9]
http://boss.bekk.no/boss/middlegen/
samples/build.xmlを修正し流用します。まずは
<!ENTITY database SYSTEM "file:./config/database/hsqldb....
を実際に使用するデータベース用のファイルに変更します。ほ...
name: javaクラスのパッケージ名に対応
database.name :これも変えるのかな?
などを変更します。また上で指定した
file:./config/database/XXXXX.xml
の内容を、個々人の環境に応じて書き換えます。たとえばこん...
<property name="database.url" value="jdbc:sybase:Tds:[I...
<property name="database.userid" value="[ID]"/>
<property name="database.password" value="[PASS]"/>
<property name="database.schema" value="dbo"/> <-おも...
<property name="database.catalog" value="XXXXXX"/> use...
で、ant hbm2javaでOK!((ほかにもant middlegenでさまざまな...
ちなみに、自動生成されたxmlファイルを手で修正してJavaを生...
----
この記事は
#vote(おもしろかった[63],そうでもない[8])
-HQLの文法ってなかなかおぼえられん。 "from Messages as m ...
#topicpath
SIZE(10){現在のアクセス:&counter;}
終了行:
#topicpath
----
//ここにコンテンツを記述します。
#contents
**基本操作 [#f67e50ad]
***HQLでクエリを発行する [#r42f3f74]
SessionFactory sessionfactory = config.buildSessionFacto...
session = sessionfactory.openSession();
List list = session.find("from UserId as userid where us...
↑ 結果(UserIdクラス)の格納されたListが返ってくる
''Hibernate3.0から上のfindはdeprecatedになりました。3.0か...
Query query = session.createQuery
("from UserId as userid where userid.userId like 'Mas...
List messages = query.list();
''としてください。''
HQLの文法などはいろんなサイトで説明されているので割愛。上...
from UserId[1] as userid[2] where userid[2].userId[3] li...
↑ 意味は、[1]のクラスを検索します。条件は[3]のフィールド...
↑ [2]はエイリアスなんでなんでもよいでしょう
** Hibernateの一時オブジェクト、永続化オブジェクト、分離...
***一時オブジェクト [#x8dcba07]
通常のJavaオブジェクト。newしたヤツ。セッションで管理され...
***永続化オブジェクト [#k0097f2c]
セッションで管理されている。対応するロウがテーブルにある。
***分離オブジェクト [#l9a51efc]
セッションで管理されていない。対応するロウがテーブルにあ...
***各状態への遷移方法 [#i03ab1dd]
一時オブジェクト ---save---> 永続化オブジェクト <-------...
一時オブジェクト <--delete-- 永続化オブジェクト --evict,...
一時オブジェクト --saveOrUpdate--> 永続化オブジェクト
分離オブジェクト --saveOrUpdate--> 永続化オブジェクト
**デバッグ張って、ためしてみた [#wb545811]
当たり前の事をまとめてます。。。
***分離オブジェクトをsaveするとinsert文が走った [#bceb4462]
final SessionFactory sessionFactory = getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setName("kino");
session.save(user);
System.out.println(user);
tx.commit(); <-この処理後、insertが走る
session.flush();
session.close();
System.out.println(user);
session = sessionFactory.openSession();
tx = session.beginTransaction();
session.save(user); さっきの分離オブジェクトをsaveしてる
// session.update(user);
// user.setName("hogehoge");
tx.commit(); <-この処理後、insertが走る(updateではない)
session.flush();
session.close();
分離オブジェクトをsaveすると、insertが走った
***分離オブジェクトをupdateするとupdate文が走った(永続化...
final SessionFactory sessionFactory = getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setName("kino");
session.save(user);
System.out.println(user);
tx.commit(); <-この処理後、insertが走る
session.flush();
session.close();
System.out.println(user);
session = sessionFactory.openSession();
tx = session.beginTransaction();
//session.save(user);
session.update(user); さっきの分離オブジェクトをupdateし...
user.setName("hogehoge");
tx.commit(); <-この処理後、updateが走る。setNameしてる...
上のupdateと併せて一回だけupdateが走る
(setNameしなくても一回はupdateが走った)
session.flush();
session.close();
分離オブジェクトをupdateすると、update文が走った。ただこ...
session = sessionFactory.openSession();
tx = session.beginTransaction();
// session.save(user);
// session.update(user);
session.lock(user, LockMode.NONE); <-これ
// user.setName("hogehoge");
tx.commit();
session.flush();
session.close();
session.lockを使用します。上の例だとupdate文は走らないけ...
***分離オブジェクトをupdateしないで変更してもupdate文は走...
ちなみに
session = sessionFactory.openSession();
tx = session.beginTransaction();
// session.save(user);
// session.update(user);
// session.lock(user, LockMode.NONE);
user.setName("hogehoge");
tx.commit();
session.flush();
session.close();
この場合userは分離オブジェクトなので、これではupdate文は...
**その他 [#d3d6a0ad]
***すでに永続化オブジェクトがセッション中にロードされてい...
org.hibernate.NonUniqueObjectException: a different objec...
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setName("hogehoge");
session.save(user);
System.out.println(user);
int num = user.getId();
user = new User();
user.setId(num);
user.setName("name");
session.update(user); <-ここで例外
System.out.println(user);
tx.commit();
session.flush();
session.close();
同じ識別子の値で別のオブジェクトがすでに関連付いている、...
あ、flushしてからevictしなくちゃいけないんですね。
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setName("hogehoge");
session.save(user);
session.flush();
session.evict(user);
int num = user.getId();
user = new User();
user.setId(num);
user.setName("name");
session.update(user); <-例外は発生しなくなる
System.out.println(user);
tx.commit();
session.flush();
session.close();
これでOKでした。
***saveしたオブジェクトをすぐevictするとエラー [#ca47b323]
上のようにsaveしたあとflushしてからevictしないと、
org.hibernate.AssertionFailure - an assertion failure oc...
(this may indicate a bug in Hibernate, but is more likel...
org.hibernate.AssertionFailure: possible nonthreadsafe a...
が発生する。
***selectしてきたオブジェクトにはCGLIBで拡張されている [#...
newしてsaveしたオブジェクトは普通のクラス。session.loadな...
***複数の設定ファイルを使用したい [#l648af06]
hibernate.cfg.xmlはどうもひとつのデータベース設定しか書け...
でも場合によっては一つのデータベースだけではなく、複数の...
Configuration config = new Configuration();
// config = config.configure(); // <-通常の設定の読み...
config = config.configure(new File(
getServlet().getServletContext().getRealPath(
"/WEB-INF/lib/hibernate.cfg.hoge.xml")));
このようにすることで、ランタイムに設定ファイルを指定する...
***結合(関連)を考える [#t380b000]
#ref(fig1.gif)
- Member -> WorkGroupを表現する
JavaBeans(ここではMember)にプロパティを追加してマッピング...
<many-to-one name ="workgroup" column="GROUPNO"
class="nu.mine.kino.binding.ait.hibernate.Workgroup" ca...
update="false" insert="false" />
を追加すればよいようだ。追加しない場合はMember#getWorkgro...
Member(N) -> WorkGroup(1) なので、many-to-oneとなる
- WorkGroup -> Memberを表現する
JavaBeans(ここではWorkGroup)にプロパティを追加してマッピ...
<set name="memberList" >
<key ><column name="groupno" /></key>
<one-to-many class="nu.mine.kino.binding.ait.hibernate....
</set>
を追加すればよいようだ。追加しない場合はWorkgroup#getMemb...
WorkGroup(1) -> Member(N) なので、one-to-manyとなる
クラス設計で考えるとWorkGroup -> Member はあってもその逆...
aWorkGroup.getMembers()
はあっても
aMember.getWorkGroup()
はないことが多いように思うけど。。。
http://www.atmarkit.co.jp/fjava/rensai3/ormap05/ormap05_1...
***WEBアプリの時、設定ファイルなどはどこに置くべきか。 [#...
:hibernate.cfg.xml|classesの直下などに置いて、各リソース...
<mapping resource="nu/mine/kino/MtAuthor.hbm.xml" />
などと指定する
:各オブジェクトの設定ファイル|Javaファイルと同じ場所に置...
***middlegenで作ったhbmファイルについて [#d5bf7378]
たとえば
<id name="id" type="java.lang.Integer" column="id" >
<meta attribute="field-description">
@hibernate.id
generator-class="Increment"
type="java.lang.Integer"
column="id"
</meta>
<generator class="Increment" />
</id>
の
<meta attribute="field-description">
@hibernate.id
generator-class="Increment"
type="java.lang.Integer"
column="id"
</meta>
の部分は、コメントに使われるだけ、だと思う。
***MySQLのauto_incrementについて [#d1cfce68]
`name_id` int(10) unsigned NOT NULL auto_increment,
と定義されるカラムがあるテーブルについて、middlegenでJava...
<id
name="nameId"
type="java.lang.Object"
column="name_id"
>
<meta attribute="field-description">
@hibernate.id
generator-class="assigned"
type="java.lang.Object"
column="name_id"
</meta>
<generator class="assigned" />
</id>
実際はIntegerとマッピングして欲しいのですが、うまくいかな...
<generator class="assigned" />
を
<generator class="increment" />
に変更しました。もちろんJavaソースも作り直しました。
***複合キーを使ったテーブルのマッピング。 [#y6914635]
主キーが複数、たとえば
create table Customer3 (customer_id varchar(20) not null,
item_id varchar(20) not null,
value varchar(255),
upd_date timestamp,
primary key (customer_id, item_id));
というようにcustomer_id,item_idでユニークになるテーブルの...
XDocletなどを使ってhbm.xmlを作る場合がほとんどだと思いま...
public class Customer3Id implements Serializable {
private String customerId;
private String itemId;
public Customer3Id() {
}
/**
* @hibernate.property column = "customer_id" not-null...
*/
public String getCustomerId() {
return customerId;
}
/**
* @hibernate.property column = "item_id" not-null = "...
*/
public String getItemId() {
return itemId;
}
public String toString(){...}
public boolean equals(Object obj) {...}
public int hashCode() {...}
}
どうも、
-toString,equals,hashCodeは必ずOverrideしなくてはいけない
-implements Serializableであること
みたいです。
で、実際のレコードの方(?)のPOJOはさっきの複合オブジェク...
/**
* @hibernate.class table = customer3
*/
public class Customer3 {
private Customer3Id compositeId;
....
/**
* @return compositeId を戻します。
* @hibernate.id generator-class="assigned"
*/
public Customer3Id getCompositeId() {
return compositeId;
}
}
XDocletでhbmを生成したところ、
<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping>
<class
name="nu.mine.kino.plugin.hsqldb.hibernate.Customer3...
<composite-id name="compositeId"
class="nu.mine.kino.plugin.hsqldb.hibernate.Custom...
<key-property
name="customerId"
type="java.lang.String"
column="customer_id"
length="20"
/>
<key-property
name="itemId"
type="java.lang.String"
column="item_id"
length="20"
/>
</composite-id>
<property
name="value"
....................
</class>
</hibernate-mapping>
なんてのができあがりました。ポイントは複合キーはそのキー...
-[[複合識別子としてのコンポーネント:http://www.hibernate....
-[[Hibernate で O/Rマッピング してみる : 関係編:http://7...
***middlegenおぼえがき [#g8f87fb9]
http://boss.bekk.no/boss/middlegen/
samples/build.xmlを修正し流用します。まずは
<!ENTITY database SYSTEM "file:./config/database/hsqldb....
を実際に使用するデータベース用のファイルに変更します。ほ...
name: javaクラスのパッケージ名に対応
database.name :これも変えるのかな?
などを変更します。また上で指定した
file:./config/database/XXXXX.xml
の内容を、個々人の環境に応じて書き換えます。たとえばこん...
<property name="database.url" value="jdbc:sybase:Tds:[I...
<property name="database.userid" value="[ID]"/>
<property name="database.password" value="[PASS]"/>
<property name="database.schema" value="dbo"/> <-おも...
<property name="database.catalog" value="XXXXXX"/> use...
で、ant hbm2javaでOK!((ほかにもant middlegenでさまざまな...
ちなみに、自動生成されたxmlファイルを手で修正してJavaを生...
----
この記事は
#vote(おもしろかった[63],そうでもない[8])
-HQLの文法ってなかなかおぼえられん。 "from Messages as m ...
#topicpath
SIZE(10){現在のアクセス:&counter;}
ページ名: