17
17
import javassist .Modifier ;
18
18
import javassist .NotFoundException ;
19
19
20
- import org .hibernate .bytecode .enhance .internal .tracker .CollectionTracker ;
21
20
import org .hibernate .bytecode .enhance .internal .tracker .DirtyTracker ;
21
+ import org .hibernate .bytecode .enhance .internal .tracker .SimpleCollectionTracker ;
22
22
import org .hibernate .bytecode .enhance .internal .tracker .SimpleFieldTracker ;
23
+ import org .hibernate .bytecode .enhance .spi .CollectionTracker ;
23
24
import org .hibernate .bytecode .enhance .spi .EnhancementContext ;
24
25
import org .hibernate .bytecode .enhance .spi .EnhancementException ;
25
26
import org .hibernate .bytecode .enhance .spi .Enhancer ;
26
27
import org .hibernate .bytecode .enhance .spi .EnhancerConstants ;
28
+ import org .hibernate .bytecode .enhance .spi .interceptor .LazyAttributeLoader ;
29
+ import org .hibernate .engine .spi .PersistentAttributeInterceptable ;
27
30
import org .hibernate .engine .spi .SelfDirtinessTracker ;
28
31
29
32
/**
@@ -39,6 +42,7 @@ public EntityEnhancer(EnhancementContext context) {
39
42
40
43
// assuming the number of fields is not very high, SimpleFieldTracker implementation it's the fastest
41
44
private static final String DIRTY_TRACKER_IMPL = SimpleFieldTracker .class .getName ();
45
+ private static final String COLLECTION_TRACKER_IMPL = SimpleCollectionTracker .class .getName ();
42
46
43
47
public void enhance (CtClass managedCtClass ) {
44
48
// add the ManagedEntity interface
@@ -110,7 +114,7 @@ private void addInLineDirtyHandling(CtClass managedCtClass) {
110
114
111
115
FieldWriter .addField (
112
116
managedCtClass ,
113
- classPool .get ( DIRTY_TRACKER_IMPL ),
117
+ classPool .get ( DirtyTracker . class . getName () ),
114
118
EnhancerConstants .TRACKER_FIELD_NAME
115
119
);
116
120
FieldWriter .addField (
@@ -181,6 +185,24 @@ private void createDirtyTrackerMethods(CtClass managedCtClass) {
181
185
EnhancerConstants .TRACKER_FIELD_NAME ,
182
186
EnhancerConstants .TRACKER_COLLECTION_CLEAR_NAME
183
187
);
188
+
189
+ MethodWriter .write (
190
+ managedCtClass ,
191
+ "public void %1$s(boolean f) {%n" +
192
+ " if (%2$s == null) %2$s = new %3$s();%n %2$s.suspend(f);%n" +
193
+ "}" ,
194
+ EnhancerConstants .TRACKER_SUSPEND_NAME ,
195
+ EnhancerConstants .TRACKER_FIELD_NAME ,
196
+ DIRTY_TRACKER_IMPL
197
+ );
198
+
199
+ MethodWriter .write (
200
+ managedCtClass ,
201
+ "public %s %s() { return %s; }" ,
202
+ CollectionTracker .class .getName (),
203
+ EnhancerConstants .TRACKER_COLLECTION_GET_NAME ,
204
+ EnhancerConstants .TRACKER_COLLECTION_NAME
205
+ );
184
206
}
185
207
catch (CannotCompileException cce ) {
186
208
cce .printStackTrace ();
@@ -197,7 +219,7 @@ private List<CtField> collectCollectionFields(CtClass managedCtClass) {
197
219
}
198
220
if ( enhancementContext .isPersistentField ( ctField ) ) {
199
221
for ( CtClass ctClass : ctField .getType ().getInterfaces () ) {
200
- if ( ctClass . getName (). equals ( Collection .class .getName () ) ) {
222
+ if ( PersistentAttributesHelper . isAssignable ( ctClass , Collection .class .getName () ) ) {
201
223
collectionList .add ( ctField );
202
224
break ;
203
225
}
@@ -217,9 +239,7 @@ private void createCollectionDirtyCheckMethod(CtClass managedCtClass) {
217
239
body .append (
218
240
String .format (
219
241
"private boolean %1$s() {%n" +
220
- " if (%2$s == null) {%n" +
221
- " return false;%n" +
222
- " }%n" ,
242
+ " if (%2$s == null) { return false; }%n%n" ,
223
243
EnhancerConstants .TRACKER_COLLECTION_CHANGED_NAME ,
224
244
EnhancerConstants .TRACKER_COLLECTION_NAME
225
245
)
@@ -231,7 +251,7 @@ private void createCollectionDirtyCheckMethod(CtClass managedCtClass) {
231
251
String .format (
232
252
" // collection field [%1$s]%n" +
233
253
" if (%1$s == null && %2$s.getSize(\" %1$s\" ) != -1) { return true; }%n" +
234
- " if (%1$s != null && %2$s.getSize(\" %1$s\" ) != %1$s.size()) { return true; }%n" ,
254
+ " if (%1$s != null && %2$s.getSize(\" %1$s\" ) != %1$s.size()) { return true; }%n%n " ,
235
255
ctField .getName (),
236
256
EnhancerConstants .TRACKER_COLLECTION_NAME
237
257
)
@@ -254,7 +274,7 @@ private void createCollectionDirtyCheckGetFieldsMethod(CtClass managedCtClass) {
254
274
body .append (
255
275
String .format (
256
276
"private void %1$s(%3$s tracker) {%n" +
257
- " if (%2$s == null) { return; }%n" ,
277
+ " if (%2$s == null) { return; }%n%n " ,
258
278
EnhancerConstants .TRACKER_COLLECTION_CHANGED_FIELD_NAME ,
259
279
EnhancerConstants .TRACKER_COLLECTION_NAME ,
260
280
DirtyTracker .class .getName ()
@@ -267,7 +287,7 @@ private void createCollectionDirtyCheckGetFieldsMethod(CtClass managedCtClass) {
267
287
String .format (
268
288
" // Collection field [%1$s]%n" +
269
289
" if (%1$s == null && %2$s.getSize(\" %1$s\" ) != -1) { tracker.add(\" %1$s\" ); }%n" +
270
- " if (%1$s != null && %2$s.getSize(\" %1$s\" ) != %1$s.size()) { tracker.add(\" %1$s\" ); }%n" ,
290
+ " if (%1$s != null && %2$s.getSize(\" %1$s\" ) != %1$s.size()) { tracker.add(\" %1$s\" ); }%n%n " ,
271
291
ctField .getName (),
272
292
EnhancerConstants .TRACKER_COLLECTION_NAME
273
293
)
@@ -289,21 +309,35 @@ private void createClearDirtyCollectionMethod(CtClass managedCtClass) throws Can
289
309
290
310
body .append (
291
311
String .format (
292
- "private void %1$s() {%n" +
293
- " if (%2$s == null) { %2$s = new %3$s(); }%n" ,
312
+ "private void %1$s() {%n" +
313
+ " if (%2$s == null) { %2$s = new %3$s(); }%n" +
314
+ " %4$s lazyInterceptor = null;%n" ,
294
315
EnhancerConstants .TRACKER_COLLECTION_CLEAR_NAME ,
295
316
EnhancerConstants .TRACKER_COLLECTION_NAME ,
296
- CollectionTracker .class .getName ()
317
+ COLLECTION_TRACKER_IMPL ,
318
+ LazyAttributeLoader .class .getName ()
297
319
)
298
320
);
299
321
322
+ if ( PersistentAttributesHelper .isAssignable ( managedCtClass , PersistentAttributeInterceptable .class .getName () ) ) {
323
+ body .append (
324
+ String .format (
325
+ " if(%1$s != null && %1$s instanceof %2$s) lazyInterceptor = (%2$s) %1$s;%n%n" ,
326
+ EnhancerConstants .INTERCEPTOR_FIELD_NAME ,
327
+ LazyAttributeLoader .class .getName ()
328
+ )
329
+ );
330
+ }
331
+
300
332
for ( CtField ctField : collectCollectionFields ( managedCtClass ) ) {
301
333
if ( !enhancementContext .isMappedCollection ( ctField ) ) {
302
334
body .append (
303
335
String .format (
304
- " // Collection field [%1$s]%n" +
305
- " if (%1$s == null) { %2$s.add(\" %1$s\" , -1); }%n" +
306
- " else { %2$s.add(\" %1$s\" , %1$s.size()); }%n" ,
336
+ " // collection field [%1$s]%n" +
337
+ " if (lazyInterceptor == null || lazyInterceptor.isAttributeLoaded(\" %1$s\" )) {%n" +
338
+ " if (%1$s == null) { %2$s.add(\" %1$s\" , -1); }%n" +
339
+ " else { %2$s.add(\" %1$s\" , %1$s.size()); }%n" +
340
+ " }%n%n" ,
307
341
ctField .getName (),
308
342
EnhancerConstants .TRACKER_COLLECTION_NAME
309
343
)
0 commit comments