前回の記事でSpring MVCでOracleDBに接続する方法を書いたが、あの後EntityManagerを手動で作らなくても@PersistenceContextアノテーションを使うとSpringが自動で注入してくれるって知った。
けど、@PersistenceContextを書いただけでは、エラーが起きたので使用するための設定を調べてみました。。。
この前買った本には「@PersistenceContexを使うとできる」くらいしか書いてなくて最初はさっぱりだったので、初心者にもわかるようにもっと詳しく書いてほしいです。。
servlet-context.xml(Beans定義ファイル)
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<mvc:annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean id="templateResolver"
class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<beans:property name="prefix" value="/WEB-INF/templates/" />
<beans:property name="suffix" value=".html" />
<beans:property name="templateMode" value="HTML5" />
</beans:bean>
<beans:bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
<beans:property name="templateResolver" ref="templateResolver" />
</beans:bean>
<beans:bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
<beans:property name="templateEngine" ref="templateEngine" />
<beans:property name="characterEncoding" value="UTF-8" />
</beans:bean>
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver" />
<beans:bean id="xmlViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver">
<beans:property name="order" value="1" />
<beans:property name="location" value="/WEB-INF/spring/views.xml" />
</beans:bean>
<context:annotation-config />
<context:component-scan base-package="jp.test.spring" />
<!-- ↓ここから追記 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="${jdbc.driverClassName}" />
<beans:property name="url" value="${jdbc.url}" />
<beans:property name="username" value="${jdbc.username}" />
<beans:property name="password" value="${jdbc.password}" />
</beans:bean>
<beans:bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
<beans:bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<beans:property name="database" value="ORACLE" />
<beans:property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
</beans:bean>
<beans:bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="packagesToScan" value="jp.test.spring.entity" />
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="jpaDialect" ref="jpaDialect" />
<beans:property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
</beans:bean>
<beans:bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<beans:property name="entityManagerFactory" ref="entityManagerFactory" />
</beans:bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- ↑ここまで追記 -->
</beans:beans>
※他のユーザさんの投稿の書き方を倣ってファイルのコメントに追加した部分を明記してみましたw
Oracle 11g接続設定
<beans:bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<beans:property name="database" value="ORACLE" />
<beans:property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
</beans:bean>
今回はOracle XE 11gなので"database"には"ORACLE"、"databasePlatform"には"org.hibernate.dialect.Oracle10gDialect"を設定
※Orale11gDialectはなく10gを使うらしい
※PostgreSQLやHSQLなど他のDBを使う場合はここを適時修正する
※最初Oracleの場合、何を設定するの?って思ったけどhttp://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/orm/jpa/vendor/AbstractJpaVendorAdapter.html#setDatabase-org.springframework.orm.jpa.vendor.Database- を見たら書いてあった
DB接続設定
DB接続設定をjdbc.propertiesに外だしにしているので src/main/resources 直下にjdbc.propertiesを新規作成
jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@localhost:1521/xe
jdbc.username=(DB接続ユーザ名)
jdbc.password=(DB接続パスワード)
EntityManagerFactory設定
あとはEntityManagerのEntityがいるパッケージの設定("packageToScan")に注意。
設定したパッケージ配下を探してくれるみたいなので最上位のパッケージを指定してもよいが通常Entityを格納するパッケージが決まっていると思うのでそこを指定。
今回は"jp.test.spring.entity"
<beans:bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="packagesToScan" value="jp.test.spring.entity" />
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="jpaDialect" ref="jpaDialect" />
<beans:property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
</beans:bean>
(注)spring-ormライブラリをpom.xmlに追加する必要あり
@PersistenceContex使用!
@PersistenceContextアノテーションを使用する準備が整ったので早速試してみる
※Entityクラスは前回のものを使用(http://qiita.com/zateon/items/f5129cd1367dc12e675d#entity%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AE%E4%BD%9C%E6%88%90)
※テスト用なのでServiceクラスでEntityManager使ってます。。
package jp.test.spring.service.impl;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import jp.test.spring.entity.NameT;
import jp.test.spring.service.TestService;
@Service("testService")
public class TestServiceImpl implements TestService {
private static final Logger logger = LoggerFactory.getLogger(TestServiceImpl.class);
@PersistenceContext
private EntityManager entityManager;
@Override
public List<NameT> getJpa() {
logger.info("getJpa()");
// EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa.sample");
// EntityManager em = emf.createEntityManager();
//
// List<NameT> nameTList = em.createNamedQuery("NameT.findAll", NameT.class).getResultList();
// for (NameT nameT : nameTList) {
// logger.info("id: " + nameT.getId() + " / name: " + nameT.getName());
// }
//
// em.close();
// emf.close();
List<NameT> nameTList = entityManager.createNamedQuery("NameT.findAll", NameT.class).getResultList();
for (NameT nameT : nameTList) {
logger.info("id: " + nameT.getId() + " / name: " + nameT.getName());
}
return nameTList;
}
}
以上でアクセスできた^^