HibernateUtil.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
org.pentaho.repository |
![]() |
![]() |
Pentaho |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* Copyright 2006 Pentaho Corporation. All rights reserved.
* This software was developed by Pentaho Corporation and is provided under the terms
* of the Mozilla Public License, Version 1.1, or any later version. You may not use
* this file except in compliance with the license. If you need a copy of the license,
* please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
* BI Platform. The Initial Developer is Pentaho Corporation.
*
* Software distributed under the Mozilla Public License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
* the license for the specific language governing your rights and limitations.
*
* @created Apr 20, 2005
* @author Marc Batchelor
*
*/
package org.pentaho.repository;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Node;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Dialect;
import org.pentaho.core.repository.RepositoryException;
import org.pentaho.core.repository.content.ContentException;
import org.pentaho.core.system.IApplicationContext;
import org.pentaho.core.system.IPentahoSystemEntryPoint;
import org.pentaho.core.system.IPentahoSystemExitPoint;
import org.pentaho.core.system.ISystemSettings;
import org.pentaho.core.system.PentahoSystem;
import org.pentaho.core.util.DatasourceHelper;
import org.pentaho.messages.MessageUtil;
import org.pentaho.messages.Messages;
public class HibernateUtil implements IPentahoSystemEntryPoint, IPentahoSystemExitPoint {
private static Log log = LogFactory.getLog(HibernateUtil.class);
private final static boolean debug = PentahoSystem.debug;
private static Configuration configuration;
private static SessionFactory sessionFactory;
private static final byte[] lock = new byte[0];
private static final ThreadLocal threadSession = new ThreadLocal();
private static final ThreadLocal threadTransaction = new ThreadLocal();
private static final ThreadLocal threadInterceptor = new ThreadLocal();
// private static final ThreadLocal commitNeeded = new ThreadLocal();
private static boolean hibernateManaged;
private static String factoryJndiName;
private static String dialect;
private static Context iniCtx;
private static List objectHandlers = new ArrayList();
private static final String QUERYWILDCARD = "%{0}%"; //$NON-NLS-1$
static {
// JIRA case #PLATFORM 150: removed listener and changed to lazy init
initialize();
}
//
private HibernateUtil() {}
protected static boolean initialize() {
IApplicationContext applicationContext = PentahoSystem.getApplicationContext();
// Add to entry/exit points list
HibernateUtil hUtil = new HibernateUtil();
applicationContext.addEntryPointHandler(hUtil);
applicationContext.addExitPointHandler(hUtil);
// Look for some hibernate-specific properties...
String hibernateConfigurationFile = applicationContext.getProperty("hibernateConfigPath", null); //$NON-NLS-1$
if ((hibernateConfigurationFile != null)) {
if (hibernateConfigurationFile.trim().length() == 0) {
hibernateConfigurationFile = null;
}
}
String tmp = applicationContext.getProperty("hibernateManaged", "false").trim().toLowerCase(); //$NON-NLS-1$ //$NON-NLS-2$
hibernateManaged = tmp.equals("true"); //$NON-NLS-1$
try {
configuration = new Configuration();
configuration.setEntityResolver(new PentahoEntityResolver());
configuration.setListener("load", new HibernateLoadEventListener()); //$NON-NLS-1$
if (hibernateConfigurationFile != null) {
String configPath = applicationContext.getSolutionPath(hibernateConfigurationFile);
File cfgFile = new File(configPath);
if (cfgFile.exists()) {
configuration.configure(cfgFile);
} else {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0012_CONFIG_NOT_FOUND", configPath)); //$NON-NLS-1$
return false;
}
} else {
configuration.configure(); // Read in the .xml document
}
String dsName = configuration.getProperty("connection.datasource"); //$NON-NLS-1$
if ((dsName != null) && dsName.toUpperCase().endsWith("HIBERNATE")) { //$NON-NLS-1$
String actualDSName = DatasourceHelper.getDSBoundName("Hibernate"); //$NON-NLS-1$
configuration.setProperty("hibernate.connection.datasource", actualDSName); //$NON-NLS-1$
}
dialect = configuration.getProperty("dialect"); //$NON-NLS-1$
setupConfigurationHandlers();
// Add in the classes we know about.
addConfigurations(configuration);
/*
* configuration.addResource("org/pentaho/repository/runtime/RuntimeElement.hbm.xml");
* //$NON-NLS-1$
* configuration.addResource("org/pentaho/repository/content/ContentLocation.hbm.xml");//$NON-NLS-1$
* configuration.addResource("org/pentaho/repository/content/ContentItem.hbm.xml");//$NON-NLS-1$
* configuration.addResource("org/pentaho/repository/content/ContentItemFile.hbm.xml");//$NON-NLS-1$
* configuration.addResource("org/pentaho/repository/DefinitionVersionManager.hbm.xml");//$NON-NLS-1$
*/
if (!hibernateManaged) {
log.info(Messages.getString("HIBUTIL.USER_HIBERNATEUNMANAGED")); //$NON-NLS-1$
sessionFactory = configuration.buildSessionFactory();
} else {
factoryJndiName = configuration.getProperty(Environment.SESSION_FACTORY_NAME);
if (factoryJndiName == null) {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0013_NO_SESSION_FACTORY"));//$NON-NLS-1$
return false;
}
log.info(Messages.getString("HIBUTIL.USER_HIBERNATEMANAGED")); //$NON-NLS-1$
configuration.buildSessionFactory(); // Let hibernate Bind it
// to JNDI...
}
Dialect.getDialect(configuration.getProperties());
DefinitionVersionManager.performAutoUpdateIfRequired();
return true;
} catch (Throwable ex) {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0006_BUILD_SESSION_FACTORY"), ex); //$NON-NLS-1$
throw new ExceptionInInitializerError(ex);
}
}
private static void setupConfigurationHandlers() {
ISystemSettings systemSettings = PentahoSystem.getSystemSettings();
List objectHandlerDefs = systemSettings.getSystemSettings("HibernatedObjectHandlers/*"); //$NON-NLS-1$
if ((objectHandlerDefs != null) && (objectHandlerDefs.size() > 0)) {
String handlerClass;
for (int i = 0; i < objectHandlerDefs.size(); i++) {
handlerClass = ((Node) objectHandlerDefs.get(i)).getText();
IHibernatedObjectExtensionList extension = (IHibernatedObjectExtensionList) PentahoSystem
.createObject(handlerClass);
if (extension != null) {
objectHandlers.add(extension);
}
}
} else {
// Handle old condition where it didn't exist in pentaho.xml
objectHandlers.add(new StdHibernateClassHandler());
}
}
private static void addConfigurations(Configuration theConfiguration) {
IHibernatedObjectExtensionList extension;
for (int i = 0; i < objectHandlers.size(); i++) {
extension = (IHibernatedObjectExtensionList) objectHandlers.get(i);
List resourceList = extension.getHibernatedObjectResourceList();
for (int j = 0; j < resourceList.size(); j++) {
theConfiguration.addResource((String) resourceList.get(j));
}
}
}
/**
* Returns the SessionFactory used for this static class.
*
* @return SessionFactory
*/
public static SessionFactory getSessionFactory() {
if (!hibernateManaged) {
return sessionFactory;
}
SessionFactory sf = null;
try {
if (iniCtx == null) {
iniCtx = new InitialContext();
}
String jndiName = factoryJndiName;
try {
sf = (SessionFactory) iniCtx.lookup(jndiName);
} catch (Exception ignored) {
}
if (sf == null) {
try {
sf = (SessionFactory) iniCtx.lookup("java:" + jndiName); //$NON-NLS-1$
} catch (Exception ignored) {
ignored.printStackTrace();
}
}
} catch (NamingException ignored) {
}
return sf;
}
/**
* Returns the original Hibernate configuration.
*
* @return Configuration
*/
public static Configuration getConfiguration() {
return configuration;
}
public static void updateSchema() throws RepositoryException {
PentahoSchemaUpdate upd = new PentahoSchemaUpdate(getConfiguration());
upd.execute(true, true);
}
/**
* Rebuild the SessionFactory with the static Configuration.
*
*/
public static void rebuildSessionFactory() throws RepositoryException {
if (!hibernateManaged) {
synchronized (lock) {
try {
sessionFactory = getConfiguration().buildSessionFactory();
} catch (Exception ex) {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0007_REBUILD_SESSION_FACTORY"), ex); //$NON-NLS-1$
throw new RepositoryException(Messages.getErrorString("HIBUTIL.ERROR_0007_REBUILD_SESSION_FACTORY"), ex); //$NON-NLS-1$
}
}
} else {
try {
getConfiguration().buildSessionFactory();
} catch (Exception ex) {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0007_REBUILD_SESSION_FACTORY"), ex); //$NON-NLS-1$
throw new RepositoryException(Messages.getErrorString("HIBUTIL.ERROR_0007_REBUILD_SESSION_FACTORY"), ex); //$NON-NLS-1$
}
}
}
/**
* Rebuild the SessionFactory with the given Hibernate Configuration.
*
* @param cfg
*/
public static void rebuildSessionFactory(Configuration cfg) throws RepositoryException {
if (!hibernateManaged) {
synchronized (lock) {
try {
sessionFactory = cfg.buildSessionFactory();
configuration = cfg;
} catch (Exception ex) {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0007_REBUILD_SESSION_FACTORY"), ex); //$NON-NLS-1$
throw new RepositoryException(Messages.getErrorString("HIBUTIL.ERROR_0007_REBUILD_SESSION_FACTORY"), ex); //$NON-NLS-1$
}
}
} else {
try {
cfg.buildSessionFactory();
configuration = cfg;
} catch (Exception ex) {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0007_REBUILD_SESSION_FACTORY"), ex); //$NON-NLS-1$
throw new RepositoryException(Messages.getErrorString("HIBUTIL.ERROR_0007_REBUILD_SESSION_FACTORY"), ex); //$NON-NLS-1$
}
}
}
/**
* Retrieves the current Session local to the thread. <p/> If no Session is
* open, opens a new Session for the running thread.
*
* @return Session
*/
public static Session getSession() throws RepositoryException {
Session s = (Session) threadSession.get();
try {
if (s == null) {
if (debug)
log.debug(Messages.getString("HIBUTIL.DEBUG_OPEN_NEW_SESSION")); //$NON-NLS-1$
if (getInterceptor() != null) {
if (debug)
log.debug(Messages.getString("HIBUTIL.DEBUG_USING_INTERCEPTOR") + getInterceptor().getClass()); //$NON-NLS-1$
s = getSessionFactory().openSession(getInterceptor());
} else {
s = getSessionFactory().openSession();
}
threadSession.set(s);
}
} catch (HibernateException ex) {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0005_GET_SESSION"), ex); //$NON-NLS-1$
throw new RepositoryException(Messages.getErrorString("HIBUTIL.ERROR_0005_GET_SESSION"), ex); //$NON-NLS-1$
}
return s;
}
public static void flushSession() throws RepositoryException {
try {
Session s = getSession();
s.flush();
} catch (HibernateException ex) {
throw new RepositoryException(ex);
}
}
/**
* Closes the Session local to the thread.
*/
public static void closeSession() throws RepositoryException {
try {
Session s = (Session) threadSession.get();
threadSession.set(null);
if (s != null && s.isOpen()) {
if (debug)
log.debug(Messages.getString("HIBUTIL.DEBUG_CLOSING_SESSION")); //$NON-NLS-1$
s.close();
}
threadTransaction.set(null);
} catch (HibernateException ex) {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0009_CLOSE_SESSION"), ex); //$NON-NLS-1$
threadTransaction.set(null);
throw new RepositoryException(Messages.getErrorString("HIBUTIL.ERROR_0009_CLOSE_SESSION"), ex); //$NON-NLS-1$
}
}
/**
* Start a new database transaction.
*/
public static void beginTransaction() throws RepositoryException {
// commitNeeded.set(Boolean.TRUE);
Transaction tx = (Transaction) threadTransaction.get();
try {
if (tx == null) {
if (debug)
log.debug(Messages.getString("HIBUTIL.DEBUG_START_TRANS")); //$NON-NLS-1$
tx = getSession().beginTransaction();
threadTransaction.set(tx);
}
} catch (HibernateException ex) {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0004_START_TRANS"), ex); //$NON-NLS-1$
throw new RepositoryException(Messages.getErrorString("HIBUTIL.ERROR_0004_START_TRANS"), ex); //$NON-NLS-1$
}
}
/**
* Commit the database transaction.
*/
public static void commitTransaction() throws RepositoryException {
// Boolean needed = (Boolean)commitNeeded.get();
// if (needed.booleanValue()){
Transaction tx = (Transaction) threadTransaction.get();
try {
if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
if (debug)
log.debug(Messages.getString("HIBUTIL.DEBUG_COMMIT_TRANS")); //$NON-NLS-1$
tx.commit();
}
} catch (HibernateException ex) {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0008_COMMIT_TRANS"), ex); //$NON-NLS-1$
try {
rollbackTransaction();
} catch (Exception e2) {
}
// throw new
// RepositoryException(Messages.getErrorString("HIBUTIL.ERROR_0008_COMMIT_TRANS"),
// ex); //$NON-NLS-1$
} finally {
threadTransaction.set(null);
}
// }
// commitNeeded.set(Boolean.FALSE);
}
/**
* Commit the database transaction.
*/
public static void rollbackTransaction() throws RepositoryException {
Transaction tx = (Transaction) threadTransaction.get();
try {
threadTransaction.set(null);
if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
if (debug)
log.debug(Messages.getString("HIBUTIL.DEBUG_ROLLBACK")); //$NON-NLS-1$
tx.rollback();
}
} catch (HibernateException ex) {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0003_ROLLBACK"), ex); //$NON-NLS-1$
throw new RepositoryException(Messages.getErrorString("HIBUTIL.ERROR_0003_ROLLBACK"), ex); //$NON-NLS-1$
} finally {
closeSession();
}
}
/**
* Reconnects a Hibernate Session to the current Thread.
*
* @param session
* The Hibernate Session to be reconnected.
*/
/*
* public static void reconnect(Session session) throws RepositoryException {
* try { session.reconnect(); threadSession.set(session); } catch
* (HibernateException ex) {
* log.error(Messages.getErrorString("HIBUTIL.ERROR_0001_RECONNECT"), ex);
* //$NON-NLS-1$ throw new RepositoryException(ex); } }
*/
/**
* Disconnect and return Session from current Thread.
*
* @return Session the disconnected Session
*/
public static Session disconnectSession() throws RepositoryException {
Session session = getSession();
try {
threadSession.set(null);
if (session.isConnected() && session.isOpen())
session.disconnect();
} catch (HibernateException ex) {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0002_DISCONNECT"), ex); //$NON-NLS-1$
throw new RepositoryException(Messages.getErrorString("HIBUTIL.ERROR_0002_DISCONNECT"), ex); //$NON-NLS-1$
}
return session;
}
/**
* Register a Hibernate interceptor with the current thread.
* <p>
* Every Session opened is opened with this interceptor after registration.
* Has no effect if the current Session of the thread is already open,
* effective on next close()/getSession().
*/
public static void registerInterceptor(Interceptor interceptor) {
threadInterceptor.set(interceptor);
}
private static Interceptor getInterceptor() {
Interceptor interceptor = (Interceptor) threadInterceptor.get();
return interceptor;
}
/**
* Searches an ISearchable object for a search term. The search rules are as
* follows:
*
* If the searchType is ISearchable.SEARCH_TYPE_PHRASE, then the fields in
* the table are searched for the exact phrase given.
*
* If the searchType is ISearchable.SEARCH_TYPE_WORDS_AND or ..._OR, then
* the following happens: a- Each word in the searchTerm is extracted and
* put into a list of search terms. b- Each search term is surrounded by the
* SQL wildcard '%'. So each search term becomes %term%. c- A dynamic query
* is generated searching each of the columns for each search term d- The
* searchType is used to determine the connector between each search term.
* e- The AND will match only if all of the terms appear in a specific
* column - cross-column searching using ..._AND will NOT work. In other
* words, if your search term is "East Sales", and your search type is
* ..._AND, a row will be returned if one of the columns contains East and
* the same column contains Sales. A row will NOT be returned if one column
* only contains East, and another column only contains Sales. This type of
* functionality could be obtained using a view that concatenates all of the
* searchable columns together into one large column, but this would be
* costly and database-specific.
*
* @param searchable
* ISearchable to search
* @param searchTerm
* Search Term - see above for rules
* @param searchType
* One of:
* ISearchable.SEARCH_TYPE_PHRASE,ISearchable.SEARCH_TYPE_WORDS_AND,
* ISearchable.SEARCH_TYPE_WORDS_OR
* @return A list of objects from Hibernate that met the conditions
* specified.
*/
public static List searchForTerm(ISearchable searchable, String searchTerm, int searchType) {
Session session = getSession();
if (searchType == ISearchable.SEARCH_TYPE_PHRASE) {
Query qry = session.getNamedQuery(searchable.getPhraseSearchQueryName());
String searchWildcard = MessageUtil.formatErrorMessage(QUERYWILDCARD, searchTerm);
qry.setString("searchTerm", searchWildcard); //$NON-NLS-1$
List rtn = qry.list();
return rtn;
}
String connector;
if (searchType == ISearchable.SEARCH_TYPE_WORDS_AND) {
connector = " and "; //$NON-NLS-1$
} else {
connector = " or "; //$NON-NLS-1$
}
StringTokenizer st = new StringTokenizer(searchTerm, " "); //$NON-NLS-1$
List searchWords = new ArrayList();
while (st.hasMoreTokens()) {
searchWords.add(MessageUtil.formatErrorMessage(QUERYWILDCARD, st.nextToken()));
}
// Ok, we now have a list of search words.
StringBuffer assembly = assembleQuery(searchable.getSearchableTable(), connector, searchWords, searchable
.getSearchableColumns());
Query qry = session.createQuery(assembly.toString());
for (int j = 0; j < searchWords.size(); j++) {
qry.setParameter("searchTerm" + j, searchWords.get(j)); //$NON-NLS-1$
}
List rtn = qry.list();
return rtn;
}
private static StringBuffer assembleQuery(String tableName, String connector, List terms, String[] columns) {
StringBuffer qry = new StringBuffer();
qry.append("from ").append(tableName).append(" tbl where "); //$NON-NLS-1$ //$NON-NLS-2$
String currCol, term;
for (int colno = 0; colno < columns.length; colno++) {
currCol = columns[colno];
qry.append("("); //$NON-NLS-1$
for (int termNo = 0; termNo < terms.size(); termNo++) {
term = (String) terms.get(termNo);
qry.append("tbl.").append(currCol).append(" like :searchTerm").append(term).append(" "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
if (termNo < terms.size() - 1) {
qry.append(connector);
}
}
qry.append(")"); //$NON-NLS-1$
if (colno < columns.length - 1) {
qry.append(" or "); // Columns are always or'd //$NON-NLS-1$
}
}
return qry;
}
public static void clear() {
getSession().clear();
}
/**
* Persists changes to the object. Object must be defined to hibernate.
*
* @param obj
* The object to make persistent
* @throws RepositoryException
*/
public static void makePersistent(Object obj) throws RepositoryException {
if (debug)
log.debug(Messages.getString("HIBUTIL.DEBUG_MAKE_PERSISTENT", obj.toString())); //$NON-NLS-1$
try {
getSession().saveOrUpdate(obj);
} catch (HibernateException ex) {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0010_SAVING_UPDATING"), ex); //$NON-NLS-1$
throw new ContentException(Messages.getErrorString("HIBUTIL.ERROR_0010_SAVING_UPDATING"), ex); //$NON-NLS-1$
}
}
/**
* Deletes the object from Hibernate
*
* @param obj
* The object to make transient
* @throws RepositoryException
*/
public static void makeTransient(Object obj) throws RepositoryException {
if (debug)
log.debug(Messages.getString("HIBUTIL.DEBUG_MAKE_TRANSIENT", obj.toString())); //$NON-NLS-1$
try {
getSession().delete(obj);
} catch (HibernateException ex) {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0011_DELETING_OBJ"), ex); //$NON-NLS-1$
throw new ContentException(Messages.getErrorString("HIBUTIL.ERROR_0011_DELETING_OBJ"), ex); //$NON-NLS-1$
}
}
/**
* HACK This method is necessary to determine whether code should execute based on Oracle
* in use as the RDBMS repository for the platform. Helps us work around Oracle
* JDBC driver bugs.
*
* @return true if Hibernate dialect for oracle is in use.
*/
public static boolean isOracleDialect(){
return dialect.indexOf("oracle") >= 0 || //$NON-NLS-1$
dialect.indexOf("Oracle") >= 0 || //$NON-NLS-1$
dialect.indexOf("ORACLE") >= 0; //$NON-NLS-1$
}
/**
* Evicts the object from the Hibernate cache. Call this if you don't
* believe you'll need this object in the cache. This is also good to call
* if you're doing semi-mass updates.
*
* @param obj
*/
public static void evict(Object obj) {
// if (debug)
// log.debug(Messages.getString("HIBUTIL.DEBUG_EVICT", obj.toString())); //$NON-NLS-1$
try {
getSession().evict(obj);
} catch (HibernateException ex) {
log.error(Messages.getErrorString("HIBUTIL.ERROR_0014_EVICTING_OBJECT"), ex); //$NON-NLS-1$
}
}
public static List getHibernatedObjectHandlerList() {
return objectHandlers;
}
public void systemEntryPoint() {
// No need to do anything for Hibernate here.
}
public void systemExitPoint() {
try {
HibernateUtil.commitTransaction();
} catch (Throwable t) {
// get some real logging code in here
t.printStackTrace();
}
try {
HibernateUtil.closeSession();
} catch (Throwable t) {
// get some real logging code in here
t.printStackTrace();
}
}
}
The table below shows all metrics for HibernateUtil.java.




