Skip to content

Commit acea523

Browse files
committed
HHH-9806 - Bytecode-enhancement-based dirty tracking does not work because PersistentAttributeInterceptor is never injected
1 parent 14fc885 commit acea523

File tree

7 files changed

+614
-453
lines changed

7 files changed

+614
-453
lines changed

hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/AttributeTypeDescriptor.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,10 @@ public String buildInLineDirtyCheckingBodyFragment(EnhancementContext context, C
3737
return "";
3838
}
3939
}
40-
builder.append( String.format( "if (%s() != null", EnhancerConstants.INTERCEPTOR_GETTER_NAME ) );
4140

4241
// primitives || enums
4342
if ( currentValue.getType().isPrimitive() || currentValue.getType().isEnum() ) {
44-
builder.append( String.format( " && %s != $1)", currentValue.getName()) );
43+
builder.append( String.format( "if (%s != $1)", currentValue.getName()) );
4544
}
4645
// simple data types
4746
else if ( currentValue.getType().getName().startsWith( "java.lang" )
@@ -50,7 +49,7 @@ else if ( currentValue.getType().getName().startsWith( "java.lang" )
5049
|| currentValue.getType().getName().startsWith( "java.sql.Date" )
5150
|| currentValue.getType().getName().startsWith( "java.util.Date" )
5251
|| currentValue.getType().getName().startsWith( "java.util.Calendar" ) ) {
53-
builder.append( String.format( " && ((%s == null) || (!%<s.equals($1))))", currentValue.getName() ) );
52+
builder.append( String.format( "if (%s == null || !%<s.equals($1))", currentValue.getName() ) );
5453
}
5554
// all other objects
5655
else {
@@ -64,7 +63,7 @@ else if ( currentValue.getType().getName().startsWith( "java.lang" )
6463
}
6564
}
6665
// TODO: for now just call equals, should probably do something else here
67-
builder.append( String.format( " && ((%s == null) || (!%<s.equals($1))))", currentValue.getName() ) );
66+
builder.append( String.format( "if (%s == null || !%<s.equals($1))", currentValue.getName() ) );
6867
}
6968
builder.append( String.format( " { %s(\"%s\"); }", EnhancerConstants.TRACKER_CHANGER_NAME, currentValue.getName() ) );
7069
}

hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/EntityEnhancer.java

Lines changed: 113 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import javassist.CtField;
1212
import javassist.Modifier;
1313
import javassist.NotFoundException;
14+
1415
import org.hibernate.bytecode.enhance.internal.tracker.CollectionTracker;
1516
import org.hibernate.bytecode.enhance.internal.tracker.SimpleDirtyTracker;
1617
import org.hibernate.bytecode.enhance.spi.EnhancementContext;
@@ -22,6 +23,7 @@
2223
import java.util.Collection;
2324
import java.util.LinkedList;
2425
import java.util.List;
26+
import java.util.Locale;
2527

2628
/**
2729
* enhancer for regular entities
@@ -54,49 +56,63 @@ public void enhance(CtClass managedCtClass) {
5456
new PersistentAttributesEnhancer( enhancementContext ).enhance( managedCtClass );
5557
}
5658

57-
/* -- */
58-
5959
private void addEntityInstanceHandling(CtClass managedCtClass) {
6060
try {
61-
MethodWriter.write( managedCtClass, "public Object %s() { return this; }", EnhancerConstants.ENTITY_INSTANCE_GETTER_NAME );
61+
MethodWriter.write(
62+
managedCtClass,
63+
"public Object %s() { return this; }",
64+
EnhancerConstants.ENTITY_INSTANCE_GETTER_NAME
65+
);
6266
}
6367
catch (CannotCompileException cce) {
64-
final String msg = String.format( "Could not enhance entity class [%s] to add EntityEntry getter", managedCtClass.getName() );
65-
throw new EnhancementException(msg, cce);
68+
throw new EnhancementException(
69+
String.format(
70+
Locale.ROOT,
71+
"Could not enhance entity class [%s] to add EntityEntry getter",
72+
managedCtClass.getName()
73+
),
74+
cce
75+
);
6676
}
6777
}
6878

69-
/* -- */
70-
7179
private void addEntityEntryHandling(CtClass managedCtClass) {
72-
FieldWriter.addFieldWithGetterAndSetter( managedCtClass, entityEntryCtClass,
80+
FieldWriter.addFieldWithGetterAndSetter(
81+
managedCtClass, entityEntryCtClass,
7382
EnhancerConstants.ENTITY_ENTRY_FIELD_NAME,
7483
EnhancerConstants.ENTITY_ENTRY_GETTER_NAME,
75-
EnhancerConstants.ENTITY_ENTRY_SETTER_NAME );
84+
EnhancerConstants.ENTITY_ENTRY_SETTER_NAME
85+
);
7686
}
7787

7888
private void addLinkedPreviousHandling(CtClass managedCtClass) {
79-
FieldWriter.addFieldWithGetterAndSetter( managedCtClass, managedEntityCtClass,
89+
FieldWriter.addFieldWithGetterAndSetter(
90+
managedCtClass, managedEntityCtClass,
8091
EnhancerConstants.PREVIOUS_FIELD_NAME,
8192
EnhancerConstants.PREVIOUS_GETTER_NAME,
82-
EnhancerConstants.PREVIOUS_SETTER_NAME );
93+
EnhancerConstants.PREVIOUS_SETTER_NAME
94+
);
8395
}
8496

8597
private void addLinkedNextHandling(CtClass managedCtClass) {
86-
FieldWriter.addFieldWithGetterAndSetter( managedCtClass, managedEntityCtClass,
98+
FieldWriter.addFieldWithGetterAndSetter(
99+
managedCtClass, managedEntityCtClass,
87100
EnhancerConstants.NEXT_FIELD_NAME,
88101
EnhancerConstants.NEXT_GETTER_NAME,
89-
EnhancerConstants.NEXT_SETTER_NAME );
102+
EnhancerConstants.NEXT_SETTER_NAME
103+
);
90104
}
91105

92-
/* --- */
93-
94106
private void addInLineDirtyHandling(CtClass managedCtClass) {
95107
try {
96108
managedCtClass.addInterface( classPool.get( SelfDirtinessTracker.class.getName() ) );
97109

98110
FieldWriter.addField( managedCtClass, classPool.get( TRACKER_IMPL ), EnhancerConstants.TRACKER_FIELD_NAME );
99-
FieldWriter.addField( managedCtClass, classPool.get( CollectionTracker.class.getName() ), EnhancerConstants.TRACKER_COLLECTION_NAME );
111+
FieldWriter.addField(
112+
managedCtClass,
113+
classPool.get( CollectionTracker.class.getName() ),
114+
EnhancerConstants.TRACKER_COLLECTION_NAME
115+
);
100116

101117
createDirtyTrackerMethods( managedCtClass );
102118
}
@@ -107,24 +123,23 @@ private void addInLineDirtyHandling(CtClass managedCtClass) {
107123

108124
private void createDirtyTrackerMethods(CtClass managedCtClass) {
109125
try {
110-
MethodWriter.write( managedCtClass, "" +
126+
MethodWriter.write(
127+
managedCtClass, "" +
111128
"public void %1$s(String name) {%n" +
112129
" if (%2$s == null) { %2$s = new %3$s(); }%n" +
113130
" %2$s.add(name);%n" +
114131
"}",
115132
EnhancerConstants.TRACKER_CHANGER_NAME,
116133
EnhancerConstants.TRACKER_FIELD_NAME,
117-
TRACKER_IMPL );
118-
119-
/* --- */
134+
TRACKER_IMPL
135+
);
120136

121137
createCollectionDirtyCheckMethod( managedCtClass );
122138
createCollectionDirtyCheckGetFieldsMethod( managedCtClass );
123139
createClearDirtyCollectionMethod( managedCtClass );
124140

125-
/* --- */
126-
127-
MethodWriter.write( managedCtClass, "" +
141+
MethodWriter.write(
142+
managedCtClass, "" +
128143
"public java.util.Set %1$s() {%n" +
129144
" if (%2$s == null) { %2$s = new %4$s(); }%n" +
130145
" %3$s(%2$s);%n" +
@@ -133,32 +148,37 @@ private void createDirtyTrackerMethods(CtClass managedCtClass) {
133148
EnhancerConstants.TRACKER_GET_NAME,
134149
EnhancerConstants.TRACKER_FIELD_NAME,
135150
EnhancerConstants.TRACKER_COLLECTION_CHANGED_FIELD_NAME,
136-
TRACKER_IMPL );
151+
TRACKER_IMPL
152+
);
137153

138-
MethodWriter.write( managedCtClass, "" +
154+
MethodWriter.write(
155+
managedCtClass,
156+
"" +
139157
"public boolean %1$s() {%n" +
140158
" return (%2$s != null && !%2$s.isEmpty()) || %3$s();%n" +
141159
"}",
142160
EnhancerConstants.TRACKER_HAS_CHANGED_NAME,
143161
EnhancerConstants.TRACKER_FIELD_NAME,
144-
EnhancerConstants.TRACKER_COLLECTION_CHANGED_NAME );
162+
EnhancerConstants.TRACKER_COLLECTION_CHANGED_NAME
163+
);
145164

146-
MethodWriter.write( managedCtClass, "" +
165+
MethodWriter.write(
166+
managedCtClass,
167+
"" +
147168
"public void %1$s() {%n" +
148169
" if (%2$s != null) { %2$s.clear(); }%n" +
149170
" %3$s();%n" +
150171
"}",
151172
EnhancerConstants.TRACKER_CLEAR_NAME,
152173
EnhancerConstants.TRACKER_FIELD_NAME,
153-
EnhancerConstants.TRACKER_COLLECTION_CLEAR_NAME );
174+
EnhancerConstants.TRACKER_COLLECTION_CLEAR_NAME
175+
);
154176
}
155177
catch (CannotCompileException cce) {
156178
cce.printStackTrace();
157179
}
158180
}
159181

160-
/* -- */
161-
162182
private List<CtField> collectCollectionFields(CtClass managedCtClass) {
163183
final List<CtField> collectionList = new LinkedList<CtField>();
164184
try {
@@ -186,21 +206,30 @@ private void createCollectionDirtyCheckMethod(CtClass managedCtClass) {
186206
try {
187207
final StringBuilder body = new StringBuilder();
188208

189-
body.append( String.format( "" +
190-
"private boolean %1$s() {%n" +
191-
" if (%2$s() == null || %3$s == null) { return false; }%n",
192-
EnhancerConstants.TRACKER_COLLECTION_CHANGED_NAME,
193-
EnhancerConstants.INTERCEPTOR_GETTER_NAME,
194-
EnhancerConstants.TRACKER_COLLECTION_NAME ) );
209+
body.append(
210+
String.format(
211+
"" +
212+
"private boolean %1$s() {%n" +
213+
" if (%2$s == null) {%n" +
214+
" return false;%n" +
215+
" }%n",
216+
EnhancerConstants.TRACKER_COLLECTION_CHANGED_NAME,
217+
EnhancerConstants.TRACKER_COLLECTION_NAME
218+
)
219+
);
195220

196221
for ( CtField ctField : collectCollectionFields( managedCtClass ) ) {
197-
if ( !enhancementContext.isMappedCollection( ctField )) {
198-
body.append( String.format( "" +
199-
" // collection field [%1$s]%n" +
200-
" if (%1$s == null && %2$s.getSize(\"%1$s\") != -1) { return true; }%n"+
201-
" if (%1$s != null && %2$s.getSize(\"%1$s\") != %1$s.size()) { return true; }%n",
202-
ctField.getName(),
203-
EnhancerConstants.TRACKER_COLLECTION_NAME ) );
222+
if ( !enhancementContext.isMappedCollection( ctField ) ) {
223+
body.append(
224+
String.format(
225+
"" +
226+
" // collection field [%1$s]%n" +
227+
" if (%1$s == null && %2$s.getSize(\"%1$s\") != -1) { return true; }%n" +
228+
" if (%1$s != null && %2$s.getSize(\"%1$s\") != %1$s.size()) { return true; }%n",
229+
ctField.getName(),
230+
EnhancerConstants.TRACKER_COLLECTION_NAME
231+
)
232+
);
204233
}
205234
}
206235
body.append( " return false;%n}" );
@@ -216,21 +245,29 @@ private void createCollectionDirtyCheckGetFieldsMethod(CtClass managedCtClass) {
216245
try {
217246
final StringBuilder body = new StringBuilder();
218247

219-
body.append( String.format( "" +
220-
"private void %1$s(%3$s tracker) {%n" +
221-
" if (%2$s == null) { return; }%n",
222-
EnhancerConstants.TRACKER_COLLECTION_CHANGED_FIELD_NAME,
223-
EnhancerConstants.TRACKER_COLLECTION_NAME,
224-
TRACKER_IMPL ) );
248+
body.append(
249+
String.format(
250+
"" +
251+
"private void %1$s(%3$s tracker) {%n" +
252+
" if (%2$s == null) { return; }%n",
253+
EnhancerConstants.TRACKER_COLLECTION_CHANGED_FIELD_NAME,
254+
EnhancerConstants.TRACKER_COLLECTION_NAME,
255+
TRACKER_IMPL
256+
)
257+
);
225258

226259
for ( CtField ctField : collectCollectionFields( managedCtClass ) ) {
227-
if ( !enhancementContext.isMappedCollection( ctField )) {
228-
body.append( String.format( "" +
229-
" // Collection field [%1$s]%n" +
230-
" if (%1$s == null && %2$s.getSize(\"%1$s\") != -1) { tracker.add(\"%1$s\"); }%n"+
231-
" if (%1$s != null && %2$s.getSize(\"%1$s\") != %1$s.size()) { tracker.add(\"%1$s\"); }%n",
232-
ctField.getName(),
233-
EnhancerConstants.TRACKER_COLLECTION_NAME ) );
260+
if ( !enhancementContext.isMappedCollection( ctField ) ) {
261+
body.append(
262+
String.format(
263+
"" +
264+
" // Collection field [%1$s]%n" +
265+
" if (%1$s == null && %2$s.getSize(\"%1$s\") != -1) { tracker.add(\"%1$s\"); }%n" +
266+
" if (%1$s != null && %2$s.getSize(\"%1$s\") != %1$s.size()) { tracker.add(\"%1$s\"); }%n",
267+
ctField.getName(),
268+
EnhancerConstants.TRACKER_COLLECTION_NAME
269+
)
270+
);
234271
}
235272
}
236273
body.append( "}" );
@@ -246,21 +283,29 @@ private void createClearDirtyCollectionMethod(CtClass managedCtClass) throws Can
246283
try {
247284
final StringBuilder body = new StringBuilder();
248285

249-
body.append( String.format( "" +
250-
"private void %1$s() {%n" +
251-
" if (%2$s == null) { %2$s = new %3$s(); }%n",
252-
EnhancerConstants.TRACKER_COLLECTION_CLEAR_NAME,
253-
EnhancerConstants.TRACKER_COLLECTION_NAME,
254-
CollectionTracker.class.getName()) );
286+
body.append(
287+
String.format(
288+
"" +
289+
"private void %1$s() {%n" +
290+
" if (%2$s == null) { %2$s = new %3$s(); }%n",
291+
EnhancerConstants.TRACKER_COLLECTION_CLEAR_NAME,
292+
EnhancerConstants.TRACKER_COLLECTION_NAME,
293+
CollectionTracker.class.getName()
294+
)
295+
);
255296

256297
for ( CtField ctField : collectCollectionFields( managedCtClass ) ) {
257298
if ( !enhancementContext.isMappedCollection( ctField ) ) {
258-
body.append( String.format( "" +
259-
" // Collection field [%1$s]%n" +
260-
" if (%1$s == null) { %2$s.add(\"%1$s\", -1); }%n"+
261-
" else { %2$s.add(\"%1$s\", %1$s.size()); }%n",
262-
ctField.getName(),
263-
EnhancerConstants.TRACKER_COLLECTION_NAME) );
299+
body.append(
300+
String.format(
301+
"" +
302+
" // Collection field [%1$s]%n" +
303+
" if (%1$s == null) { %2$s.add(\"%1$s\", -1); }%n" +
304+
" else { %2$s.add(\"%1$s\", %1$s.size()); }%n",
305+
ctField.getName(),
306+
EnhancerConstants.TRACKER_COLLECTION_NAME
307+
)
308+
);
264309
}
265310
}
266311
body.append( "}" );

0 commit comments

Comments
 (0)