diff --git a/Jenkinsfile b/Jenkinsfile index de276d66652..4ecbf3d359a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -69,7 +69,7 @@ stage('Build') { println "AMP Version: ${codeVersion}" //Used in the initial generation of keys when working with a new jenkins instance //**************************************************************** -// sh "ssh-keygen -t rsa -b 4096 -C 'jenkins@${environment}' -f ~/.ssh/id_rsa -N ''" +// sh "ssh-keygen -t rsa -b 4096 -C '${env.jenkinsUser}@${environment}' -f ~/.ssh/id_rsa -N ''" sh "ssh-keyscan -H ${environment} >> ~/.ssh/known_hosts" // sh "cat /root/.ssh/id_rsa.pub" //****************************************************** diff --git a/amp/src/main/java/org/dgfoundation/amp/onepager/HibernateRequestCycleListener.java b/amp/src/main/java/org/dgfoundation/amp/onepager/HibernateRequestCycleListener.java new file mode 100644 index 00000000000..13b67883f1b --- /dev/null +++ b/amp/src/main/java/org/dgfoundation/amp/onepager/HibernateRequestCycleListener.java @@ -0,0 +1,89 @@ +package org.dgfoundation.amp.onepager; + +import org.apache.wicket.request.IRequestHandler; +import org.apache.wicket.request.cycle.AbstractRequestCycleListener; +import org.apache.wicket.request.cycle.RequestCycle; +import org.digijava.kernel.persistence.PersistenceManager; +import org.hibernate.Session; +import org.hibernate.Transaction; + +/** + * Wicket request cycle listener that manages Hibernate session lifecycle + * for each web request. + */ +public class HibernateRequestCycleListener extends AbstractRequestCycleListener { + private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(HibernateRequestCycleListener.class); + + @Override + public void onBeginRequest(RequestCycle cycle) { + if (PersistenceManager.isSessionManaged()) { + logger.warn("Session already exists when starting new request - possible nesting issue"); + return; + } + + try { + Session session = PersistenceManager.getSession(); + if (!session.getTransaction().isActive()) { + session.beginTransaction(); + } + logger.debug("Started new session and transaction for request"); + } catch (Exception e) { + logger.error("Failed to start Hibernate session for request", e); + throw new RuntimeException("Failed to initialize Hibernate session", e); + } + } + + @Override + public void onEndRequest(RequestCycle cycle) { + try { + Session session = PersistenceManager.getSession(); + if (session == null || !session.isOpen()) { + logger.debug("No active session to close at end of request"); + return; + } + + Transaction transaction = session.getTransaction(); + try { + if (transaction.isActive()) { + if (transaction.getStatus().canRollback()) { + transaction.commit(); + logger.debug("Successfully committed transaction"); + } else { + logger.warn("Transaction in unexpected state: " + transaction.getStatus()); + } + } + } catch (Exception e) { + logger.error("Error during transaction commit - attempting rollback", e); + try { + if (transaction.isActive()) { + transaction.rollback(); + logger.debug("Rolled back transaction after error"); + } + } catch (Exception rollbackEx) { + logger.error("Failed to rollback transaction", rollbackEx); + } + throw new RuntimeException("Failed to commit transaction", e); + } + } finally { + try { + PersistenceManager.cleanupThread(); + logger.debug("Cleaned up thread resources"); + } catch (Exception e) { + logger.error("Error during thread cleanup", e); + } + } + } + + @Override + public void onDetach(RequestCycle cycle) { + // Ensure cleanup even if request processing fails + PersistenceManager.cleanupThread(); + } + + @Override + public IRequestHandler onException(RequestCycle cycle, Exception ex) { + logger.error("Exception occurred during request processing - cleaning up session", ex); + PersistenceManager.cleanupThread(); + return null; + } +} diff --git a/amp/src/main/java/org/dgfoundation/amp/onepager/OnePagerApp.java b/amp/src/main/java/org/dgfoundation/amp/onepager/OnePagerApp.java index dbbb3902cf4..bd32cb3652a 100644 --- a/amp/src/main/java/org/dgfoundation/amp/onepager/OnePagerApp.java +++ b/amp/src/main/java/org/dgfoundation/amp/onepager/OnePagerApp.java @@ -69,6 +69,7 @@ public void init() { WicketSource.configure(this); IS_DEVELOPMENT_MODE = true; } + getRequestCycleListeners().add(new HibernateRequestCycleListener()); //getResourceSettings().setStripJavaScriptCommentsAndWhitespace(true); //getResourceSettings().setAddLastModifiedTimeToResourceReferenceUrl(true); diff --git a/amp/src/main/java/org/dgfoundation/amp/onepager/models/AmpActivityModel.java b/amp/src/main/java/org/dgfoundation/amp/onepager/models/AmpActivityModel.java index ded00f87de3..2e39acdc3df 100644 --- a/amp/src/main/java/org/dgfoundation/amp/onepager/models/AmpActivityModel.java +++ b/amp/src/main/java/org/dgfoundation/amp/onepager/models/AmpActivityModel.java @@ -87,7 +87,7 @@ public void beginConversation(boolean reset) { * @return */ public static Session getHibernateSession(){ - return getHibernateSession(false); + return PersistenceManager.getSession(); } private static Session getHibernateSession(boolean reset) { diff --git a/amp/src/main/java/org/dgfoundation/amp/onepager/util/ActivityUtil.java b/amp/src/main/java/org/dgfoundation/amp/onepager/util/ActivityUtil.java index 207728fe54b..a14261fcb5a 100644 --- a/amp/src/main/java/org/dgfoundation/amp/onepager/util/ActivityUtil.java +++ b/amp/src/main/java/org/dgfoundation/amp/onepager/util/ActivityUtil.java @@ -178,6 +178,7 @@ public static AmpActivityVersion saveActivityNewVersion(AmpActivityVersion a, * saves a new version of an activity * returns newActivity */ + public static AmpActivityVersion saveActivityNewVersion(AmpActivityVersion a, Collection translations, List cumulativeTranslations, AmpTeamMember ampCurrentMember, boolean draft, @@ -234,6 +235,7 @@ public static AmpActivityVersion saveActivityNewVersion(AmpActivityVersion a, } session.flush(); + session.clear(); } catch (CloneNotSupportedException e) { logger.error("Can't clone current Activity: ", e); @@ -307,6 +309,7 @@ public static AmpActivityVersion saveActivityNewVersion(AmpActivityVersion a, session.merge(a); } session.flush(); + session.clear(); updatePerformanceRules(oldA, a); diff --git a/amp/src/main/java/org/digijava/kernel/persistence/PersistenceManager.java b/amp/src/main/java/org/digijava/kernel/persistence/PersistenceManager.java index a8ed85d19f5..28dd09e0137 100644 --- a/amp/src/main/java/org/digijava/kernel/persistence/PersistenceManager.java +++ b/amp/src/main/java/org/digijava/kernel/persistence/PersistenceManager.java @@ -56,6 +56,7 @@ import java.sql.SQLException; import java.util.*; import java.util.Map.Entry; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; @@ -65,6 +66,10 @@ public class PersistenceManager { private static SessionFactory sf; private static Configuration cfg; private static Logger logger = I18NHelper.getKernelLogger(PersistenceManager.class); + private static final AtomicInteger activeSessions = new AtomicInteger(); + + + private static final HashMap sessionStackTraceMap = new HashMap<>(); public static String PRECACHE_REGION = "org.digijava.kernel.persistence.PersistenceManager.precache_region"; @@ -75,7 +80,8 @@ public class PersistenceManager { */ public static final long MAX_HIBERNATE_SESSION_LIFE_MILLIS=60*60*1000; - private static final HashMap sessionStackTraceMap = new HashMap<>(); + + /** * Invoked at the end of each request. Iterates and removes Hibernate closed sessions from the trace map. @@ -83,53 +89,31 @@ public class PersistenceManager { * The {@link HashMap} is synchronized to prevent concurrency issues between HTTP threads */ public static void checkClosedOrLongSessionsFromTraceMap() { - // remove closed sessions synchronized (sessionStackTraceMap) { - Iterator iterator = PersistenceManager.sessionStackTraceMap - .keySet().iterator(); + Iterator iterator = sessionStackTraceMap.keySet().iterator(); while (iterator.hasNext()) { - Session session = (Session) iterator.next(); - - - // force closure of long running sessions - Long millis = (Long) sessionStackTraceMap.get(session)[0]; - if (session.isOpen() && ( System.currentTimeMillis() - millis > MAX_HIBERNATE_SESSION_LIFE_MILLIS )) { - StackTraceElement[] stackTrace = (StackTraceElement[]) sessionStackTraceMap - .get(session)[1]; - logger.info("Forcing closure and removal of hibernate session " - + session.hashCode() - + " because it ran for longer than " - + MAX_HIBERNATE_SESSION_LIFE_MILLIS - / 1000 - + " seconds"); - logger.info("Please review the code that generated the following recorded stack trace and ensure this session is closed properly: "); - for (int i = 0; i < stackTrace.length && i < 8; i++) logger.info(stackTrace[i].toString()); + Session session = iterator.next(); - - try { - session.getTransaction().commit(); - } catch (Throwable e) { - e.printStackTrace(); + if (session.isOpen() && (System.currentTimeMillis() - (Long) sessionStackTraceMap.get(session)[0] > MAX_HIBERNATE_SESSION_LIFE_MILLIS)) { + StackTraceElement[] stackTrace = (StackTraceElement[]) sessionStackTraceMap.get(session)[1]; + logger.warn("Forcing closure of long-running session " + session.hashCode()); + for (int i = 0; i < stackTrace.length && i < 8; i++) { + logger.warn(stackTrace[i].toString()); } try { - session.clear(); - } catch (Throwable e) { - e.printStackTrace(); - } - - - try { + if (session.getTransaction().isActive()) { + session.getTransaction().rollback(); + } session.close(); } catch (Throwable e) { - e.printStackTrace(); + logger.error("Error forcing session closure", e); } } - // remove closed sessions - if (!session.isOpen()) iterator.remove(); - - + if (!session.isOpen()) { + iterator.remove(); + } } } } @@ -152,6 +136,15 @@ private static void removeClosedSessionsFromMap() { logger.debug( count + " closed sessions were removed from 'sessionStackTraceMap' "); } + public static void cleanupThread() { + Session session = threadSession.get(); + if (session != null) { + closeSession(session); + } + threadSession.remove(); + CURRENT_SESSION_IS_MANAGED.remove(); + } + /** * Opens a new Hibernate session. Use this with caution. * For servlets you will not require to use this, use {@link #getSession()} instead! @@ -159,10 +152,14 @@ private static void removeClosedSessionsFromMap() { * @return */ public static Session openNewSession() { - org.hibernate.Session openSession = sf.openSession(); - return openSession; + Session session = sf.openSession(); + activeSessions.incrementAndGet(); + addSessionToStackTraceMap(session); + logger.debug("Opened new unmanaged session. Active sessions: " + activeSessions.get()); + return session; } + /** * Returns the metadata for the given class from session factory * @param clazz @@ -171,15 +168,14 @@ public static Session openNewSession() { public static ClassMetadata getClassMetadata(Class clazz) { return sf.getClassMetadata(clazz); } + private static final ThreadLocal threadSession = new ThreadLocal<>(); - public static PersistentClass getClassMapping(Class clazz) - { - - StandardServiceRegistry registry = new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build(); + public static PersistentClass getClassMapping(Class clazz) { + StandardServiceRegistry registry = new StandardServiceRegistryBuilder() + .applySettings(cfg.getProperties()).build(); MetadataSources sources = new MetadataSources(registry); Metadata metadata = sources.buildMetadata(); return metadata.getEntityBinding(clazz.getName()); -// return cfg.getClassMapping(clazz.getName()); } /** @@ -206,31 +202,24 @@ public static Connection getJdbcConnection() throws SQLException { * This needs to be invoked (as Hibernate's APIs suggests) before {@link SessionFactory#close()} is invoked at the very end of AMP lifecycle */ public static void closeUnclosedSessionsFromTraceMap() { - // print open sessions - boolean found=false; synchronized (sessionStackTraceMap) { - Iterator iterator = PersistenceManager.sessionStackTraceMap.keySet().iterator(); + Iterator iterator = sessionStackTraceMap.keySet().iterator(); while (iterator.hasNext()) { - Session session = (Session) iterator.next(); - if(session.isOpen()) { - found=true; - Object o[] = sessionStackTraceMap.get(session); - StackTraceElement[] stackTraceElements = (StackTraceElement[]) o[1]; - logger.info("Session opened "+(System.currentTimeMillis()-(Long)o[0])+" miliseconds ago is still open. Will force closure, recorded stack trace: "); - for (int i = 3; i < stackTraceElements.length && i < 8; i++) logger.info(stackTraceElements[i].toString()); - logger.info("Forcing Hibernate session close..."); - try { - session.clear(); + Session session = iterator.next(); + if (session.isOpen()) { + Object[] o = sessionStackTraceMap.get(session); + logger.warn("Force closing session opened " + (System.currentTimeMillis() - (Long) o[0]) + "ms ago"); + try { + if (session.getTransaction().isActive()) { + session.getTransaction().rollback(); + } session.close(); - logger.info("Hibernate Session Close succeeded"); } catch (Throwable t) { - logger.info("Error while forcing Hibernate session close:"); - logger.error(t.getMessage(), t); + logger.error("Error closing session", t); } - logger.error("----------------------------------"); } + iterator.remove(); } - if(found) logger.info("Check the code around the above stack traces, commit transactions only if not using HTTP threads:"); } } @@ -244,28 +233,22 @@ public static void initialize(boolean precache) { } public static synchronized void initialize(boolean precache, String target) { - DigiConfig config = null; HashMap modulesConfig = null; try { config = DigiConfigManager.getConfig(); - logger.debug("Initializing persistence manager"); - // load kernel hibernate classes HibernateClassLoader.initialize(config); - if (target != null) { - if (!target.equalsIgnoreCase("kernel")) { - Object modConfig = DigiConfigManager.getModulesConfig().get(target); - if (modConfig != null) { - modulesConfig = new HashMap(); - modulesConfig.put(target, modConfig); - } + if (target != null && !target.equalsIgnoreCase("kernel")) { + Object modConfig = DigiConfigManager.getModulesConfig().get(target); + if (modConfig != null) { + modulesConfig = new HashMap(); + modulesConfig.put(target, modConfig); } - } - else { + } else { modulesConfig = DigiConfigManager.getModulesConfig(); } @@ -282,14 +265,9 @@ public static synchronized void initialize(boolean precache, String target) { if (precache) { precache(); } - } - catch (Exception ex) { - //String errKey = "PersistenceManager.intialize.error"; - //logger.l7dlog(Level.FATAL, errKey, null, ex); + } catch (Exception ex) { logger.fatal("Unable to initialize PersistenceManager", ex); - } - } /** @@ -466,14 +444,12 @@ public static void cleanup() { logger.debug("cleanup() called"); if (sf != null) { try { + closeUnclosedSessionsFromTraceMap(); sf.close(); - } - catch (HibernateException ex) { + } catch (HibernateException ex) { logger.error("Error cleaning up persistence manager", ex); } } - - } @@ -554,39 +530,88 @@ public static void inTransaction(Runnable runnable) { } public static T supplyInTransaction(Supplier supplier) { - boolean prevManagedFlag = CURRENT_SESSION_IS_MANAGED.get(); + Session session = getSessionWithoutBeginningTransaction(); + boolean existingTransaction = session.getTransaction().isActive(); + Transaction transaction = null; + boolean committed = false; + try { - CURRENT_SESSION_IS_MANAGED.set(true); - return supplier.get(); - } catch (Throwable e) { - PersistenceManager.rollbackCurrentSessionTx(); - throw e; + if (!existingTransaction) { + logger.debug("Starting new transaction..."); + transaction = session.beginTransaction(); + logger.debug("Transaction started: " + transaction.isActive()); + } + + T result = supplier.get(); + + if (!existingTransaction) { + logger.debug("Committing transaction status..."+ transaction.getStatus()); + if (transaction.getStatus().equals(TransactionStatus.ACTIVE)) { + transaction.commit(); + committed = true; + } + } + + return result; + } catch (Exception e) { + if (!existingTransaction && transaction != null && transaction.isActive()) { + try { + logger.info("Rolling back after exception"); + transaction.rollback(); + } catch (HibernateException he) { + logger.error("Failed to rollback transaction", he); + } + } + throw new RuntimeException("Transaction failed", e); } finally { - PersistenceManager.endSessionLifecycle(); - CURRENT_SESSION_IS_MANAGED.set(prevManagedFlag); + if (!existingTransaction && session != null && session.isOpen()) { + try { + if (!committed && session.getTransaction().isActive()) { + session.getTransaction().rollback(); + } + session.close(); + } catch (HibernateException e) { + logger.error("Failed to close session", e); + } + clearCurrentSession(); + } } } + /** * Returns the current Session. If there is none, creates one and returns it * upon creating a new session, a transaction is created. */ public static Session getSession() { - boolean currentSessionIsManaged = CURRENT_SESSION_IS_MANAGED.get(); - if (!currentSessionIsManaged) { - throw new IllegalStateException("Called outside of managed session context."); + Session session = getSessionWithoutBeginningTransaction(); + if (session.getTransaction() == null || !session.getTransaction().isActive()) { + session.beginTransaction(); } - Session sess = sf().getCurrentSession(); - sess.setFlushMode(FlushModeType.AUTO); - Transaction transaction = sess.getTransaction(); - if (transaction == null || !transaction.isActive()) { - sess.beginTransaction(); + return session; + } + + public static Session getSessionWithoutBeginningTransaction() { + Session session = threadSession.get(); + if (session == null || !session.isOpen()) { + session = sf.openSession(); + session.setFlushMode(FlushModeType.AUTO); + threadSession.set(session); + addSessionToStackTraceMap(session); } -// sess.clear(); + return session; + } + + public static void setCurrentSession(Session session) { + threadSession.set(session); + } + public static void clearCurrentSession() { + threadSession.remove(); + } - addSessionToStackTraceMap(sess); - return sess; + public static boolean isSessionManaged() { + return CURRENT_SESSION_IS_MANAGED.get(); } /** @@ -600,14 +625,17 @@ public static Session getRequestDBSession() { * Adds this session to the stack trace map, so its closing can be tracked later * @param sess */ - public static void addSessionToStackTraceMap(Session sess) { - synchronized (sessionStackTraceMap){ - if(sessionStackTraceMap.get(sess)==null) - //logger.error(String.format("Thread #%d: storing new Session %d", Thread.currentThread().getId(), System.identityHashCode(sess))); - sessionStackTraceMap.put(sess,new Object[] {System.currentTimeMillis(),Thread.currentThread().getStackTrace()}); + private static void addSessionToStackTraceMap(Session sess) { + synchronized (sessionStackTraceMap) { + if (!sessionStackTraceMap.containsKey(sess)) { + sessionStackTraceMap.put(sess, new Object[] { + System.currentTimeMillis(), + Thread.currentThread().getStackTrace(), + new Exception("Session creation point") + }); + } } } - /** * Removes object from Hibernate second-level cache, loads it from database * and initializes @@ -747,15 +775,26 @@ public static SessionFactory sf() { */ public static void closeSession(Session session) { if (session == null) return; + try { - flushAndCommit(session); - } catch (HibernateException e) { - // logging the error since finally may throw another exception and this one will be lost - logger.error("Failed to commit.", e); - throw e; - } finally { if (session.isOpen()) { + if (session.getTransaction().isActive()) { + try { + session.getTransaction().rollback(); + } catch (HibernateException e) { + logger.error("Failed to rollback transaction during close", e); + } + } session.close(); + activeSessions.decrementAndGet(); + logger.debug("Closed unmanaged session. Active sessions: " + activeSessions.get()); + } + } catch (HibernateException e) { + logger.error("Failed to close session", e); + } finally { + removeSessionFromMap(session); + if (session.equals(threadSession.get())) { + clearCurrentSession(); } } } @@ -821,12 +860,7 @@ public static void cleanupSession(Session session) { private static void removeSessionFromMap(Session session) { synchronized (sessionStackTraceMap) { - if (sessionStackTraceMap.containsKey(session)) { - //logger.error(String.format("Thread #%d: removing Session %d", Thread.currentThread().getId(), System.identityHashCode(session))); - sessionStackTraceMap.remove(session); - } else { - //logger.error(String.format("Thread #%d: trying to cleanup nonexisting Session %d", Thread.currentThread().getId(), System.identityHashCode(session))); - } + sessionStackTraceMap.remove(session); } } diff --git a/amp/src/main/java/org/digijava/module/aim/action/dataimporter/ExcelImporter.java b/amp/src/main/java/org/digijava/module/aim/action/dataimporter/ExcelImporter.java index d41c5e64c98..651e0d6d3f8 100644 --- a/amp/src/main/java/org/digijava/module/aim/action/dataimporter/ExcelImporter.java +++ b/amp/src/main/java/org/digijava/module/aim/action/dataimporter/ExcelImporter.java @@ -141,7 +141,7 @@ public static void processBatch(List batch,Sheet sheet, HttpServletRequest importDataModel.setModified_by(TeamMemberUtil.getCurrentAmpTeamMember(request).getAmpTeamMemId()); importDataModel.setCreated_by(TeamMemberUtil.getCurrentAmpTeamMember(request).getAmpTeamMemId()); importDataModel.setTeam(TeamMemberUtil.getCurrentAmpTeamMember(request).getAmpTeam().getAmpTeamId()); - importDataModel.setIs_draft(true); + importDataModel.setIs_draft(false); OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC); importDataModel.setCreation_date(now.format(formatter)); setStatus(importDataModel); diff --git a/amp/src/main/java/org/digijava/module/aim/action/dataimporter/util/ImporterUtil.java b/amp/src/main/java/org/digijava/module/aim/action/dataimporter/util/ImporterUtil.java index 357fc6c0c79..f07e91160fb 100644 --- a/amp/src/main/java/org/digijava/module/aim/action/dataimporter/util/ImporterUtil.java +++ b/amp/src/main/java/org/digijava/module/aim/action/dataimporter/util/ImporterUtil.java @@ -13,6 +13,7 @@ import org.digijava.kernel.ampapi.endpoints.activity.ActivityInterchangeUtils; import org.digijava.kernel.ampapi.endpoints.activity.dto.ActivitySummary; import org.digijava.kernel.ampapi.endpoints.common.JsonApiResponse; +import org.digijava.kernel.ampapi.filters.AmpClientModeHolder; import org.digijava.kernel.persistence.PersistenceManager; import org.digijava.module.aim.action.dataimporter.dbentity.ImportStatus; import org.digijava.module.aim.action.dataimporter.dbentity.ImportedProject; @@ -622,6 +623,7 @@ public static void importTheData(ImportDataModel importDataModel, Session sessio importDataModel.setProject_title(existing.getName()); importDataModel.setProject_code(!Objects.equals(importDataModel.getProject_code(), "") ? importDataModel.getProject_code() : existing.getProjectCode()); updateFundingOrgsAndSectorsWithAlreadyExisting(existing, importDataModel); + map = objectMapper .convertValue(importDataModel, new TypeReference>() { }); @@ -655,6 +657,7 @@ public static void importTheData(ImportDataModel importDataModel, Session sessio logger.info("Imported project: " + importedProject); } + private static void updateFundingOrgsAndSectorsWithAlreadyExisting(AmpActivityVersion ampActivityVersion, ImportDataModel importDataModel) { if (ampActivityVersion.getFunding() != null) { diff --git a/amp/src/main/java/org/digijava/module/message/jobs/ConnectionCleaningJob.java b/amp/src/main/java/org/digijava/module/message/jobs/ConnectionCleaningJob.java index e1b512e1d98..56237868e23 100644 --- a/amp/src/main/java/org/digijava/module/message/jobs/ConnectionCleaningJob.java +++ b/amp/src/main/java/org/digijava/module/message/jobs/ConnectionCleaningJob.java @@ -6,7 +6,7 @@ import org.quartz.JobExecutionException; public abstract class ConnectionCleaningJob implements Job { - + @Override public final void execute(JobExecutionContext context) throws JobExecutionException { try { if (shouldExecuteInTransaction()) { @@ -28,7 +28,7 @@ public abstract class ConnectionCleaningJob implements Job { } } } - + public abstract void executeInternal(JobExecutionContext context) throws JobExecutionException; public boolean shouldExecuteInTransaction() { diff --git a/amp/src/main/resources/hibernate.cfg.xml b/amp/src/main/resources/hibernate.cfg.xml index ef0d674d819..3b9d209ae6f 100644 --- a/amp/src/main/resources/hibernate.cfg.xml +++ b/amp/src/main/resources/hibernate.cfg.xml @@ -6,11 +6,12 @@ java:comp/env/ampDS org.dgfoundation.amp.ar.viewfetcher.AmpPostgresDialect &dialect; - org.hibernate.context.internal.ThreadLocalSessionContext + thread true create 0 20 + AUTO true true org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory