PlayFramework2.1.3(Java)+JPA 使ってみる #2
コントローラーから検証#1
UnitTestをあきらめて、コントローラーからDBアクセスを検証してみる。
app/controllers/Application.java
public class Application extends Controller { public static Result tests() { Company company = Company.findById(1L); if (company == null) { return notFound(); } return ok(company.name); } }
conf/routes
GET /tests controllers.Application.tests()
play1のような感覚で実装できた。コントローラーメソッドの戻り値が void から Result に、Result は Exceptionでなくなった。
play1 の throw result は面白かったけど throw this のような違和感があった。独自Resultクラスで throw this と書いたことがあります。やめたけど。
http://localhost:9000/tests にアクセスすると、
[RuntimeException: No EntityManager bound to this thread. Try to annotate your action method with @play.db.jpa.Transactional]
と表示された。親切なメッセージだなあ。
testsアクションを @play.db.jpa.Transactional でアノテートとする。これはドキュメントにも載っている通り。2.3のころにはアノテートしなくてもよくなるかな。
アノテートして http://localhost:9000/tests へ。
[PersistenceException: org.hibernate.exception.SQLGrammarException: could not load an entity: [models.Company#1]]
h2データベースに接続したみたいだ。SQLGrammarException は create table も insert もしていないので当然か。
コントローラーから検証#2
コントローラーでDDLとテストデータを投入してみる。JPA.em() で EntityManager 取得できるのは play1と同じ感覚。
@play.db.jpa.Transactional
public static Result tests() {
String sql1 = "create table company ( "
+ "id bigint not null, "
+ "name varchar(255), "
+ "constraint pk_company primary key (id))";
String sql2 = "insert into company (id,name) values ( 1,'Apple Inc.')";
JPA.em().createNativeQuery(sql1).executeUpdate();
JPA.em().createNativeQuery(sql2).executeUpdate();
Company company = Company.findById(1L);
if (company == null) {
return notFound();
}
return ok(company.name);
}
コントローラーでテストデータ投入#2
@play.db.jpa.Transactional
public static Result tests()
{
Company c = new Company();
c.id = 2L;
c.name = "asdf";
c.save();
Company company = Company.findById(2L);
if (company == null) {
return notFound();
}
return ok(company.name);
}