/* * Copyright 2011-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kr.debop4j.data.hibernate.unitofwork; import kr.debop4j.core.Guard; import kr.debop4j.core.Local; import lombok.extern.slf4j.Slf4j; import org.hibernate.Session; import org.hibernate.SessionFactory; /** * Hibernate 용 IUnitOfWork Factory 클래스입니다. * * @author 배성혁 ( sunghyouk.bae@gmail.com ) * @since 12. 11. 30. */ @Slf4j public class UnitOfWorkFactory implements IUnitOfWorkFactory { protected final Object syncLock = new Object(); protected SessionFactory sessionFactory; @Override public SessionFactory getSessionFactory() { return this.sessionFactory; } @Override public void setSessionFactory(SessionFactory sessionFactory) { Guard.shouldNotBeNull(sessionFactory, "sessionFactory"); if (log.isInfoEnabled()) log.info("SessionFactory를 설정합니다. sessionFactory=[{}]", sessionFactory); this.sessionFactory = sessionFactory; } @Override public Session getCurrentSession() { Session session = (Session) Local.get(IUnitOfWorkFactory.CURRENT_HIBERNATE_SESSION); Guard.shouldBe(session != null, "Session이 현 Thread Context에서 생성되지 않았습니다. UnitOfWorks.getStart() 를 먼저 호출하셔야 합니다."); return session; } @Override public void setCurrentSession(Session session) { if (log.isDebugEnabled()) log.debug("현 ThreadContext의 Session을 설정합니다. session=[{}]", session); Local.put(IUnitOfWorkFactory.CURRENT_HIBERNATE_SESSION, session); } @Override public void init() { if (log.isInfoEnabled()) log.info("Hibernate 용 UnitOfWorkFactory를 초기화합니다."); } @Override public IUnitOfWorkImplementor create(SessionFactory factory, IUnitOfWorkImplementor previous) { if (log.isDebugEnabled()) log.debug("새로운 IUnitOfWorkImplementor 인스턴스를 생성합니다... factory=[{}], previous=[{}]", factory, previous); if (factory == null) factory = this.sessionFactory; if (log.isDebugEnabled()) log.debug("Local ThreadContext 에 Session을 설정합니다..."); // Builder 패턴을 사용해도 됩니다. // sSession session = factory.withOptions().interceptor(interceptor).openSession(); Session session = factory.openSession(); setCurrentSession(session); return new UnitOfWorkAdapter(this, session, (UnitOfWorkAdapter) previous); } @Override public void closeUnitOfWork(IUnitOfWorkImplementor adapter) { Guard.shouldNotBeNull(adapter, "adapter"); if (log.isDebugEnabled()) log.debug("[{}]를 close 합니다.", adapter.getClass().getName()); Session session = null; if (adapter.getPrevious() != null) session = adapter.getPrevious().getSession(); setCurrentSession(session); UnitOfWorks.closeUnitOfWork(adapter); } }