package jp.bne.deno.ordermaid.common;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;

public class DaoInterceptor implements MethodInterceptor {
	private static Logger log = Logger.getLogger(DaoInterceptor.class);

	private EntityManagerFactory factory;

	/**
	 * コンストラクタでEntityManagerを取得しておく.
	 */
	public DaoInterceptor(EntityManagerFactory entityManagerFactory) {
		this.factory = entityManagerFactory;
	}

	/**
	 * DAO実行後にEntityManagerを必ずクリアする.
	 */
	public Object invoke(MethodInvocation methodInvocation) throws Throwable {
		EntityManager entityManager = factory.createEntityManager();
		try {
			return methodInvocation.proceed();
		} catch (Throwable e) {
			// 例外発生時はロールバック.
			if (entityManager.getTransaction().isActive()) {
				try {
					entityManager.getTransaction().rollback();
				} catch (Throwable e2) {
					log.error(e2);
				}
			}
			throw e;
		} finally {
			// 管理オブジェクトを解放する.
			entityManager.clear();
			long free = Runtime.getRuntime().freeMemory() / 1024 / 1024;
			long max = Runtime.getRuntime().maxMemory() / 1024 / 1024;
			log.info("EntityManager#clear" + "[" + free + "/" + max + "]");
		}
	}
}
