ITエンジニアぽむのブログ

IT系で気になったことを書き留めておく備忘録です。仕事でよく使っているJavaと自宅で使っているLinuxについて書いていこうと思っています。同じお悩みをお持ちの方のお役に立てたら嬉しいです。

Spring5とHibernate5.2を使ってSessionFactoryをBeanとして取得してみよう!

こんにちは、ぽむです。

年末年始は時間の空いてるときに、過去のブログを更新していました。誤字脱字、言葉の表現がおかしいところなどをまとめて修正しました。日本語ってホント難しいです。。

令和2年ものろのろしたペースでブログを更新していきたいと思っています。本年もよろしくお願い申し上げます。

今回は、Spring5フレームワークとO/RマッパであるHibernate5.2を使ってSessionFactoryをBeanとして取得する方法をご紹介したいと思います。

はじめに

SessionFactoryは、データベースのデータを操作する際にWebアプリケーションとデータベースの橋渡し役として必要になります。

SessionFactory is an interface. SessionFactory can be created by providing Configuration object, which will contain all DB related property details pulled from either hibernate.cfg.xml file or hibernate.properties file. SessionFactory is a factory for Session objects.

We can create one SessionFactory implementation per database in any application. If your application is referring to multiple databases, then you need to create one SessionFactory per database.

※下記リンクを引用させて頂きました。ありがとうございます。

What is SessionFactory in Hibernate? - Hibernate Tutorials

データの操作とは、主にデータベースのデータを取得・保存・更新・削除することです。データを操作するプログラムを集めたものをDAO(Data Access Objectsの略)といいます。

引用元にある通り(英語の引用元でごめんなさい。。僕は簡単な英語、見たことのある専門用語なら分かります!)、SessionFactoryを取得するにはhibernate.cfg.xmlファイルもしくはhibernate.propertiesファイルに関連付けられたデータベースから取得できます。

今回は、hibernate.cfg.xmlファイルからSessionFactoryを取得する方法をご紹介したいと思います。

開発環境

開発環境は下記の通りです。

Spring5.2.1.RELEASE
Hibernate5.2.10.Final
MySQL8.0.16

hibernate.cfg.xmlファイル

hibernate.cfg.xmlファイル内で下記の設定を行っています。

  • データベースのドライバ
  • データベースへの接続文字列
  • O/Rマッパの設定
  • エンティティの宣言

リソースフォルダに配置すれば、自動的に認識してくれます。

<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>

        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://127.0.0.1:3306/TESTDB?useUnicode=true&amp;characterEncoding=UTF-8</property>
        <property name="connection.username">test</property>
        <property name="connection.password">****</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>

        <!-- Disable the second-level cache -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
        
        <!-- Mapping file inclusion -->
        <mapping class="com.pom2019.entity.HouseholdAppliances"/>

    </session-factory>
</hibernate-configuration>

※パスワードはマスキングしています。

Configファイル

詳細は下記の通りとなっています。

  • Configurationアノテーション→設定ファイルとしてSpringが認識してくれます。ここでは絶対パスとなっていますが、これはHibernateのConfigurationクラスとクラス名が被っているからです。

  • Beanアノテーション→BeanクラスとしてSpringが認識してくれます。

  • SessionFactoryの取得hibernate.cfg.xmlファイルから設定を読み込みSessionFactoryを取得しています。SessionFactoryが取得できたら、取得できたことをコンソールに出力しています。

package com.pom2019.config;

import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.springframework.context.annotation.Bean;

@org.springframework.context.annotation.Configuration
public class HibernateConfig {

    @Bean
    public SessionFactory sessionFactory() {
        SessionFactory sessionFactory = null;
        
        try {
            //registryの作成
            StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();

            //MetadataSourcesの作成
            MetadataSources sources = new MetadataSources(registry);

            //Metadataの作成
            Metadata metadata = sources.getMetadataBuilder().build();

            //SessionFactoryの作成
            sessionFactory = metadata.getSessionFactoryBuilder().build();
            
            //ログの出力
            if (sessionFactory != null) {
                System.out.println("セッションファクトリーを取得できました!");
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        
        return sessionFactory;
    }
}

サーバーの起動

HibernateConfigファイルをComponentScanの対象にして、サーバーを起動します。

1 04, 2020 2:49:53 午後 org.apache.catalina.startup.Catalina load
情報: Initialization processed in 2646 ms
INFO  ContextLoader - Root WebApplicationContext: initialization started
INFO  ContextLoader - Root WebApplicationContext initialized in 419 ms
INFO  DispatcherServlet - Initializing Servlet 'dispatcherServlet'
INFO  Version - HHH000412: Hibernate Core {5.2.10.Final}
INFO  Environment - HHH000206: hibernate.properties not found
INFO  Version - HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
WARN  pooling - HHH10001002: Using Hibernate built-in connection pool (not for production use!)
INFO  pooling - HHH10001005: using driver [com.mysql.cj.jdbc.Driver] at URL [jdbc:mysql://127.0.0.1:3306/TESTDB?useUnicode=true&characterEncoding=UTF-8]
INFO  pooling - HHH10001001: Connection properties: {user=test, password=****}
INFO  pooling - HHH10001003: Autocommit mode: false
INFO  DriverManagerConnectionProviderImpl - HHH000115: Hibernate connection pool size: 1 (min=1)
INFO  Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
セッションファクトリーを取得できました!
INFO  DispatcherServlet - Completed initialization in 4332 ms
1 04, 2020 2:50:01 午後 org.apache.catalina.startup.Catalina start
情報: Server startup in 7681 ms

おわりに

SessionFactoryが無事取得できました。

SessionFactoryがBeanとして取得できたので、SessionFactoryを使いたいときにこのBeanを注入(Autowired)してあげれば、いつでもSessionFactoryを使うことができます。

最後までお読み頂きありがとうございました。