Skip to content

Commit f759c15

Browse files
barreirosebersole
authored andcommitted
HHH-9985 - bytecode enhancer - fix merge use case
1 parent 463decd commit f759c15

File tree

11 files changed

+121
-36
lines changed

11 files changed

+121
-36
lines changed

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

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
import javassist.NotFoundException;
1919

2020
import org.hibernate.bytecode.enhance.internal.tracker.CollectionTracker;
21-
import org.hibernate.bytecode.enhance.internal.tracker.SimpleDirtyTracker;
21+
import org.hibernate.bytecode.enhance.internal.tracker.DirtyTracker;
22+
import org.hibernate.bytecode.enhance.internal.tracker.SimpleFieldTracker;
2223
import org.hibernate.bytecode.enhance.spi.EnhancementContext;
2324
import org.hibernate.bytecode.enhance.spi.EnhancementException;
2425
import org.hibernate.bytecode.enhance.spi.Enhancer;
@@ -36,8 +37,8 @@ public EntityEnhancer(EnhancementContext context) {
3637
super( context );
3738
}
3839

39-
// for very small sizes SimpleDirtyTracker implementation ends up being faster
40-
private static final String TRACKER_IMPL = SimpleDirtyTracker.class.getName();
40+
// assuming the number of fields is not very high, SimpleFieldTracker implementation it's the fastest
41+
private static final String DIRTY_TRACKER_IMPL = SimpleFieldTracker.class.getName();
4142

4243
public void enhance(CtClass managedCtClass) {
4344
// add the ManagedEntity interface
@@ -107,7 +108,11 @@ private void addInLineDirtyHandling(CtClass managedCtClass) {
107108
try {
108109
managedCtClass.addInterface( classPool.get( SelfDirtinessTracker.class.getName() ) );
109110

110-
FieldWriter.addField( managedCtClass, classPool.get( TRACKER_IMPL ), EnhancerConstants.TRACKER_FIELD_NAME );
111+
FieldWriter.addField(
112+
managedCtClass,
113+
classPool.get( DIRTY_TRACKER_IMPL ),
114+
EnhancerConstants.TRACKER_FIELD_NAME
115+
);
111116
FieldWriter.addField(
112117
managedCtClass,
113118
classPool.get( CollectionTracker.class.getName() ),
@@ -124,22 +129,22 @@ private void addInLineDirtyHandling(CtClass managedCtClass) {
124129
private void createDirtyTrackerMethods(CtClass managedCtClass) {
125130
try {
126131
MethodWriter.write(
127-
managedCtClass, "" +
132+
managedCtClass,
128133
"public void %1$s(String name) {%n" +
129134
" if (%2$s == null) { %2$s = new %3$s(); }%n" +
130135
" %2$s.add(name);%n" +
131136
"}",
132137
EnhancerConstants.TRACKER_CHANGER_NAME,
133138
EnhancerConstants.TRACKER_FIELD_NAME,
134-
TRACKER_IMPL
139+
DIRTY_TRACKER_IMPL
135140
);
136141

137142
createCollectionDirtyCheckMethod( managedCtClass );
138143
createCollectionDirtyCheckGetFieldsMethod( managedCtClass );
139144
createClearDirtyCollectionMethod( managedCtClass );
140145

141146
MethodWriter.write(
142-
managedCtClass, "" +
147+
managedCtClass,
143148
"public String[] %1$s() {%n" +
144149
" if(%3$s == null) {%n" +
145150
" return (%2$s == null) ? new String[0] : %2$s.get();%n" +
@@ -153,12 +158,11 @@ private void createDirtyTrackerMethods(CtClass managedCtClass) {
153158
EnhancerConstants.TRACKER_FIELD_NAME,
154159
EnhancerConstants.TRACKER_COLLECTION_NAME,
155160
EnhancerConstants.TRACKER_COLLECTION_CHANGED_FIELD_NAME,
156-
TRACKER_IMPL
161+
DIRTY_TRACKER_IMPL
157162
);
158163

159164
MethodWriter.write(
160165
managedCtClass,
161-
"" +
162166
"public boolean %1$s() {%n" +
163167
" return (%2$s != null && !%2$s.isEmpty()) || %3$s();%n" +
164168
"}",
@@ -169,7 +173,6 @@ private void createDirtyTrackerMethods(CtClass managedCtClass) {
169173

170174
MethodWriter.write(
171175
managedCtClass,
172-
"" +
173176
"public void %1$s() {%n" +
174177
" if (%2$s != null) { %2$s.clear(); }%n" +
175178
" %3$s();%n" +
@@ -213,7 +216,6 @@ private void createCollectionDirtyCheckMethod(CtClass managedCtClass) {
213216

214217
body.append(
215218
String.format(
216-
"" +
217219
"private boolean %1$s() {%n" +
218220
" if (%2$s == null) {%n" +
219221
" return false;%n" +
@@ -227,7 +229,6 @@ private void createCollectionDirtyCheckMethod(CtClass managedCtClass) {
227229
if ( !enhancementContext.isMappedCollection( ctField ) ) {
228230
body.append(
229231
String.format(
230-
"" +
231232
" // collection field [%1$s]%n" +
232233
" if (%1$s == null && %2$s.getSize(\"%1$s\") != -1) { return true; }%n" +
233234
" if (%1$s != null && %2$s.getSize(\"%1$s\") != %1$s.size()) { return true; }%n",
@@ -252,20 +253,18 @@ private void createCollectionDirtyCheckGetFieldsMethod(CtClass managedCtClass) {
252253

253254
body.append(
254255
String.format(
255-
"" +
256256
"private void %1$s(%3$s tracker) {%n" +
257257
" if (%2$s == null) { return; }%n",
258258
EnhancerConstants.TRACKER_COLLECTION_CHANGED_FIELD_NAME,
259259
EnhancerConstants.TRACKER_COLLECTION_NAME,
260-
TRACKER_IMPL
260+
DirtyTracker.class.getName()
261261
)
262262
);
263263

264264
for ( CtField ctField : collectCollectionFields( managedCtClass ) ) {
265265
if ( !enhancementContext.isMappedCollection( ctField ) ) {
266266
body.append(
267267
String.format(
268-
"" +
269268
" // Collection field [%1$s]%n" +
270269
" if (%1$s == null && %2$s.getSize(\"%1$s\") != -1) { tracker.add(\"%1$s\"); }%n" +
271270
" if (%1$s != null && %2$s.getSize(\"%1$s\") != %1$s.size()) { tracker.add(\"%1$s\"); }%n",
@@ -290,7 +289,6 @@ private void createClearDirtyCollectionMethod(CtClass managedCtClass) throws Can
290289

291290
body.append(
292291
String.format(
293-
"" +
294292
"private void %1$s() {%n" +
295293
" if (%2$s == null) { %2$s = new %3$s(); }%n",
296294
EnhancerConstants.TRACKER_COLLECTION_CLEAR_NAME,
@@ -303,7 +301,6 @@ private void createClearDirtyCollectionMethod(CtClass managedCtClass) throws Can
303301
if ( !enhancementContext.isMappedCollection( ctField ) ) {
304302
body.append(
305303
String.format(
306-
"" +
307304
" // Collection field [%1$s]%n" +
308305
" if (%1$s == null) { %2$s.add(\"%1$s\", -1); }%n" +
309306
" else { %2$s.add(\"%1$s\", %1$s.size()); }%n",
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.bytecode.enhance.internal.tracker;
8+
9+
/**
10+
* Interface to be implemented by dirty trackers, a simplified Set of String.
11+
*
12+
* @author <a href="mailto:[email protected]">Luis Barreiro</a>
13+
*/
14+
public interface DirtyTracker {
15+
16+
void add(String name);
17+
18+
boolean contains(String name);
19+
20+
void clear();
21+
22+
boolean isEmpty();
23+
24+
String[] get();
25+
}
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,23 @@
1616
*
1717
* @author <a href="mailto:[email protected]">Luis Barreiro</a>
1818
*/
19-
public final class SimpleDirtyTracker {
19+
public final class SimpleFieldTracker implements DirtyTracker {
2020

2121
private String[] names;
2222

23-
public SimpleDirtyTracker() {
23+
public SimpleFieldTracker() {
2424
names = new String[0];
2525
}
2626

27+
@Override
2728
public void add(String name) {
2829
if ( !contains( name ) ) {
2930
names = Arrays.copyOf( names, names.length + 1 );
3031
names[names.length - 1] = name;
3132
}
3233
}
3334

35+
@Override
3436
public boolean contains(String name) {
3537
for ( String existing : names ) {
3638
if ( existing.equals( name ) ) {
@@ -40,14 +42,17 @@ public boolean contains(String name) {
4042
return false;
4143
}
4244

45+
@Override
4346
public void clear() {
4447
names = new String[0];
4548
}
4649

50+
@Override
4751
public boolean isEmpty() {
4852
return names.length == 0;
4953
}
5054

55+
@Override
5156
public String[] get() {
5257
return names;
5358
}
Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@
1313
*
1414
* @author <a href="mailto:[email protected]">Luis Barreiro</a>
1515
*/
16-
public final class SortedDirtyTracker {
16+
public final class SortedFieldTracker implements DirtyTracker {
1717

1818
private String[] names;
1919

20-
public SortedDirtyTracker() {
20+
public SortedFieldTracker() {
2121
names = new String[0];
2222
}
2323

24+
@Override
2425
public void add(String name) {
2526
// we do a binary search: even if we don't find the name at least we get the position to insert into the array
2627
int insert = 0;
@@ -41,12 +42,13 @@ else if( compare < 0 ) {
4142
}
4243
}
4344
final String[] newNames = new String[names.length + 1];
44-
System.arraycopy( names, 0, newNames, 0, insert);
45-
System.arraycopy( names, insert, newNames, insert + 1, names.length - insert);
45+
System.arraycopy( names, 0, newNames, 0, insert );
46+
System.arraycopy( names, insert, newNames, insert + 1, names.length - insert );
4647
newNames[insert] = name;
4748
names = newNames;
4849
}
4950

51+
@Override
5052
public boolean contains(String name) {
5153
for ( int low = 0, high = names.length - 1; low <= high; ) {
5254
final int middle = low + ( ( high - low ) / 2 );
@@ -66,14 +68,17 @@ else if( compare < 0 ) {
6668
return false;
6769
}
6870

71+
@Override
6972
public void clear() {
7073
names = new String[0];
7174
}
7275

76+
@Override
7377
public boolean isEmpty() {
7478
return names.length == 0;
7579
}
7680

81+
@Override
7782
public String[] get() {
7883
return names;
7984
}

hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/EnhancerConstants.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
*
1212
* @author Steve Ebersole
1313
*/
14-
public class EnhancerConstants {
14+
public final class EnhancerConstants {
15+
1516
/**
1617
* Prefix for persistent-field reader methods.
1718
*/
@@ -141,22 +142,34 @@ public class EnhancerConstants {
141142
*/
142143
public static final String TRACKER_COLLECTION_CHANGED_NAME = "$$_hibernate_areCollectionFieldsDirty";
143144

145+
/**
146+
* Name of the field that holds the collection tracker
147+
*/
144148
public static final String TRACKER_COLLECTION_NAME = "$$_hibernate_collectionTracker";
149+
145150
/**
146151
* Name of method to get dirty collection field names
147152
*/
148153
public static final String TRACKER_COLLECTION_CHANGED_FIELD_NAME = "$$_hibernate_getCollectionFieldDirtyNames";
149154

155+
/**
156+
* Name of method to clear dirty attribute on collection fields
157+
*/
150158
public static final String TRACKER_COLLECTION_CLEAR_NAME = "$$_hibernate_clearDirtyCollectionNames";
151159

152-
public static final String TRACKER_COMPOSITE_DIRTY_CHECK = "$$_hibernate_areCompositeFieldsDirty";
153-
154-
public static final String TRACKER_COMPOSITE_DIRTY_FIELDS_GETTER = "$$_hibernate_getCompositeDirtyFields";
155-
160+
/**
161+
* Field to hold the track the owner of the embeddable entity
162+
*/
156163
public static final String TRACKER_COMPOSITE_FIELD_NAME = "$$_hibernate_compositeOwners";
157164

165+
/**
166+
* Method to set the owner of the embedded entity
167+
*/
158168
public static final String TRACKER_COMPOSITE_SET_OWNER = "$$_hibernate_setOwner";
159169

170+
/**
171+
* Method to clear the owner of the embedded entity
172+
*/
160173
public static final String TRACKER_COMPOSITE_CLEAR_OWNER = "$$_hibernate_clearOwner";
161174

162175
private EnhancerConstants() {

hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/LazyAttributeLoader.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import java.util.Set;
1111

1212
import org.hibernate.LazyInitializationException;
13-
import org.hibernate.bytecode.enhance.internal.tracker.SimpleDirtyTracker;
13+
import org.hibernate.bytecode.enhance.internal.tracker.SimpleFieldTracker;
1414
import org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer;
1515
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
1616
import org.hibernate.engine.spi.SessionImplementor;
@@ -26,7 +26,7 @@ public class LazyAttributeLoader implements PersistentAttributeInterceptor {
2626
private final Set<String> lazyFields;
2727
private final String entityName;
2828

29-
private final SimpleDirtyTracker initializedFields = new SimpleDirtyTracker();
29+
private final SimpleFieldTracker initializedFields = new SimpleFieldTracker();
3030

3131
public LazyAttributeLoader(SessionImplementor session, Set<String> lazyFields, String entityName) {
3232
this.session = session;
@@ -58,6 +58,14 @@ else if ( !session.isOpen() || !session.isConnected() ) {
5858
}
5959
}
6060

61+
public void setLoaded(String attributeName) {
62+
initializedFields.add( attributeName );
63+
}
64+
65+
public String[] getiInitializedFields() {
66+
return initializedFields.get();
67+
}
68+
6169
@Override
6270
public String toString() {
6371
return "LazyAttributeLoader(entityName=" + entityName + " ,lazyFields=" + lazyFields + ')';

hibernate-core/src/main/java/org/hibernate/engine/internal/AbstractEntityEntry.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ public void postUpdate(Object entity, Object[] updatedState, Object nextVersion)
287287
}
288288

289289
if( entity instanceof SelfDirtinessTracker ) {
290-
((SelfDirtinessTracker) entity).$$_hibernate_clearDirtyAttributes();
290+
( (SelfDirtinessTracker) entity ).$$_hibernate_clearDirtyAttributes();
291291
}
292292

293293
persistenceContext.getSession()
@@ -342,7 +342,7 @@ public boolean requiresDirtyCheck(Object entity) {
342342
private boolean isUnequivocallyNonDirty(Object entity) {
343343

344344
if(entity instanceof SelfDirtinessTracker) {
345-
return ((SelfDirtinessTracker) entity).$$_hibernate_hasDirtyAttributes();
345+
return ! ( (SelfDirtinessTracker) entity ).$$_hibernate_hasDirtyAttributes();
346346
}
347347

348348
final CustomEntityDirtinessStrategy customEntityDirtinessStrategy =

hibernate-core/src/main/java/org/hibernate/engine/spi/SelfDirtinessTracker.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ public interface SelfDirtinessTracker {
3232
*/
3333
String[] $$_hibernate_getDirtyAttributes();
3434

35+
/**
36+
* Adds persistent attribute to the set of values that have changed
37+
*/
38+
void $$_hibernate_trackChange(String attributes);
39+
3540
/**
3641
* Clear the stored dirty attributes
3742
*/

0 commit comments

Comments
 (0)