Skip to content

Commit e615d76

Browse files
barreirosebersole
authored andcommitted
HHH-10646 - [enhancer] Add support for @MappedSuperclass
1 parent 3a0824a commit e615d76

File tree

5 files changed

+121
-14
lines changed

5 files changed

+121
-14
lines changed

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

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
import java.util.LinkedList;
1111
import java.util.List;
1212
import java.util.Locale;
13+
import java.util.Map;
14+
15+
import javax.persistence.MappedSuperclass;
1316

1417
import javassist.CannotCompileException;
1518
import javassist.CtClass;
@@ -211,24 +214,33 @@ private void createDirtyTrackerMethods(CtClass managedCtClass) {
211214

212215
private List<CtField> collectCollectionFields(CtClass managedCtClass) {
213216
final List<CtField> collectionList = new LinkedList<CtField>();
214-
try {
215-
for ( CtField ctField : managedCtClass.getDeclaredFields() ) {
216-
// skip static fields and skip fields added by enhancement
217-
if ( Modifier.isStatic( ctField.getModifiers() ) || ctField.getName().startsWith( "$$_hibernate_" ) ) {
218-
continue;
219-
}
220-
if ( enhancementContext.isPersistentField( ctField ) ) {
221-
for ( CtClass ctClass : ctField.getType().getInterfaces() ) {
222-
if ( PersistentAttributesHelper.isAssignable( ctClass, Collection.class.getName() ) ) {
223-
collectionList.add( ctField );
224-
break;
225-
}
226-
}
217+
218+
for ( CtField ctField : managedCtClass.getDeclaredFields() ) {
219+
// skip static fields and skip fields added by enhancement
220+
if ( Modifier.isStatic( ctField.getModifiers() ) || ctField.getName().startsWith( "$$_hibernate_" ) ) {
221+
continue;
222+
}
223+
if ( enhancementContext.isPersistentField( ctField ) ) {
224+
if ( PersistentAttributesHelper.isAssignable( ctField, Collection.class.getName() ) ||
225+
PersistentAttributesHelper.isAssignable( ctField, Map.class.getName() ) ) {
226+
collectionList.add( ctField );
227227
}
228228
}
229229
}
230-
catch (NotFoundException ignored) {
230+
231+
// HHH-10646 Add fields inherited from @MappedSuperclass
232+
for ( CtField ctField : managedCtClass.getDeclaredFields() ) {
233+
if ( !ctField.getDeclaringClass().hasAnnotation( MappedSuperclass.class ) || Modifier.isStatic( ctField.getModifiers() ) ) {
234+
continue;
235+
}
236+
if ( enhancementContext.isPersistentField( ctField ) ) {
237+
if ( PersistentAttributesHelper.isAssignable( ctField, Collection.class.getName() ) ||
238+
PersistentAttributesHelper.isAssignable( ctField, Map.class.getName() ) ) {
239+
collectionList.add( ctField );
240+
}
241+
}
231242
}
243+
232244
return collectionList;
233245
}
234246

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import javax.persistence.Id;
1515
import javax.persistence.ManyToMany;
1616
import javax.persistence.ManyToOne;
17+
import javax.persistence.MappedSuperclass;
1718
import javax.persistence.OneToMany;
1819
import javax.persistence.OneToOne;
1920

@@ -89,6 +90,16 @@ private CtField[] collectPersistentFields(CtClass managedCtClass) {
8990
persistentFieldList.add( ctField );
9091
}
9192
}
93+
// HHH-10646 Add fields inherited from @MappedSuperclass
94+
// CtClass.getFields() does not return private fields, while CtClass.getDeclaredFields() does not return inherit
95+
for ( CtField ctField : managedCtClass.getFields() ) {
96+
if ( !ctField.getDeclaringClass().hasAnnotation( MappedSuperclass.class ) || Modifier.isStatic( ctField.getModifiers() ) ) {
97+
continue;
98+
}
99+
if ( enhancementContext.isPersistentField( ctField ) ) {
100+
persistentFieldList.add( ctField );
101+
}
102+
}
92103
return enhancementContext.order( persistentFieldList.toArray( new CtField[persistentFieldList.size()] ) );
93104
}
94105

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,4 +381,14 @@ public static boolean isAssignable(CtClass thisCtClass, String targetClassName)
381381
return false;
382382
}
383383

384+
public static boolean isAssignable(CtField thisCtField, String targetClassName) {
385+
try {
386+
return isAssignable( thisCtField.getType(), targetClassName );
387+
}
388+
catch (NotFoundException e) {
389+
// keep going
390+
}
391+
return false;
392+
}
393+
384394
}

hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.hibernate.test.bytecode.enhancement.lazy.basic.LazyBasicPropertyAccessTestTask;
3434
import org.hibernate.test.bytecode.enhancement.lazy.group.LazyGroupAccessTestTask;
3535
import org.hibernate.test.bytecode.enhancement.lazyCache.InitFromCacheTestTask;
36+
import org.hibernate.test.bytecode.enhancement.mapped.MappedSuperclassTestTask;
3637
import org.hibernate.test.bytecode.enhancement.merge.CompositeMergeTestTask;
3738
import org.hibernate.test.bytecode.enhancement.ondemandload.LazyCollectionWithClearedSessionTestTask;
3839
import org.hibernate.test.bytecode.enhancement.ondemandload.LazyCollectionWithClosedSessionTestTask;
@@ -111,6 +112,12 @@ public void testLazyUnexpectedDelete() {
111112
EnhancerTestUtils.runEnhancerTestTask( UnexpectedDeleteTwoTestTask.class );
112113
}
113114

115+
@Test
116+
@TestForIssue( jiraKey = "HHH-10646" )
117+
public void testMappedSuperclass() {
118+
EnhancerTestUtils.runEnhancerTestTask( MappedSuperclassTestTask.class );
119+
}
120+
114121
@Test
115122
public void testMerge() {
116123
EnhancerTestUtils.runEnhancerTestTask( CompositeMergeTestTask.class );
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package org.hibernate.test.bytecode.enhancement.mapped;
2+
3+
import javax.persistence.Entity;
4+
import javax.persistence.Id;
5+
import javax.persistence.MappedSuperclass;
6+
import javax.persistence.Version;
7+
8+
import org.hibernate.Session;
9+
import org.hibernate.cfg.Configuration;
10+
import org.hibernate.cfg.Environment;
11+
12+
import org.hibernate.testing.bytecode.enhancement.EnhancerTestUtils;
13+
import org.hibernate.test.bytecode.enhancement.AbstractEnhancerTestTask;
14+
15+
/**
16+
* @author Luis Barreiro
17+
*/
18+
public class MappedSuperclassTestTask extends AbstractEnhancerTestTask {
19+
20+
public Class<?>[] getAnnotatedClasses() {
21+
return new Class<?>[] { Person.class, Employee.class };
22+
}
23+
24+
public void prepare() {
25+
Configuration cfg = new Configuration();
26+
cfg.setProperty( Environment.ENABLE_LAZY_LOAD_NO_TRANS, "true" );
27+
cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" );
28+
super.prepare( cfg );
29+
}
30+
31+
public void execute() {
32+
Employee charles = new Employee( "Charles", "Engineer" );
33+
charles.oca = 1002;
34+
35+
// Check that both types of class attributes are being dirty tracked
36+
EnhancerTestUtils.checkDirtyTracking( charles, "title", "oca" );
37+
}
38+
39+
protected void cleanup() {
40+
}
41+
42+
@MappedSuperclass private static class Person {
43+
44+
@Id String name;
45+
46+
@Version long oca;
47+
48+
public Person(String name) {
49+
this();
50+
this.name = name;
51+
}
52+
53+
protected Person() {}
54+
}
55+
56+
@Entity private static class Employee extends Person {
57+
58+
private String title;
59+
60+
public Employee(String name, String title) {
61+
super(name);
62+
this.title = title;
63+
}
64+
65+
public Employee() {}
66+
}
67+
}

0 commit comments

Comments
 (0)