NativeQueryでSELECTしてみる
TweetPosted on Saturday Jan 25, 2014 at 11:37PM in Technology
ここではNativeQueryを使うまでもない簡単な単独のエンティティをSELECTしてみます。複雑なのは後々。
環境
- Hibernate 4.3.0.Final
- WildFly8.0.0.CR1
- Oracle JDK7u51
- postgresql-9.3-1100.jdbc41.jar
- PostgreSQL 9.2.4
前提条件
- Arquillian Persistence ExtensionとJavaEE7を使います
- プロジェクトを作ったりする作業はJavaEE7プロジェクトでArquillianを使ってみるあたりを参照
- WildFlyへのJDBCドライバ配備方法等はWildFly - CLIでデータソースを定義するあたりを参照
関連を持たない単独のエンティティをSELECTしてみる
エンティティクラス等を配置
配置図
図で選択されている資源を作る必要が有ります
Employee.java
package org.arquillian.example; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Employee implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column private String firstName; @Column private String lastName; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } @Override public String toString() { return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + "]"; } }
orm.xml
<?xml version="1.0" encoding="UTF-8"?> <entity-mappings version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd"> <named-native-query name="findEmployee" result-set-mapping="employeeResult"> <query><![CDATA[ SELECT emp.id, emp.firstName, emp.lastName FROM Employee AS emp ]]></query> </named-native-query> <sql-result-set-mapping name="employeeResult"> <entity-result entity-class="org.arquillian.example.Employee"/> </sql-result-set-mapping> </entity-mappings>
IndependentSelectTest.java
package org.arquillian.example; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.transaction.Transactional; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.persistence.UsingDataSet; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(Arquillian.class) public class IndependentSelectTest { @Deployment public static Archive<?> createDeployment() { Archive<?> a = ShrinkWrap.create(WebArchive.class, "test.war") .addPackage(Employee.class.getPackage()) .addAsResource("test-persistence.xml", "META-INF/persistence.xml") .addAsResource("META-INF/orm.xml", "META-INF/orm.xml") .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addAsWebInfResource("jbossas-ds.xml"); return a; } @PersistenceContext EntityManager em; @Test @Transactional @UsingDataSet("datasets/independentSelect/employees.yml") public void select() throws Exception { dumpEntityList(em.createNamedQuery("findEmployee", Employee.class).getResultList()); } protected void dumpEntityList(List<?> list){ for(Object o : list){ System.out.println(o + ", contains=" + em.contains(o)); } } }
employees.yml
employee: - id: -1 firstname: Taro lastname: Yamada - id: -2 firstname: Jiro lastname: Suzuki - id: -3 firstname: Saburo lastname: Tanaka
jbossas-ds.xml
ローカルで動いているPostgreSQLにjpapracというDBを作っておきます
<?xml version="1.0" encoding="UTF-8"?> <datasources xmlns="http://www.jboss.org/ironjacamar/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.jboss.org/ironjacamar/schema http://docs.jboss.org/ironjacamar/schema/datasources_1_0.xsd"> <datasource enabled="true" jndi-name="jdbc/arquillian" pool-name="ArquillianPostgresPool"> <connection-url>jdbc:postgresql://localhost:5432/jpaprac</connection-url> <driver>postgresql-9.3-1100.jdbc41.jar</driver> <security> <user-name>postgres</user-name> <password>***</password> </security> </datasource> </datasources>
test-persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence-unit name="test"> <jta-data-source>jdbc/arquillian</jta-data-source> <properties> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.show_sql" value="true" /> </properties> </persistence-unit> </persistence>
実行結果
コンソールの出力を関係ありそうなところだけ抜粋
10:23:35,245 INFO [stdout] (pool-2-thread-12) Hibernate: SELECT emp.id, emp.firstName, emp.lastName FROM Employee AS emp 10:23:35,248 INFO [stdout] (pool-2-thread-12) Employee [id=-1, firstName=Taro, lastName=Yamada], contains=true 10:23:35,248 INFO [stdout] (pool-2-thread-12) Employee [id=-2, firstName=Jiro, lastName=Suzuki], contains=true 10:23:35,248 INFO [stdout] (pool-2-thread-12) Employee [id=-3, firstName=Saburo, lastName=Tanaka], contains=true
普通に出てますね。NamedNativeQueryにしてResultSetMappingまで定義するとManagedになる。
備考
@UsingDataSetアノテーションをテストメソッドに付けると、Arquillian Persistence Extensionがデータ投入してくれますが、投入したデータはテスト後にTRUNCATEされてしまうので、テスト後にテーブルで確認しようとしても見えないようです[3]。これを抑制する設定は現状存在しないらしい。まあデバッガか何かで止めれば見られるだろうけど。
arquillian.xmlにこういう内容を書けばTRUNCATEがテスト実行前に走るようになるので、テスト実行後のデータを簡単に確認できます
<?xml version="1.0" encoding="UTF-8"?> <arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd"> <extension qualifier="persistence"> <property name="defaultCleanupPhase">BEFORE</property> </extension> </arquillian>
HibernateのSQLログは、persistence.xmlのproperties要素内に以下のようなのを追記すると複数行使って見やすくインデントとかしてくれる
<property name="hibernate.format_sql" value="true"/>
続き
NativeQueryで関連持ちエンティティをSELECTしてみる
参考文献
Tags: jpa