001
014
015 package com.liferay.portal.dao.orm.hibernate.event;
016
017 import java.util.Map;
018
019 import org.hibernate.FlushMode;
020 import org.hibernate.HibernateException;
021 import org.hibernate.engine.ActionQueue;
022 import org.hibernate.engine.PersistenceContext;
023 import org.hibernate.engine.SessionFactoryImplementor;
024 import org.hibernate.event.AutoFlushEvent;
025 import org.hibernate.event.EventSource;
026 import org.hibernate.event.def.DefaultAutoFlushEventListener;
027 import org.hibernate.stat.Statistics;
028 import org.hibernate.stat.StatisticsImplementor;
029
030
033 public class NestableAutoFlushEventListener
034 extends DefaultAutoFlushEventListener {
035
036 public static final NestableAutoFlushEventListener INSTANCE =
037 new NestableAutoFlushEventListener();
038
039 @Override
040 public void onAutoFlush(AutoFlushEvent autoFlushEvent)
041 throws HibernateException {
042
043 EventSource eventSource = autoFlushEvent.getSession();
044
045 if (!isFlushable(eventSource)) {
046 return;
047 }
048
049 ActionQueue actionQueue = eventSource.getActionQueue();
050
051 int oldSize = actionQueue.numberOfCollectionRemovals();
052
053 flushEverythingToExecutions(autoFlushEvent);
054
055 PersistenceContext persistenceContext =
056 eventSource.getPersistenceContext();
057
058 if (isFlushReallyNeeded(autoFlushEvent, eventSource)) {
059 persistenceContext.setFlushing(true);
060
061 try {
062 performExecutions(eventSource);
063
064 postFlush(eventSource);
065 }
066 finally {
067 persistenceContext.setFlushing(false);
068 }
069
070 SessionFactoryImplementor sessionFactoryImplementor =
071 eventSource.getFactory();
072
073 Statistics statistics = sessionFactoryImplementor.getStatistics();
074
075 if (statistics.isStatisticsEnabled()) {
076 StatisticsImplementor statisticsImplementor =
077 sessionFactoryImplementor.getStatisticsImplementor();
078
079 statisticsImplementor.flush();
080 }
081 }
082 else if (!persistenceContext.isFlushing()) {
083 actionQueue.clearFromFlushNeededCheck(oldSize);
084 }
085
086 autoFlushEvent.setFlushRequired(
087 isFlushReallyNeeded(autoFlushEvent, eventSource));
088 }
089
090 private boolean isFlushable(EventSource eventSource) {
091 FlushMode flushMode = eventSource.getFlushMode();
092
093 if (flushMode.lessThan(FlushMode.AUTO)) {
094 return false;
095 }
096
097 if (eventSource.getDontFlushFromFind() != 0) {
098 return false;
099 }
100
101 PersistenceContext persistenceContext =
102 eventSource.getPersistenceContext();
103
104 Map<?, ?> entityEntries = persistenceContext.getEntityEntries();
105
106 if (!entityEntries.isEmpty()) {
107 return true;
108 }
109
110 Map<?, ?> collectionEntries = persistenceContext.getCollectionEntries();
111
112 if (!collectionEntries.isEmpty()) {
113 return true;
114 }
115
116 return false;
117 }
118
119 private boolean isFlushReallyNeeded(
120 AutoFlushEvent autoFlushEvent, EventSource eventSource) {
121
122 if (eventSource.getFlushMode() == FlushMode.ALWAYS) {
123 return true;
124 }
125
126 ActionQueue actionQueue = eventSource.getActionQueue();
127
128 return actionQueue.areTablesToBeUpdated(
129 autoFlushEvent.getQuerySpaces());
130 }
131
132 }