From 165f037bad08ae9ef0733842b040e244a90fd9b9 Mon Sep 17 00:00:00 2001 From: barreiro Date: Tue, 31 Mar 2015 19:01:56 +0100 Subject: [PATCH] HHH-8489 - bytecode enhancement: bi-directional associtation management Closes #933 --- .../internal/AttributeTypeDescriptor.java | 4 +- .../PersistentAttributesEnhancer.java | 224 +++++++++++++++--- .../spi/DefaultEnhancementContext.java | 7 + .../enhance/spi/EnhancementContext.java | 11 + .../tool/enhance/EnhancementTask.java | 45 ++-- .../enhancement/CustomerEnhancerTest.java | 97 +++++++- .../enhancement/entity/customer/Customer.java | 18 ++ .../entity/customer/CustomerInventory.java | 4 + .../enhancement/entity/customer/Group.java | 77 ++++++ .../enhancement/entity/customer/User.java | 100 ++++++++ .../enhance/plugins/MavenEnhancePlugin.java | 37 +-- .../tooling/gradle/EnhancerTask.groovy | 4 + 12 files changed, 553 insertions(+), 75 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/entity/customer/Group.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/entity/customer/User.java diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/AttributeTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/AttributeTypeDescriptor.java index 145e964f3b..3fc5173bb4 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/AttributeTypeDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/AttributeTypeDescriptor.java @@ -67,7 +67,7 @@ public abstract class AttributeTypeDescriptor { || currentValue.getType().getName().startsWith( "java.sql.Date" ) || currentValue.getType().getName().startsWith( "java.util.Date" ) || currentValue.getType().getName().startsWith( "java.util.Calendar" ) ) { - builder.append( String.format( "&& ((%s == null) || (!% targetClass = null; + if (persistentField.hasAnnotation( OneToOne.class )) { + targetClass = ((OneToOne) persistentField.getAnnotation( OneToOne.class )).targetEntity(); + } + if (persistentField.hasAnnotation( OneToMany.class )) { + targetClass = ((OneToMany) persistentField.getAnnotation( OneToMany.class )).targetEntity(); + } + if (persistentField.hasAnnotation( ManyToOne.class )) { + targetClass = ((ManyToOne) persistentField.getAnnotation( ManyToOne.class )).targetEntity(); + } + if (persistentField.hasAnnotation( ManyToMany.class )) { + targetClass = ((ManyToMany) persistentField.getAnnotation( ManyToMany.class )).targetEntity(); + } + if ( targetClass != null && targetClass != void.class ) { + return classPool.get( targetClass.getName() ); + } + } + catch (ClassNotFoundException ignore) { + } + + // infer targetEntity from generic type signature + if ( persistentField.hasAnnotation( OneToOne.class ) || persistentField.hasAnnotation( ManyToOne.class )) { + return persistentField.getType(); + } + if ( persistentField.hasAnnotation( OneToMany.class ) || persistentField.hasAnnotation( ManyToMany.class )) { + try { + final SignatureAttribute.TypeArgument target = ((SignatureAttribute.ClassType) SignatureAttribute.toFieldSignature( persistentField.getGenericSignature() )).getTypeArguments()[0]; + return persistentField.getDeclaringClass().getClassPool().get( target.toString() ); + } + catch (BadBytecode ignore) { + } + } + return null; + } + + /* --- */ + + private void handleCompositeField(CtClass managedCtClass, CtField persistentField, CtMethod fieldWriter) throws NotFoundException, CannotCompileException { + if ( !persistentField.hasAnnotation( Embedded.class ) ) { + return; + } + + // make sure to add the CompositeOwner interface + managedCtClass.addInterface( classPool.get( CompositeOwner.class.getName() ) ); + + if ( enhancementContext.isCompositeClass( managedCtClass ) ) { + // if a composite have a embedded field we need to implement the TRACKER_CHANGER_NAME method as well + MethodWriter.write( managedCtClass, "" + + "public void %1$s(String name) {%n" + + " if (%2$s != null) { %2$s.callOwner(\".\" + name) ; }%n}", + EnhancerConstants.TRACKER_CHANGER_NAME, + EnhancerConstants.TRACKER_COMPOSITE_FIELD_NAME ); + } + + // cleanup previous owner + fieldWriter.insertBefore( String.format( "" + + "if (%1$s != null) { ((%2$s) %1$s).%3$s(\"%1$s\"); }%n", + persistentField.getName(), + CompositeTracker.class.getName(), + EnhancerConstants.TRACKER_COMPOSITE_CLEAR_OWNER) ); + + // trigger track changes + fieldWriter.insertAfter( String.format( "" + + "((%2$s) %1$s).%4$s(\"%1$s\", (%3$s) this);%n" + + "%5$s(\"%1$s\");", + persistentField.getName(), + CompositeTracker.class.getName(), + CompositeOwner.class.getName(), + EnhancerConstants.TRACKER_COMPOSITE_SET_OWNER, + EnhancerConstants.TRACKER_CHANGER_NAME ) ); + } + + /* --- */ + protected void enhanceAttributesAccess(CtClass managedCtClass, IdentityHashMap attributeDescriptorMap) { final ConstPool constPool = managedCtClass.getClassFile().getConstPool(); diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/DefaultEnhancementContext.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/DefaultEnhancementContext.java index d57a1acabc..b2e0d390a2 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/DefaultEnhancementContext.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/DefaultEnhancementContext.java @@ -61,6 +61,13 @@ public class DefaultEnhancementContext implements EnhancementContext { return classDescriptor.hasAnnotation( Embeddable.class ); } + /** + * @return true + */ + public boolean doBiDirectionalAssociationManagement(CtField field) { + return true; + } + /** * @return true */ diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/EnhancementContext.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/EnhancementContext.java index e69e8551b6..3bfc4ce5ee 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/EnhancementContext.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/EnhancementContext.java @@ -69,6 +69,17 @@ public interface EnhancementContext { */ public boolean isCompositeClass(CtClass classDescriptor); + /** + * Should we manage association of bi-directional persistent attributes for this field? + * + * @param field The field to check. + * + * @return {@code true} indicates that the field is enhanced so that for bi-directional persistent fields + * the association is managed, i.e. the associations are automatically set; {@code false} indicates that + * the management is handled by the user. + */ + public boolean doBiDirectionalAssociationManagement(CtField field); + /** * Should we in-line dirty checking for persistent attributes for this class? * diff --git a/hibernate-core/src/main/java/org/hibernate/tool/enhance/EnhancementTask.java b/hibernate-core/src/main/java/org/hibernate/tool/enhance/EnhancementTask.java index 0f1366fdf9..028021e833 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/enhance/EnhancementTask.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/enhance/EnhancementTask.java @@ -23,6 +23,23 @@ */ package org.hibernate.tool.enhance; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtField; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.FileSet; +import org.hibernate.bytecode.enhance.spi.EnhancementContext; +import org.hibernate.bytecode.enhance.spi.Enhancer; + +import javax.persistence.ElementCollection; +import javax.persistence.Embeddable; +import javax.persistence.Entity; +import javax.persistence.ManyToMany; +import javax.persistence.OneToMany; +import javax.persistence.Transient; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -30,25 +47,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import javax.persistence.ElementCollection; -import javax.persistence.Embeddable; -import javax.persistence.Entity; -import javax.persistence.ManyToMany; -import javax.persistence.OneToMany; -import javax.persistence.Transient; - -import javassist.ClassPool; -import javassist.CtClass; -import javassist.CtField; - -import org.hibernate.bytecode.enhance.spi.EnhancementContext; -import org.hibernate.bytecode.enhance.spi.Enhancer; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.types.FileSet; /** * Ant task for performing build-time enhancement of entities and component/embeddable classes. @@ -74,7 +72,7 @@ public class EnhancementTask extends Task implements EnhancementContext { @Override public void execute() throws BuildException { - log( "Starting Hibernate EnhancementTask execution", Project.MSG_INFO ); + log("Starting Hibernate EnhancementTask execution", Project.MSG_INFO); // we use the CtClass stuff here just as a simple vehicle for obtaining low level information about // the class(es) contained in a file while still maintaining easy access to the underlying byte[] @@ -116,7 +114,7 @@ public class EnhancementTask extends Task implements EnhancementContext { private void processEntityClassFile(File javaClassFile, CtClass ctClass ) { try { - byte[] result = enhancer.enhance( ctClass.getName(), ctClass.toBytecode() ); + byte[] result = enhancer.enhance(ctClass.getName(), ctClass.toBytecode()); if(result != null) writeEnhancedClass(javaClassFile, result); } @@ -187,6 +185,11 @@ public class EnhancementTask extends Task implements EnhancementContext { return classDescriptor.hasAnnotation(Embeddable.class); } + @Override + public boolean doBiDirectionalAssociationManagement(CtField field) { + return false; + } + @Override public boolean doDirtyCheckingInline(CtClass classDescriptor) { return true; diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/CustomerEnhancerTest.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/CustomerEnhancerTest.java index 753b109802..f16869134c 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/CustomerEnhancerTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/CustomerEnhancerTest.java @@ -30,16 +30,24 @@ import org.hibernate.engine.spi.PersistentAttributeInterceptor; import org.hibernate.test.bytecode.enhancement.entity.customer.Address; import org.hibernate.test.bytecode.enhancement.entity.customer.Customer; import org.hibernate.test.bytecode.enhancement.entity.customer.CustomerInventory; +import org.hibernate.test.bytecode.enhancement.entity.customer.Group; import org.hibernate.test.bytecode.enhancement.entity.customer.SupplierComponentPK; +import org.hibernate.test.bytecode.enhancement.entity.customer.User; import org.hibernate.testing.junit4.BaseUnitTestCase; import org.junit.Test; import java.lang.reflect.Method; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; /** * @author Steve Ebersole @@ -52,7 +60,8 @@ public class CustomerEnhancerTest extends BaseUnitTestCase { } private void testFor(Class entityClassToEnhance) throws Exception { - ClassLoader cl = new ClassLoader() {}; + ClassLoader cl = new ClassLoader() { + }; // just for debugging Class addressClass = EnhancerTestUtils.enhanceAndDecompile(Address.class, cl); @@ -69,7 +78,7 @@ public class CustomerEnhancerTest extends BaseUnitTestCase { assertNull(getter.invoke(entityInstance)); setter.invoke(entityInstance, EnhancerTestUtils.makeEntityEntry()); assertNotNull(getter.invoke(entityInstance)); - setter.invoke(entityInstance, new Object[] {null}); + setter.invoke(entityInstance, new Object[]{null}); assertNull(getter.invoke(entityInstance)); Method entityInstanceGetter = entityClass.getMethod(EnhancerConstants.ENTITY_INSTANCE_GETTER_NAME); @@ -83,7 +92,7 @@ public class CustomerEnhancerTest extends BaseUnitTestCase { Method nextGetter = entityClass.getMethod(EnhancerConstants.PREVIOUS_GETTER_NAME); Method nextSetter = entityClass.getMethod(EnhancerConstants.PREVIOUS_SETTER_NAME, ManagedEntity.class); nextSetter.invoke(entityInstance, entityInstance); - assertSame( entityInstance, nextGetter.invoke(entityInstance)); + assertSame(entityInstance, nextGetter.invoke(entityInstance)); // add an attribute interceptor... assertNull(entityClass.getMethod(EnhancerConstants.INTERCEPTOR_GETTER_NAME).invoke(entityInstance)); @@ -120,4 +129,86 @@ public class CustomerEnhancerTest extends BaseUnitTestCase { EnhancerTestUtils.checkDirtyTracking(entityInstance, "address"); } + + @Test + public void testBiDirectionalAssociationManagement() throws Exception { + ClassLoader cl = new ClassLoader() { + }; + + Class userClass = EnhancerTestUtils.enhanceAndDecompile(User.class, cl); + Class groupClass = EnhancerTestUtils.enhanceAndDecompile(Group.class, cl); + Class customerClass = EnhancerTestUtils.enhanceAndDecompile(Customer.class, cl); + Class customerInventoryClass = EnhancerTestUtils.enhanceAndDecompile(CustomerInventory.class, cl); + + Object userInstance = userClass.newInstance(); + assertTyping(ManagedEntity.class, userInstance); + + Object groupInstance = groupClass.newInstance(); + assertTyping(ManagedEntity.class, groupInstance); + + Object customerInstance = customerClass.newInstance(); + assertTyping(ManagedEntity.class, customerInstance); + + Object customerInventoryInstance = customerInventoryClass.newInstance(); + assertTyping(ManagedEntity.class, customerInventoryInstance); + + Method interceptorSetter = userClass.getMethod(EnhancerConstants.INTERCEPTOR_SETTER_NAME, PersistentAttributeInterceptor.class); + interceptorSetter.invoke(userInstance, new EnhancerTestUtils.LocalPersistentAttributeInterceptor()); + + /* --- @OneToOne */ + + userClass.getMethod("setLogin", String.class).invoke(userInstance, UUID.randomUUID().toString()); + + customerClass.getMethod("setUser", userClass).invoke(customerInstance, userInstance); + assertEquals(customerInstance, userClass.getMethod("getCustomer").invoke(userInstance)); + + // check dirty tracking is set automatically with bi-directional association management + EnhancerTestUtils.checkDirtyTracking(userInstance, "login", "customer"); + + Object anotherUser = userClass.newInstance(); + userClass.getMethod("setLogin", String.class).invoke(anotherUser, UUID.randomUUID().toString()); + + customerClass.getMethod("setUser", userClass).invoke(customerInstance, anotherUser); + assertEquals(null, userClass.getMethod("getCustomer").invoke(userInstance)); + assertEquals(customerInstance, userClass.getMethod("getCustomer").invoke(anotherUser)); + + userClass.getMethod("setCustomer", customerClass).invoke(userInstance, customerClass.newInstance()); + assertEquals(userInstance, customerClass.getMethod("getUser").invoke(userClass.getMethod("getCustomer").invoke(userInstance))); + + /* --- @OneToMany @ManyToOne */ + + assertTrue(((Collection) customerClass.getMethod("getInventories").invoke(customerInstance)).isEmpty()); + customerInventoryClass.getMethod("setCustomer", customerClass).invoke(customerInventoryInstance, customerInstance); + + Collection inventories = (Collection < ?>) customerClass.getMethod("getInventories").invoke(customerInstance); + assertTrue(inventories.size() == 1); + assertTrue(inventories.contains(customerInventoryInstance)); + + Object anotherCustomer = customerClass.newInstance(); + customerInventoryClass.getMethod("setCustomer", customerClass).invoke(customerInventoryInstance, anotherCustomer); + assertTrue(((Collection) customerClass.getMethod("getInventories").invoke(customerInstance)).isEmpty()); + + customerClass.getMethod("addInventory", customerInventoryClass).invoke(customerInstance, customerInventoryInstance); + assertTrue(customerInventoryClass.getMethod("getCustomer").invoke(customerInventoryInstance) == customerInstance); + + inventories = (Collection < ?>) customerClass.getMethod("getInventories").invoke(customerInstance); + assertTrue(inventories.size() == 1); + + customerClass.getMethod("addInventory", customerInventoryClass).invoke(customerInstance, customerInventoryClass.newInstance()); + assertTrue(((Collection) customerClass.getMethod("getInventories").invoke(customerInstance)).size() == 2); + + /* --- @ManyToMany */ + + Object anotherGroup = groupClass.newInstance(); + userClass.getMethod("addGroup", groupClass).invoke(userInstance, groupInstance); + userClass.getMethod("addGroup", groupClass).invoke(userInstance, anotherGroup); + userClass.getMethod("addGroup", groupClass).invoke(anotherUser, groupInstance); + + assertTrue(((Collection) groupClass.getMethod("getUsers").invoke(groupInstance)).size() == 2); + + groupClass.getMethod("setUsers", Set.class).invoke(groupInstance, new HashSet()); + assertTrue(((Collection) userClass.getMethod("getGroups").invoke(userInstance)).size() == 1); + + } + } diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/entity/customer/Customer.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/entity/customer/Customer.java index 70dc6e032d..25786cd0af 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/entity/customer/Customer.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/entity/customer/Customer.java @@ -32,6 +32,7 @@ import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.OneToMany; +import javax.persistence.OneToOne; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @@ -57,6 +58,9 @@ public class Customer { @Column(name="C_ID") private int id; + @OneToOne + private User user; + @Column(name="C_FIRST") private String firstName; @@ -209,6 +213,20 @@ public class Customer { return customerInventories; } + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public void addInventory(CustomerInventory inventory) { + List list = getInventories(); + list.add(inventory); + customerInventories = list; + } + public CustomerInventory addInventory(String item, int quantity, BigDecimal totalValue) { diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/entity/customer/CustomerInventory.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/entity/customer/CustomerInventory.java index 9490da8a87..134416bcd7 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/entity/customer/CustomerInventory.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/entity/customer/CustomerInventory.java @@ -115,6 +115,10 @@ public class CustomerInventory implements Serializable, ComparatorStåle W. Pedersen + */ +@Entity +@Table(name = "GROUP") +@SequenceGenerator(name = "GROUP_SEQUENCE", sequenceName = "GROUP_SEQUENCE", allocationSize = 1, initialValue = 0) +public class Group { + + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "GROUP_SEQUENCE") + private int id; + + @Column + private String name; + + @ManyToMany(mappedBy = "groups") + private Set users = new HashSet(); + + public Group() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Set getUsers() { + return users; + } + + public void setUsers(Set users) { + this.users = users; + } + + public void removeUser(User user) { + Set set = this.users; + set.remove(user); + this.users = set; + } +} \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/entity/customer/User.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/entity/customer/User.java new file mode 100644 index 0000000000..dbd5209060 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/entity/customer/User.java @@ -0,0 +1,100 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2012, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.bytecode.enhancement.entity.customer; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.ManyToMany; +import javax.persistence.OneToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Ståle W. Pedersen + */ +@Entity +@Table(name = "USER") +@SequenceGenerator(name = "USER_SEQUENCE", sequenceName = "USER_SEQUENCE", allocationSize = 1, initialValue = 0) +public class User { + + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_SEQUENCE") + private int id; + + @Column + private String login; + + @Column + private String password; + + @OneToOne(mappedBy = "user") + private Customer customer; + + @ManyToMany + private Set groups; + + public User() { + } + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public void addGroup(Group group) { + Set set = (groups == null ? new HashSet() : groups); + set.add(group); + groups = set; + } + + public Set getGroups() { + return groups; + } + + public void setGroups(Set groups) { + this.groups = groups; + } +} \ No newline at end of file diff --git a/tooling/hibernate-enhance-maven-plugin/src/main/java/org/hibernate/bytecode/enhance/plugins/MavenEnhancePlugin.java b/tooling/hibernate-enhance-maven-plugin/src/main/java/org/hibernate/bytecode/enhance/plugins/MavenEnhancePlugin.java index ae72e39422..dc8317305a 100644 --- a/tooling/hibernate-enhance-maven-plugin/src/main/java/org/hibernate/bytecode/enhance/plugins/MavenEnhancePlugin.java +++ b/tooling/hibernate-enhance-maven-plugin/src/main/java/org/hibernate/bytecode/enhance/plugins/MavenEnhancePlugin.java @@ -23,26 +23,9 @@ */ package org.hibernate.bytecode.enhance.plugins; -import java.io.File; -import java.io.FileFilter; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - import javassist.ClassPool; import javassist.CtClass; import javassist.CtField; - -import javax.persistence.ElementCollection; -import javax.persistence.Embeddable; -import javax.persistence.Entity; -import javax.persistence.ManyToMany; -import javax.persistence.OneToMany; -import javax.persistence.Transient; - import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -53,6 +36,21 @@ import org.apache.maven.plugins.annotations.Parameter; import org.hibernate.bytecode.enhance.spi.EnhancementContext; import org.hibernate.bytecode.enhance.spi.Enhancer; +import javax.persistence.ElementCollection; +import javax.persistence.Embeddable; +import javax.persistence.Entity; +import javax.persistence.ManyToMany; +import javax.persistence.OneToMany; +import javax.persistence.Transient; +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + /** * This plugin will enhance Entity objects. * @@ -228,6 +226,11 @@ public class MavenEnhancePlugin extends AbstractMojo implements EnhancementConte return classDescriptor.hasAnnotation(Embeddable.class); } + @Override + public boolean doBiDirectionalAssociationManagement(CtField field) { + return false; + } + @Override public boolean doDirtyCheckingInline(CtClass classDescriptor) { return true; diff --git a/tooling/hibernate-gradle-plugin/src/main/groovy/org/hibernate/tooling/gradle/EnhancerTask.groovy b/tooling/hibernate-gradle-plugin/src/main/groovy/org/hibernate/tooling/gradle/EnhancerTask.groovy index e2ac57e746..7b8f618f9c 100644 --- a/tooling/hibernate-gradle-plugin/src/main/groovy/org/hibernate/tooling/gradle/EnhancerTask.groovy +++ b/tooling/hibernate-gradle-plugin/src/main/groovy/org/hibernate/tooling/gradle/EnhancerTask.groovy @@ -146,6 +146,10 @@ public class EnhancerTask extends DefaultTask implements EnhancementContext { return false; } + public boolean doBiDirectionalAssociationManagement(CtField field) { + return false; + } + public boolean doDirtyCheckingInline(CtClass classDescriptor) { return true; }