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.dao.shard.ShardSpringSessionContext;
020 import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
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 public void setShardEnabled(boolean shardEnabled) {
089 _shardEnabled = shardEnabled;
090 }
091
092 protected static Map<String, Class<?>> getPreloadClassLoaderClasses() {
093 try {
094 Map<String, Class<?>> classes = new HashMap<>();
095
096 for (String className : _PRELOAD_CLASS_NAMES) {
097 ClassLoader portalClassLoader =
098 ClassLoaderUtil.getPortalClassLoader();
099
100 Class<?> clazz = portalClassLoader.loadClass(className);
101
102 classes.put(className, clazz);
103 }
104
105 return classes;
106 }
107 catch (ClassNotFoundException cnfe) {
108 throw new RuntimeException(cnfe);
109 }
110 }
111
112 protected Dialect determineDialect() {
113 return DialectDetector.getDialect(getDataSource());
114 }
115
116 protected ClassLoader getConfigurationClassLoader() {
117 Class<?> clazz = getClass();
118
119 return clazz.getClassLoader();
120 }
121
122 protected String[] getConfigurationResources() {
123 return PropsUtil.getArray(PropsKeys.HIBERNATE_CONFIGS);
124 }
125
126 @Override
127 protected Configuration newConfiguration() {
128 Configuration configuration = new Configuration();
129
130 Properties properties = PropsUtil.getProperties();
131
132 Properties hibernateProperties = getHibernateProperties();
133
134 for (Map.Entry<Object, Object> entry : hibernateProperties.entrySet()) {
135 String key = (String)entry.getKey();
136 String value = (String)entry.getValue();
137
138 properties.setProperty(key, value);
139 }
140
141 if (Validator.isNull(PropsValues.HIBERNATE_DIALECT)) {
142 Dialect dialect = determineDialect();
143
144 setDB(dialect);
145
146 Class<?> clazz = dialect.getClass();
147
148 properties.setProperty("hibernate.dialect", clazz.getName());
149 }
150
151 if (_shardEnabled) {
152 properties.setProperty(
153 Environment.CURRENT_SESSION_CONTEXT_CLASS,
154 ShardSpringSessionContext.class.getName());
155 }
156
157 properties.setProperty("hibernate.cache.use_query_cache", "false");
158 properties.setProperty(
159 "hibernate.cache.use_second_level_cache", "false");
160
161 properties.remove("hibernate.cache.region.factory_class");
162
163 configuration.setProperties(properties);
164
165 try {
166 String[] resources = getConfigurationResources();
167
168 for (String resource : resources) {
169 try {
170 readResource(configuration, resource);
171 }
172 catch (Exception e2) {
173 if (_log.isWarnEnabled()) {
174 _log.warn(e2, e2);
175 }
176 }
177 }
178
179 if (_mvccEnabled) {
180 EventListeners eventListeners =
181 configuration.getEventListeners();
182
183 eventListeners.setAutoFlushEventListeners(
184 new AutoFlushEventListener[] {
185 NestableAutoFlushEventListener.INSTANCE
186 });
187 eventListeners.setPostUpdateEventListeners(
188 new PostUpdateEventListener[] {
189 MVCCSynchronizerPostUpdateEventListener.INSTANCE
190 });
191 }
192 }
193 catch (Exception e1) {
194 _log.error(e1, e1);
195 }
196
197 return configuration;
198 }
199
200 @Override
201 protected void postProcessConfiguration(Configuration configuration) {
202
203
204
205
206
207
208 String connectionReleaseMode = PropsUtil.get(
209 Environment.RELEASE_CONNECTIONS);
210
211 if (Validator.isNotNull(connectionReleaseMode)) {
212 configuration.setProperty(
213 Environment.RELEASE_CONNECTIONS, connectionReleaseMode);
214 }
215 }
216
217 protected void readResource(
218 Configuration configuration, InputStream inputStream)
219 throws Exception {
220
221 if (inputStream == null) {
222 return;
223 }
224
225 if (_hibernateConfigurationConverter != null) {
226 String configurationString = StringUtil.read(inputStream);
227
228 configurationString = _hibernateConfigurationConverter.convert(
229 configurationString);
230
231 inputStream = new UnsyncByteArrayInputStream(
232 configurationString.getBytes());
233 }
234
235 configuration.addInputStream(inputStream);
236
237 inputStream.close();
238 }
239
240 protected void readResource(Configuration configuration, String resource)
241 throws Exception {
242
243 ClassLoader classLoader = getConfigurationClassLoader();
244
245 if (resource.startsWith("classpath*:")) {
246 String name = resource.substring("classpath*:".length());
247
248 Enumeration<URL> enu = classLoader.getResources(name);
249
250 if (_log.isDebugEnabled() && !enu.hasMoreElements()) {
251 _log.debug("No resources found for " + name);
252 }
253
254 while (enu.hasMoreElements()) {
255 URL url = enu.nextElement();
256
257 InputStream inputStream = url.openStream();
258
259 readResource(configuration, inputStream);
260 }
261 }
262 else {
263 InputStream inputStream = classLoader.getResourceAsStream(resource);
264
265 readResource(configuration, inputStream);
266 }
267 }
268
269 protected void setDB(Dialect dialect) {
270 DBFactoryUtil.setDB(dialect);
271 }
272
273 private static final String[] _PRELOAD_CLASS_NAMES =
274 PropsValues.SPRING_HIBERNATE_CONFIGURATION_PROXY_FACTORY_PRELOAD_CLASSLOADER_CLASSES;
275
276 private static final Log _log = LogFactoryUtil.getLog(
277 PortalHibernateConfiguration.class);
278
279 private static final Map<ProxyFactory, ClassLoader>
280 _proxyFactoryClassLoaders = new WeakHashMap<>();
281
282 static {
283 ProxyFactory.classLoaderProvider =
284 new ProxyFactory.ClassLoaderProvider() {
285
286 @Override
287 public ClassLoader get(ProxyFactory proxyFactory) {
288 synchronized (_proxyFactoryClassLoaders) {
289 ClassLoader classLoader = _proxyFactoryClassLoaders.get(
290 proxyFactory);
291
292 if (classLoader != null) {
293 return classLoader;
294 }
295
296 classLoader = ClassLoaderUtil.getPortalClassLoader();
297
298 ClassLoader contextClassLoader =
299 ClassLoaderUtil.getContextClassLoader();
300
301 if (classLoader != contextClassLoader) {
302 classLoader = new PreloadClassLoader(
303 contextClassLoader,
304 getPreloadClassLoaderClasses());
305 }
306
307 _proxyFactoryClassLoaders.put(
308 proxyFactory, classLoader);
309
310 return classLoader;
311 }
312 }
313
314 };
315 }
316
317 private Converter<String> _hibernateConfigurationConverter;
318 private boolean _mvccEnabled = true;
319 private boolean _shardEnabled;
320
321 }