001
014
015 package com.liferay.portal.spring.hibernate;
016
017 import com.liferay.portal.dao.orm.hibernate.event.MVCCSynchronizerPostUpdateEventListener;
018 import com.liferay.portal.dao.orm.hibernate.event.NestableAutoFlushEventListener;
019 import com.liferay.portal.kernel.dao.db.DBManagerUtil;
020 import com.liferay.portal.kernel.dao.db.DBType;
021 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
022 import com.liferay.portal.kernel.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024 import com.liferay.portal.kernel.util.ClassLoaderUtil;
025 import com.liferay.portal.kernel.util.Converter;
026 import com.liferay.portal.kernel.util.PreloadClassLoader;
027 import com.liferay.portal.kernel.util.PropsKeys;
028 import com.liferay.portal.kernel.util.StringUtil;
029 import com.liferay.portal.kernel.util.Validator;
030 import com.liferay.portal.util.PropsUtil;
031 import com.liferay.portal.util.PropsValues;
032
033 import java.io.InputStream;
034
035 import java.net.URL;
036
037 import java.util.Enumeration;
038 import java.util.HashMap;
039 import java.util.Map;
040 import java.util.Properties;
041 import java.util.WeakHashMap;
042
043 import javassist.util.proxy.ProxyFactory;
044
045 import org.hibernate.HibernateException;
046 import org.hibernate.SessionFactory;
047 import org.hibernate.cfg.Configuration;
048 import org.hibernate.cfg.Environment;
049 import org.hibernate.dialect.Dialect;
050 import org.hibernate.event.AutoFlushEventListener;
051 import org.hibernate.event.EventListeners;
052 import org.hibernate.event.PostUpdateEventListener;
053
054 import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
055
056
062 public class PortalHibernateConfiguration extends LocalSessionFactoryBean {
063
064 @Override
065 public SessionFactory buildSessionFactory() throws Exception {
066 setBeanClassLoader(getConfigurationClassLoader());
067
068 return super.buildSessionFactory();
069 }
070
071 @Override
072 public void destroy() throws HibernateException {
073 setBeanClassLoader(null);
074
075 super.destroy();
076 }
077
078 public void setHibernateConfigurationConverter(
079 Converter<String> hibernateConfigurationConverter) {
080
081 _hibernateConfigurationConverter = hibernateConfigurationConverter;
082 }
083
084 public void setMvccEnabled(boolean mvccEnabled) {
085 _mvccEnabled = mvccEnabled;
086 }
087
088 protected static Map<String, Class<?>> getPreloadClassLoaderClasses() {
089 try {
090 Map<String, Class<?>> classes = new HashMap<>();
091
092 for (String className : _PRELOAD_CLASS_NAMES) {
093 ClassLoader portalClassLoader =
094 ClassLoaderUtil.getPortalClassLoader();
095
096 Class<?> clazz = portalClassLoader.loadClass(className);
097
098 classes.put(className, clazz);
099 }
100
101 return classes;
102 }
103 catch (ClassNotFoundException cnfe) {
104 throw new RuntimeException(cnfe);
105 }
106 }
107
108 protected ClassLoader getConfigurationClassLoader() {
109 Class<?> clazz = getClass();
110
111 return clazz.getClassLoader();
112 }
113
114 protected String[] getConfigurationResources() {
115 return PropsUtil.getArray(PropsKeys.HIBERNATE_CONFIGS);
116 }
117
118 @Override
119 protected Configuration newConfiguration() {
120 Configuration configuration = new Configuration();
121
122 Properties properties = PropsUtil.getProperties();
123
124 Properties hibernateProperties = getHibernateProperties();
125
126 for (Map.Entry<Object, Object> entry : hibernateProperties.entrySet()) {
127 String key = (String)entry.getKey();
128 String value = (String)entry.getValue();
129
130 properties.setProperty(key, value);
131 }
132
133 Dialect dialect = DialectDetector.getDialect(getDataSource());
134
135 if (DBManagerUtil.getDBType(dialect) == DBType.SYBASE) {
136 properties.setProperty(PropsKeys.HIBERNATE_JDBC_BATCH_SIZE, "0");
137 }
138
139 if (Validator.isNull(PropsValues.HIBERNATE_DIALECT)) {
140 DBManagerUtil.setDB(dialect, getDataSource());
141
142 Class<?> clazz = dialect.getClass();
143
144 properties.setProperty("hibernate.dialect", clazz.getName());
145 }
146
147 properties.setProperty("hibernate.cache.use_query_cache", "false");
148 properties.setProperty(
149 "hibernate.cache.use_second_level_cache", "false");
150
151 properties.remove("hibernate.cache.region.factory_class");
152
153 configuration.setProperties(properties);
154
155 try {
156 String[] resources = getConfigurationResources();
157
158 for (String resource : resources) {
159 try {
160 readResource(configuration, resource);
161 }
162 catch (Exception e2) {
163 if (_log.isWarnEnabled()) {
164 _log.warn(e2, e2);
165 }
166 }
167 }
168
169 if (_mvccEnabled) {
170 EventListeners eventListeners =
171 configuration.getEventListeners();
172
173 eventListeners.setAutoFlushEventListeners(
174 new AutoFlushEventListener[] {
175 NestableAutoFlushEventListener.INSTANCE
176 });
177 eventListeners.setPostUpdateEventListeners(
178 new PostUpdateEventListener[] {
179 MVCCSynchronizerPostUpdateEventListener.INSTANCE
180 });
181 }
182 }
183 catch (Exception e1) {
184 _log.error(e1, e1);
185 }
186
187 return configuration;
188 }
189
190 @Override
191 protected void postProcessConfiguration(Configuration configuration) {
192
193
194
195
196
197
198 String connectionReleaseMode = PropsUtil.get(
199 Environment.RELEASE_CONNECTIONS);
200
201 if (Validator.isNotNull(connectionReleaseMode)) {
202 configuration.setProperty(
203 Environment.RELEASE_CONNECTIONS, connectionReleaseMode);
204 }
205 }
206
207 protected void readResource(
208 Configuration configuration, InputStream inputStream)
209 throws Exception {
210
211 if (inputStream == null) {
212 return;
213 }
214
215 if (_hibernateConfigurationConverter != null) {
216 String configurationString = StringUtil.read(inputStream);
217
218 configurationString = _hibernateConfigurationConverter.convert(
219 configurationString);
220
221 inputStream = new UnsyncByteArrayInputStream(
222 configurationString.getBytes());
223 }
224
225 configuration.addInputStream(inputStream);
226
227 inputStream.close();
228 }
229
230 protected void readResource(Configuration configuration, String resource)
231 throws Exception {
232
233 ClassLoader classLoader = getConfigurationClassLoader();
234
235 if (resource.startsWith("classpath*:")) {
236 String name = resource.substring("classpath*:".length());
237
238 Enumeration<URL> enu = classLoader.getResources(name);
239
240 if (_log.isDebugEnabled() && !enu.hasMoreElements()) {
241 _log.debug("No resources found for " + name);
242 }
243
244 while (enu.hasMoreElements()) {
245 URL url = enu.nextElement();
246
247 InputStream inputStream = url.openStream();
248
249 readResource(configuration, inputStream);
250 }
251 }
252 else {
253 InputStream inputStream = classLoader.getResourceAsStream(resource);
254
255 readResource(configuration, inputStream);
256 }
257 }
258
259 private static final String[] _PRELOAD_CLASS_NAMES =
260 PropsValues.SPRING_HIBERNATE_CONFIGURATION_PROXY_FACTORY_PRELOAD_CLASSLOADER_CLASSES;
261
262 private static final Log _log = LogFactoryUtil.getLog(
263 PortalHibernateConfiguration.class);
264
265 private static final Map<ProxyFactory, ClassLoader>
266 _proxyFactoryClassLoaders = new WeakHashMap<>();
267
268 static {
269 ProxyFactory.classLoaderProvider =
270 new ProxyFactory.ClassLoaderProvider() {
271
272 @Override
273 public ClassLoader get(ProxyFactory proxyFactory) {
274 synchronized (_proxyFactoryClassLoaders) {
275 ClassLoader classLoader = _proxyFactoryClassLoaders.get(
276 proxyFactory);
277
278 if (classLoader != null) {
279 return classLoader;
280 }
281
282 classLoader = ClassLoaderUtil.getPortalClassLoader();
283
284 ClassLoader contextClassLoader =
285 ClassLoaderUtil.getContextClassLoader();
286
287 if (classLoader != contextClassLoader) {
288 classLoader = new PreloadClassLoader(
289 contextClassLoader,
290 getPreloadClassLoaderClasses());
291 }
292
293 _proxyFactoryClassLoaders.put(
294 proxyFactory, classLoader);
295
296 return classLoader;
297 }
298 }
299
300 };
301 }
302
303 private Converter<String> _hibernateConfigurationConverter;
304 private boolean _mvccEnabled = true;
305
306 }