Skip to content

Commit

Permalink
HHH-10646 - [enhancer] Add support for @MappedSuperclass
Browse files Browse the repository at this point in the history
  • Loading branch information
barreiro authored and sebersole committed Jun 2, 2016
1 parent 3a0824a commit e615d76
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 14 deletions.
Expand Up @@ -10,6 +10,9 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.persistence.MappedSuperclass;

import javassist.CannotCompileException;
import javassist.CtClass;
Expand Down Expand Up @@ -211,24 +214,33 @@ private void createDirtyTrackerMethods(CtClass managedCtClass) {

private List<CtField> collectCollectionFields(CtClass managedCtClass) {
final List<CtField> collectionList = new LinkedList<CtField>();
try {
for ( CtField ctField : managedCtClass.getDeclaredFields() ) {
// skip static fields and skip fields added by enhancement
if ( Modifier.isStatic( ctField.getModifiers() ) || ctField.getName().startsWith( "$$_hibernate_" ) ) {
continue;
}
if ( enhancementContext.isPersistentField( ctField ) ) {
for ( CtClass ctClass : ctField.getType().getInterfaces() ) {
if ( PersistentAttributesHelper.isAssignable( ctClass, Collection.class.getName() ) ) {
collectionList.add( ctField );
break;
}
}

for ( CtField ctField : managedCtClass.getDeclaredFields() ) {
// skip static fields and skip fields added by enhancement
if ( Modifier.isStatic( ctField.getModifiers() ) || ctField.getName().startsWith( "$$_hibernate_" ) ) {
continue;
}
if ( enhancementContext.isPersistentField( ctField ) ) {
if ( PersistentAttributesHelper.isAssignable( ctField, Collection.class.getName() ) ||
PersistentAttributesHelper.isAssignable( ctField, Map.class.getName() ) ) {
collectionList.add( ctField );
}
}
}
catch (NotFoundException ignored) {

// HHH-10646 Add fields inherited from @MappedSuperclass
for ( CtField ctField : managedCtClass.getDeclaredFields() ) {
if ( !ctField.getDeclaringClass().hasAnnotation( MappedSuperclass.class ) || Modifier.isStatic( ctField.getModifiers() ) ) {
continue;
}
if ( enhancementContext.isPersistentField( ctField ) ) {
if ( PersistentAttributesHelper.isAssignable( ctField, Collection.class.getName() ) ||
PersistentAttributesHelper.isAssignable( ctField, Map.class.getName() ) ) {
collectionList.add( ctField );
}
}
}

return collectionList;
}

Expand Down
Expand Up @@ -14,6 +14,7 @@
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;

Expand Down Expand Up @@ -89,6 +90,16 @@ private CtField[] collectPersistentFields(CtClass managedCtClass) {
persistentFieldList.add( ctField );
}
}
// HHH-10646 Add fields inherited from @MappedSuperclass
// CtClass.getFields() does not return private fields, while CtClass.getDeclaredFields() does not return inherit
for ( CtField ctField : managedCtClass.getFields() ) {
if ( !ctField.getDeclaringClass().hasAnnotation( MappedSuperclass.class ) || Modifier.isStatic( ctField.getModifiers() ) ) {
continue;
}
if ( enhancementContext.isPersistentField( ctField ) ) {
persistentFieldList.add( ctField );
}
}
return enhancementContext.order( persistentFieldList.toArray( new CtField[persistentFieldList.size()] ) );
}

Expand Down
Expand Up @@ -381,4 +381,14 @@ public static boolean isAssignable(CtClass thisCtClass, String targetClassName)
return false;
}

public static boolean isAssignable(CtField thisCtField, String targetClassName) {
try {
return isAssignable( thisCtField.getType(), targetClassName );
}
catch (NotFoundException e) {
// keep going
}
return false;
}

}
Expand Up @@ -33,6 +33,7 @@
import org.hibernate.test.bytecode.enhancement.lazy.basic.LazyBasicPropertyAccessTestTask;
import org.hibernate.test.bytecode.enhancement.lazy.group.LazyGroupAccessTestTask;
import org.hibernate.test.bytecode.enhancement.lazyCache.InitFromCacheTestTask;
import org.hibernate.test.bytecode.enhancement.mapped.MappedSuperclassTestTask;
import org.hibernate.test.bytecode.enhancement.merge.CompositeMergeTestTask;
import org.hibernate.test.bytecode.enhancement.ondemandload.LazyCollectionWithClearedSessionTestTask;
import org.hibernate.test.bytecode.enhancement.ondemandload.LazyCollectionWithClosedSessionTestTask;
Expand Down Expand Up @@ -111,6 +112,12 @@ public void testLazyUnexpectedDelete() {
EnhancerTestUtils.runEnhancerTestTask( UnexpectedDeleteTwoTestTask.class );
}

@Test
@TestForIssue( jiraKey = "HHH-10646" )
public void testMappedSuperclass() {
EnhancerTestUtils.runEnhancerTestTask( MappedSuperclassTestTask.class );
}

@Test
public void testMerge() {
EnhancerTestUtils.runEnhancerTestTask( CompositeMergeTestTask.class );
Expand Down
@@ -0,0 +1,67 @@
package org.hibernate.test.bytecode.enhancement.mapped;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;

import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;

import org.hibernate.testing.bytecode.enhancement.EnhancerTestUtils;
import org.hibernate.test.bytecode.enhancement.AbstractEnhancerTestTask;

/**
* @author Luis Barreiro
*/
public class MappedSuperclassTestTask extends AbstractEnhancerTestTask {

public Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Person.class, Employee.class };
}

public void prepare() {
Configuration cfg = new Configuration();
cfg.setProperty( Environment.ENABLE_LAZY_LOAD_NO_TRANS, "true" );
cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" );
super.prepare( cfg );
}

public void execute() {
Employee charles = new Employee( "Charles", "Engineer" );
charles.oca = 1002;

// Check that both types of class attributes are being dirty tracked
EnhancerTestUtils.checkDirtyTracking( charles, "title", "oca" );
}

protected void cleanup() {
}

@MappedSuperclass private static class Person {

@Id String name;

@Version long oca;

public Person(String name) {
this();
this.name = name;
}

protected Person() {}
}

@Entity private static class Employee extends Person {

private String title;

public Employee(String name, String title) {
super(name);
this.title = title;
}

public Employee() {}
}
}

0 comments on commit e615d76

Please sign in to comment.