LoginSignup
1
3

More than 5 years have passed since last update.

Spring MVC+Oracleで@PersistenceContext使う

Last updated at Posted at 2016-07-24

前回の記事でSpring MVCでOracleDBに接続する方法を書いたが、あの後EntityManagerを手動で作らなくても@PersistenceContextアノテーションを使うとSpringが自動で注入してくれるって知った。
けど、@PersistenceContextを書いただけでは、エラーが起きたので使用するための設定を調べてみました。。。

この前買った本には「@PersistenceContexを使うとできる」くらいしか書いてなくて最初はさっぱりだったので、初心者にもわかるようにもっと詳しく書いてほしいです。。

servlet-context.xml(Beans定義ファイル)

servlet-context.xml
<?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接続設定

servlet-context抜粋.xml
<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.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"

servlet-context抜粋.xml
<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使ってます。。

TestServiceImpl.java
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;
    }

}

以上でアクセスできた^^

1
3
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3