1717import javassist .Modifier ;
1818import javassist .NotFoundException ;
1919
20- import org .hibernate .bytecode .enhance .internal .tracker .CollectionTracker ;
2120import org .hibernate .bytecode .enhance .internal .tracker .DirtyTracker ;
21+ import org .hibernate .bytecode .enhance .internal .tracker .SimpleCollectionTracker ;
2222import org .hibernate .bytecode .enhance .internal .tracker .SimpleFieldTracker ;
23+ import org .hibernate .bytecode .enhance .spi .CollectionTracker ;
2324import org .hibernate .bytecode .enhance .spi .EnhancementContext ;
2425import org .hibernate .bytecode .enhance .spi .EnhancementException ;
2526import org .hibernate .bytecode .enhance .spi .Enhancer ;
2627import org .hibernate .bytecode .enhance .spi .EnhancerConstants ;
28+ import org .hibernate .bytecode .enhance .spi .interceptor .LazyAttributeLoader ;
29+ import org .hibernate .engine .spi .PersistentAttributeInterceptable ;
2730import org .hibernate .engine .spi .SelfDirtinessTracker ;
2831
2932/**
@@ -39,6 +42,7 @@ public EntityEnhancer(EnhancementContext context) {
3942
4043 // assuming the number of fields is not very high, SimpleFieldTracker implementation it's the fastest
4144 private static final String DIRTY_TRACKER_IMPL = SimpleFieldTracker .class .getName ();
45+ private static final String COLLECTION_TRACKER_IMPL = SimpleCollectionTracker .class .getName ();
4246
4347 public void enhance (CtClass managedCtClass ) {
4448 // add the ManagedEntity interface
@@ -110,7 +114,7 @@ private void addInLineDirtyHandling(CtClass managedCtClass) {
110114
111115 FieldWriter .addField (
112116 managedCtClass ,
113- classPool .get ( DIRTY_TRACKER_IMPL ),
117+ classPool .get ( DirtyTracker . class . getName () ),
114118 EnhancerConstants .TRACKER_FIELD_NAME
115119 );
116120 FieldWriter .addField (
@@ -181,6 +185,24 @@ private void createDirtyTrackerMethods(CtClass managedCtClass) {
181185 EnhancerConstants .TRACKER_FIELD_NAME ,
182186 EnhancerConstants .TRACKER_COLLECTION_CLEAR_NAME
183187 );
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+ );
184206 }
185207 catch (CannotCompileException cce ) {
186208 cce .printStackTrace ();
@@ -197,7 +219,7 @@ private List<CtField> collectCollectionFields(CtClass managedCtClass) {
197219 }
198220 if ( enhancementContext .isPersistentField ( ctField ) ) {
199221 for ( CtClass ctClass : ctField .getType ().getInterfaces () ) {
200- if ( ctClass . getName (). equals ( Collection .class .getName () ) ) {
222+ if ( PersistentAttributesHelper . isAssignable ( ctClass , Collection .class .getName () ) ) {
201223 collectionList .add ( ctField );
202224 break ;
203225 }
@@ -217,9 +239,7 @@ private void createCollectionDirtyCheckMethod(CtClass managedCtClass) {
217239 body .append (
218240 String .format (
219241 "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" ,
223243 EnhancerConstants .TRACKER_COLLECTION_CHANGED_NAME ,
224244 EnhancerConstants .TRACKER_COLLECTION_NAME
225245 )
@@ -231,7 +251,7 @@ private void createCollectionDirtyCheckMethod(CtClass managedCtClass) {
231251 String .format (
232252 " // collection field [%1$s]%n" +
233253 " 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 " ,
235255 ctField .getName (),
236256 EnhancerConstants .TRACKER_COLLECTION_NAME
237257 )
@@ -254,7 +274,7 @@ private void createCollectionDirtyCheckGetFieldsMethod(CtClass managedCtClass) {
254274 body .append (
255275 String .format (
256276 "private void %1$s(%3$s tracker) {%n" +
257- " if (%2$s == null) { return; }%n" ,
277+ " if (%2$s == null) { return; }%n%n " ,
258278 EnhancerConstants .TRACKER_COLLECTION_CHANGED_FIELD_NAME ,
259279 EnhancerConstants .TRACKER_COLLECTION_NAME ,
260280 DirtyTracker .class .getName ()
@@ -267,7 +287,7 @@ private void createCollectionDirtyCheckGetFieldsMethod(CtClass managedCtClass) {
267287 String .format (
268288 " // Collection field [%1$s]%n" +
269289 " 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 " ,
271291 ctField .getName (),
272292 EnhancerConstants .TRACKER_COLLECTION_NAME
273293 )
@@ -289,21 +309,35 @@ private void createClearDirtyCollectionMethod(CtClass managedCtClass) throws Can
289309
290310 body .append (
291311 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" ,
294315 EnhancerConstants .TRACKER_COLLECTION_CLEAR_NAME ,
295316 EnhancerConstants .TRACKER_COLLECTION_NAME ,
296- CollectionTracker .class .getName ()
317+ COLLECTION_TRACKER_IMPL ,
318+ LazyAttributeLoader .class .getName ()
297319 )
298320 );
299321
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+
300332 for ( CtField ctField : collectCollectionFields ( managedCtClass ) ) {
301333 if ( !enhancementContext .isMappedCollection ( ctField ) ) {
302334 body .append (
303335 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" ,
307341 ctField .getName (),
308342 EnhancerConstants .TRACKER_COLLECTION_NAME
309343 )
0 commit comments