/
CollectionUpdateAction.java
130 lines (116 loc) · 4.22 KB
/
CollectionUpdateAction.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.action.internal;
import java.io.Serializable;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.event.service.spi.EventListenerGroup;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PostCollectionUpdateEvent;
import org.hibernate.event.spi.PostCollectionUpdateEventListener;
import org.hibernate.event.spi.PreCollectionUpdateEvent;
import org.hibernate.event.spi.PreCollectionUpdateEventListener;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.stat.spi.StatisticsImplementor;
/**
* The action for updating a collection
*/
public final class CollectionUpdateAction extends CollectionAction {
private final boolean emptySnapshot;
/**
* Constructs a CollectionUpdateAction
*
* @param collection The collection to update
* @param persister The collection persister
* @param id The collection key
* @param emptySnapshot Indicates if the snapshot is empty
* @param session The session
*/
public CollectionUpdateAction(
final PersistentCollection collection,
final CollectionPersister persister,
final Serializable id,
final boolean emptySnapshot,
final SharedSessionContractImplementor session) {
super( persister, collection, id, session );
this.emptySnapshot = emptySnapshot;
}
@Override
public void execute() throws HibernateException {
final Serializable id = getKey();
final SharedSessionContractImplementor session = getSession();
final CollectionPersister persister = getPersister();
final PersistentCollection collection = getCollection();
final boolean affectedByFilters = persister.isAffectedByEnabledFilters( session );
preUpdate();
if ( !collection.wasInitialized() ) {
// If there were queued operations, they would have been processed
// and cleared by now.
// The collection should still be dirty.
if ( !collection.isDirty() ) {
throw new AssertionFailure( "collection is not dirty" );
}
//do nothing - we only need to notify the cache...
}
else if ( !affectedByFilters && collection.empty() ) {
if ( !emptySnapshot ) {
persister.remove( id, session );
}
}
else if ( collection.needsRecreate( persister ) ) {
if ( affectedByFilters ) {
throw new HibernateException(
"cannot recreate collection while filter is enabled: " +
MessageHelper.collectionInfoString( persister, collection, id, session )
);
}
if ( !emptySnapshot ) {
persister.remove( id, session );
}
persister.recreate( collection, id, session );
}
else {
persister.deleteRows( collection, id, session );
persister.updateRows( collection, id, session );
persister.insertRows( collection, id, session );
}
session.getPersistenceContextInternal().getCollectionEntry( collection ).afterAction( collection );
evict();
postUpdate();
final StatisticsImplementor statistics = session.getFactory().getStatistics();
if ( statistics.isStatisticsEnabled() ) {
statistics.updateCollection( persister.getRole() );
}
}
private void preUpdate() {
getFastSessionServices()
.eventListenerGroup_PRE_COLLECTION_UPDATE
.fireLazyEventOnEachListener( this::newPreCollectionUpdateEvent, PreCollectionUpdateEventListener::onPreUpdateCollection );
}
private PreCollectionUpdateEvent newPreCollectionUpdateEvent() {
return new PreCollectionUpdateEvent(
getPersister(),
getCollection(),
eventSource()
);
}
private void postUpdate() {
getFastSessionServices()
.eventListenerGroup_POST_COLLECTION_UPDATE
.fireLazyEventOnEachListener( this::newPostCollectionUpdateEvent, PostCollectionUpdateEventListener::onPostUpdateCollection );
}
private PostCollectionUpdateEvent newPostCollectionUpdateEvent() {
return new PostCollectionUpdateEvent(
getPersister(),
getCollection(),
eventSource()
);
}
}