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

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

セッションファクトリーの便利な保存方法!

まえがき

SessionFactoryは、O/RマッパでEntityを取得するために必要になります。

(Entity操作を行うDaoは、すべてSessionFactoryをベースとして実装されています。他にEntityManagerを使う方法がありますが、ここではSessionFactoryにフォーカスしてお伝えしたいと思います。)

そのSessionFactoryをサーバ起動時に取得しておこうというのが今回の趣旨となります。

Dao使用時に毎回SessionFactoryを生成してしまうと、Daoを作成した分だけSessionFactory生成処理が必要になってきます。

その分、余分な処理が必要になってくるというわけです。

サーバ起動時に1度、SessionFactoryを生成しておけば、そのSessionFactoryを使い回すことで、余分な処理が必要なくなります!

ServletContextListenerの作成

ServletContextListenerを作成して、サーバ起動時にSessionFactoryをServletContextに保存する処理を追加します。

  • ServletContextListenerをインプリメントしてサーブレットコンテキストを取得しています。
  • hibernate.cfg.xmlから設定内容を読み込んでいます。
  • 設定内容からセッションファクトリーを取得しています。
  • サーブレットコンテキストにセッションファクトリーを保存しています。
package com.pom2019.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

public class HibernateListener implements ServletContextListener {
    private SessionFactory sessionFactory;

    public static final String KEY_NAME = HibernateListener.class.getName();

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        if (sessionFactory != null) {
            sessionFactory.close();
        }
    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        try {
            //configures settings from hibernate.cfg.xml
            Configuration configuration = new Configuration().configure();
            StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
                    .applySettings(configuration.getProperties());
            SessionFactory sessionFactory = configuration.buildSessionFactory(builder.build());

            //save the Hibernate session factory into serlvet context
            arg0.getServletContext().setAttribute(KEY_NAME, sessionFactory);
            
            //ログの出力
            if (sessionFactory != null) {
                System.out.println("セッションファクトリーを取得できました!");
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

※28行目、29行目、30行目でSessionFactoryが取得できた場合は、ログ出力を行っています。

HibernateListenerをリスナー登録

web.xmlでHibernateListenerをリスナー登録して、サーバ起動時にHibernateListenerを呼び出すようにしています。

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="struts_blank" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>Struts Blank Convention</display-name>

    <listener>
        <listener-class>com.pom2019.Struts2Web.InitListener</listener-class>
    </listener>
    
    <listener>
        <listener-class>com.pom2019.listener.HibernateListener</listener-class>
    </listener>
    
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

実行結果

サーバを再起動して、SessionFactoryを取得できているか確認します。

8 10, 2019 5:30:03 午後 org.apache.catalina.startup.Catalina load
情報: Initialization processed in 2959 ms
セッションファクトリーを取得できました!
8 10, 2019 5:30:10 午後 org.apache.catalina.startup.Catalina start
情報: Server startup in 6482 ms

無事、SessionFactoryを取得できていることが確認できました!

あとがき

SessionFactoryをServletContextに保存しておけば、いつでもSevletContextからSessionFactoryを取得することができます。

Dao操作を頻繁に行う、もしくはコードをシンプルにしたいなどといった場合に有効なので、よかったら活用して下さいね。

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