2007/11/03

[Java] S2Hibernate-JPA を試してみた

仕事の調査で S2Hibernate-JPA を試してみました。
簡単なケースではエンティティの POJO を作って Entity アノテーション と Id アノテーション をつけるだけでおしまいです。ActiveRecord ほどではありませんが、なかなか簡単です。
Java 的にはクエリのパラメータに ? ではなく :name のように名前を付けられのが嬉しいところです。

カーソルをオープンして1レコードずつフェッチする的な処理をできる Dao がなかなかないのですが、Hibernate のネイティブ ScrollableResults を使ってそれを実現できるのは貴重です。
JPA で足りないところを Hibernate ネイティブの機能でおぎなえる、なかなか使えるような気がします。

create table bano (id int primary key, name varchar(20));
create table ba_bi (ba_id ind primary key, bi_name varchar(20));

package com.ms246.gpy1.dao;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
public class Bano {
@Id
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

package com.ms246.gpy1.dao;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class BaBi {
@Id
private int baId;
private String biName;
public int getBaId() {
return baId;
}
public void setBaId(int baId) {
this.baId = baId;
}
public String getBiName() {
return biName;
}
public void setBiName(String biName) {
this.biName = biName;
}
}

package com.ms246.gpy1;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.hibernate.ScrollableResults;
import org.hibernate.ejb.HibernateQuery;
import org.seasar.extension.unit.S2TestCase;

import com.ms246.gpy1.dao.BaBi;
import com.ms246.gpy1.dao.Bano;

public class Aaa extends S2TestCase {

private EntityManager em;

public Aaa(String name) {
super(name);
}

protected void setUp() throws Exception {
include("jpa.dicon");
}

protected void tearDown() throws Exception {
}

public void testBanoTx() {
// インサートとプライマリキーでのセレクト
for (int i = 0; i < 10; ++i) {
Bano bano = new Bano();
String name = "ひつじ" + i + "号";
bano.setId(i);
bano.setName(name);
em.persist(bano);
bano = em.find(Bano.class, i);
assertEquals(name, bano.getName());
}
// 該当レコードがない場合
assertNull(em.find(Bano.class, 100));

// Hibernate ネイティブの ScrollableResults を使う。
Query query = em.createQuery("select ba from Bano ba order by ba.id");
ScrollableResults results = ((HibernateQuery) query)
.getHibernateQuery().scroll();
for (int i = 0; results.next(); ++i) {
Bano bano = (Bano) results.get(0);
assertEquals("ひつじ" + i + "号", bano.getName());
}
results.close();

// EJB-QL
query = em
.createQuery("select ba from Bano ba where ba.id > :id order by ba.id");
query.setParameter("id", 7);
List<Bano> list = query.getResultList();
assertEquals(2, list.size());
assertEquals("ひつじ8号", list.get(0).getName());
assertEquals("ひつじ9号", list.get(1).getName());

// ネイティブクエリ
query = em.createNativeQuery("select * from Bano where name = :name",
Bano.class);
query.setParameter("name", "ひつじ2号");
assertEquals(2, ((Bano)query.getSingleResult()).getId());
}

public void testBaBiTx() {
// アンダーバーのあるテーブル名、カラム名もOK
BaBi baBi = new BaBi();
baBi.setBaId(2);
baBi.setBiName("ばああ");
em.persist(baBi);
}
}


その後の感想。
複合主キーの場合、主キー用のクラスが必要になるのがどうにもやっかいです。
S2Jdbc で1件ずつフェッチできれば、それで決定なのになぁ。

0 件のコメント: