/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.dao.orm.hibernate; import com.liferay.portal.kernel.dao.orm.Dialect; import com.liferay.portal.kernel.dao.orm.ORMException; import com.liferay.portal.kernel.dao.orm.Session; import com.liferay.portal.kernel.dao.orm.SessionFactory; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.util.ProxyUtil; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.spring.hibernate.PortletTransactionManager; import com.liferay.portal.spring.transaction.CurrentPlatformTransactionManagerUtil; import com.liferay.portal.util.PropsValues; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.sql.Connection; import org.hibernate.engine.SessionFactoryImplementor; import org.springframework.orm.hibernate3.HibernateTransactionManager; import org.springframework.transaction.PlatformTransactionManager; /** * @author Shuyang Zhou */ public class VerifySessionFactoryWrapper implements SessionFactory { public static SessionFactory createVerifySessionFactoryWrapper( SessionFactoryImpl sessionFactoryImpl) { if (PropsValues.SPRING_HIBERNATE_SESSION_FACTORY_VERIFY) { return new VerifySessionFactoryWrapper(sessionFactoryImpl); } return sessionFactoryImpl; } public VerifySessionFactoryWrapper(SessionFactoryImpl sessionFactoryImpl) { _sessionFactoryImpl = sessionFactoryImpl; } @Override public void closeSession(Session session) throws ORMException { if (PropsValues.SPRING_HIBERNATE_SESSION_DELEGATED && ProxyUtil.isProxyClass(session.getClass())) { InvocationHandler invocationHandler = ProxyUtil.getInvocationHandler(session); if (invocationHandler.getClass() == SessionInvocationHandler.class) { session.flush(); } } _sessionFactoryImpl.closeSession(session); } @Override public Session getCurrentSession() throws ORMException { return _sessionFactoryImpl.getCurrentSession(); } @Override public Dialect getDialect() throws ORMException { return _sessionFactoryImpl.getDialect(); } @Override public Session openNewSession(Connection connection) throws ORMException { return _sessionFactoryImpl.openNewSession(connection); } @Override public Session openSession() throws ORMException { if (!PropsValues.SPRING_HIBERNATE_SESSION_DELEGATED || _verify()) { return _sessionFactoryImpl.openSession(); } Session session = _sessionFactoryImpl.openSession(); return (Session)ProxyUtil.newProxyInstance( Session.class.getClassLoader(), new Class<?>[] {Session.class}, new SessionInvocationHandler(session)); } private void _logFailure( SessionFactoryImplementor currentSessionFactoryImplementor, SessionFactoryImplementor targetSessionFactoryImplementor) { StringBundler sb = new StringBundler(5); sb.append("Wrong current transaction manager, current session "); sb.append("factory classes metadata: "); sb.append(currentSessionFactoryImplementor.getAllClassMetadata()); sb.append(", target session factory classes metadata: "); sb.append(targetSessionFactoryImplementor.getAllClassMetadata()); _log.error( "Failed session factory verification", new IllegalStateException(sb.toString())); } private boolean _verify() { PlatformTransactionManager platformTransactionManager = CurrentPlatformTransactionManagerUtil. getCurrentPlatformTransactionManager(); if (platformTransactionManager == null) { throw new IllegalStateException("No current transaction manager"); } SessionFactoryImplementor targetSessionFactoryImplementor = _sessionFactoryImpl.getSessionFactoryImplementor(); if (platformTransactionManager instanceof HibernateTransactionManager) { HibernateTransactionManager hibernateTransactionManager = (HibernateTransactionManager)platformTransactionManager; SessionFactoryImplementor currentSessionFactoryImplementor = (SessionFactoryImplementor) hibernateTransactionManager.getSessionFactory(); if (targetSessionFactoryImplementor == currentSessionFactoryImplementor) { return true; } else { _logFailure( currentSessionFactoryImplementor, targetSessionFactoryImplementor); return false; } } if (platformTransactionManager instanceof PortletTransactionManager) { PortletTransactionManager portletTransactionManager = (PortletTransactionManager)platformTransactionManager; SessionFactoryImplementor currentSessionFactoryImplementor = (SessionFactoryImplementor) portletTransactionManager.getPortletSessionFactory(); if (targetSessionFactoryImplementor == currentSessionFactoryImplementor) { return true; } else { _logFailure( currentSessionFactoryImplementor, targetSessionFactoryImplementor); return false; } } throw new IllegalStateException( "Unknown transaction manager type: " + platformTransactionManager); } private static final Log _log = LogFactoryUtil.getLog( VerifySessionFactoryWrapper.class); private final SessionFactoryImpl _sessionFactoryImpl; private static class SessionInvocationHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws ReflectiveOperationException { return method.invoke(_session, args); } private SessionInvocationHandler(Session session) { _session = session; } private final Session _session; } }