3.4.11. CRUD 操作に対するカスタム SQL
Hibernate を使用すると、生成された各単一 SQL ステートメントをオーバーライドできます。ネイティブ SQL クエリの使用方法についてはすでに説明しましたが、エンティティのステータスをロードまたは変更するために使用される SQL ステートメントをオーバーライドすることもできます。
@Entity @Table(name="CHAOS") @SQLInsert( sql="INSERT INTO CHAOS(size, name, nickname, id) VALUES(?,upper(?),?,?)") @SQLUpdate( sql="UPDATE CHAOS SET size = ?, name = upper(?), nickname = ? WHERE id = ?") @SQLDelete( sql="DELETE CHAOS WHERE id = ?") @SQLDeleteAll( sql="DELETE CHAOS") @Loader(namedQuery = "chaos") @NamedNativeQuery(name="chaos", query="select id, size, name, lower( nickname ) as nickname from CHAOS where id= ?", resultClass = Chaos.class) public class Chaos { @Id private Long id; private Long size; private String name; private String nickname;
@SQLInsert
、@SQLUpdate
、@SQLDelete
、@SQLDeleteAll
はそれぞれ INSERT ステートメント、UPDATE ステートメント、DELETE ステートメント、DELETE ステートメントをオーバーライドしてすべてのエンティティを削除します。
ストアドプロシージャを呼び出す場合は、
callable
属性を true (@SQLInsert(callable=true, ...)
) に設定してください。
実行が正常に行われたことを確認するために、Hibernate を使用して以下の 3 つの方針のいずれかを定義できます。
- NONE: 確認が行われません。ストアドプロシージャは問題発生時に失敗してしまうでしょう。
- COUNT: 更新が成功したことを確認する rowcount の使用
- PARAM: COUNT と似ていますが、標準的なメカニズムではなく出力パラメータを使用します。
結果チェックスタイルを定義するには、
check
パラメータ (@SQLUpdate(check=ResultCheckStyle.COUNT, ...)
) を使用します。
また、ネイティブ SQL クエリまたは HQL クエリにより SQL ロードステートメントをオーバーライドすることもできます。
@Loader
アノテーションを使用して名前付きクエリを参照する必要があります。
まったく同じアノテーションセットを使用してコレクション関連のステートメントをオーバーライドできます。
@OneToMany
@JoinColumn(name="chaos_fk")
@SQLInsert( sql="UPDATE CASIMIR_PARTICULE SET chaos_fk = ? where id = ?") @SQLDelete( sql="UPDATE CASIMIR_PARTICULE SET chaos_fk = null where id = ?")
private Set<CasimirParticle> particles = new HashSet<CasimirParticle>();
パラメータの順序は重要であり、順序 Hibernate ハンドルプロパティにより定義されます。
org.hibernate.persister.entity
レベルに対してデバッグロギングを有効にすることにより、予期された順序を確認できます。このレベルを有効にすると、 Hibernate はエンティティの作成、更新、削除などに使用される静的な SQL を出力します (予期されたシーケンスを確認するために、アノテーションを使用してカスタム SQL を含めないようにしてください (Hibernate により生成された静的な SQL をオーバーライドします))。
@org.hibernate.annotations.Table
と attributes sqlInsert
、sqlUpdate
、または sqlDelete
のいずれかあるいはすべてを使用して、セカンダリテーブルのために SQL ステートメントをオーバーライドすることもできます。
@Entity
@SecondaryTables({
@SecondaryTable(name = "`Cat nbr1`"),
@SecondaryTable(name = "Cat2"})
@org.hibernate.annotations.Tables( {
@Table(appliesTo = "Cat", comment = "My cat table" ),
@Table(appliesTo = "Cat2", foreignKey = @ForeignKey(name="FK_CAT2_CAT"), fetch = FetchMode.SELECT,
sqlInsert=@SQLInsert(sql="insert into Cat2(storyPart2, id) values(upper(?), ?)") )
} )
public class Cat implements Serializable {
前の例は、該当するテーブル (プライマリまたはセカンダリ) に対してコメントを提供できることも示しています。このコメントは DDL 生成に使用されます。