diff --git a/design/fk.adoc b/design/fk.adoc index c160126912f4..b9d6265cd7aa 100644 --- a/design/fk.adoc +++ b/design/fk.adoc @@ -24,7 +24,7 @@ key-side:: `orders.customer_fk` target-side:: `customers.id` -Assuming bi-directionality, we have 2 `Association` refs: +Assuming bidirectionality, we have 2 `Association` refs: * `Order#customer` which models the key-side of the FK, * `Customer#orders` which models the target-side diff --git a/documentation/src/main/asciidoc/userguide/chapters/pc/BytecodeEnhancement.adoc b/documentation/src/main/asciidoc/userguide/chapters/pc/BytecodeEnhancement.adoc index 5ad420d6a3ff..280a839341fa 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/pc/BytecodeEnhancement.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/pc/BytecodeEnhancement.adoc @@ -97,7 +97,10 @@ include::{example-dir-enhancement}/BytecodeEnhancementTest.java[tags=BytecodeEnh ---- ==== -Bytecode-enhanced bi-directional association management makes that first example work by managing the "other side" of a bi-directional association whenever one side is manipulated. +Bytecode-enhanced bidirectional association management makes that first example work by managing the "other side" of a bidirectional association whenever one side is manipulated. + +[IMPORTANT] +Hibernate's bidirectional association management bytecode enhancement feature has been deprecated. Users should instead manage both sides of such associations directly. [[BytecodeEnhancement-dirty-tracking-optimizations]] ==== Internal performance optimizations diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/BiDirectionalAssociationHandler.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/BiDirectionalAssociationHandler.java index a3aa90e30f46..d1411e52ca31 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/BiDirectionalAssociationHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/BiDirectionalAssociationHandler.java @@ -66,7 +66,7 @@ static Implementation wrap( if ( bidirectionalAttributeName == null || bidirectionalAttributeName.isEmpty() ) { if ( log.isInfoEnabled() ) { log.infof( - "Bi-directional association not managed for field [%s#%s]: Could not find target field in [%s]", + "Bidirectional association not managed for field [%s#%s]: Could not find target field in [%s]", managedCtClass.getName(), persistentField.getName(), targetEntity.getCanonicalName() @@ -122,7 +122,7 @@ static Implementation wrap( if ( persistentField.getType().asErasure().isAssignableTo( Map.class ) || targetType.isAssignableTo( Map.class ) ) { if ( log.isInfoEnabled() ) { log.infof( - "Bi-directional association not managed for field [%s#%s]: @ManyToMany in java.util.Map attribute not supported ", + "Bidirectional association not managed for field [%s#%s]: @ManyToMany in java.util.Map attribute not supported ", managedCtClass.getName(), persistentField.getName() ); @@ -169,7 +169,7 @@ public static TypeDescription getTargetEntityClass(TypeDescription managedCtClas if ( targetClass == null ) { if ( log.isInfoEnabled() ) { log.infof( - "Bi-directional association not managed for field [%s#%s]: Could not find target type", + "Bidirectional association not managed for field [%s#%s]: Could not find target type", managedCtClass.getName(), persistentField.getName() ); @@ -208,7 +208,7 @@ private static String getMappedBy(AnnotatedFieldDescription target, TypeDescript return null; } else { - // HHH-13446 - mappedBy from annotation may not be a valid bi-directional association, verify by calling isValidMappedBy() + // HHH-13446 - mappedBy from annotation may not be a valid bidirectional association, verify by calling isValidMappedBy() return isValidMappedBy( target, targetEntity, mappedBy, context ) ? mappedBy : null; } } 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 b3dd61b331c3..e17ed60e7186 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 @@ -61,14 +61,16 @@ public interface EnhancementContext { boolean isMappedSuperclassClass(UnloadedClass classDescriptor); /** - * Should we manage association of bi-directional persistent attributes for this field? + * Should we manage association of bidirectional 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 + * @return {@code true} indicates that the field is enhanced so that for bidirectional persistent fields * the association is managed, i.e. the associations are automatically set; {@code false} indicates that * the management is handled by the user. + * @deprecated Will be removed without replacement. See HHH-19660 */ + @Deprecated(forRemoval = true) boolean doBiDirectionalAssociationManagement(UnloadedField field); /** diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/BiDirectionalFetch.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/BiDirectionalFetch.java index f0814f7f234b..edf4cebe0b86 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/BiDirectionalFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/BiDirectionalFetch.java @@ -40,7 +40,7 @@ * ``` * * - * Here we have one root result and 3 fetches. 2 of the fetches are bi-directional: + * Here we have one root result and 3 fetches. 2 of the fetches are bidirectional: * * `o`:: The paths `p` and `p.address.owner` (aliased as `o`) are the same table reference in SQL terms * `oa`:: The paths `p.address` and `p.address.owner.address` (aliased as `oa`) are again the same table reference diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/list/ListMappingTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/list/ListMappingTest.java index e4b4b7c8d4f5..4ff98aaf3ae0 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/list/ListMappingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/list/ListMappingTest.java @@ -104,7 +104,7 @@ public void accept(String action) { } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Bi-directional model + // Bidirectional model @Entity( name = "Order" ) @Table( name = "t_order" ) diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/association/OneToManyAssociationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/association/OneToManyAssociationTest.java index 9e3a6d022dcb..75823c0e3653 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/association/OneToManyAssociationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/association/OneToManyAssociationTest.java @@ -74,7 +74,7 @@ private static class Customer { String name; - // HHH-13446 - Type not validated in bi-directional association mapping + // HHH-13446 - Type not validated in bidirectional association mapping @OneToMany(cascade = CascadeType.ALL, mappedBy = "custId", fetch = FetchType.EAGER) List inventoryIdList = new ArrayList<>(); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/association/OneToOneAssociationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/association/OneToOneAssociationTest.java index b8abfb1d7e19..841abdcb09a2 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/association/OneToOneAssociationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/association/OneToOneAssociationTest.java @@ -33,7 +33,7 @@ public void test() { assertEquals( customer, user.getCustomer() ); - // check dirty tracking is set automatically with bi-directional association management + // check dirty tracking is set automatically with bidirectional association management EnhancerTestUtils.checkDirtyTracking( user, "login", "customer" ); User anotherUser = new User(); @@ -59,7 +59,7 @@ public void testSetNull() { assertEquals( customer, user.getCustomer() ); - // check dirty tracking is set automatically with bi-directional association management + // check dirty tracking is set automatically with bidirectional association management EnhancerTestUtils.checkDirtyTracking( user, "login", "customer" ); user.setCustomer( null ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/basic/ExtendedAssociationManagementTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/basic/ExtendedAssociationManagementTest.java index 611873655f19..c293a364385b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/basic/ExtendedAssociationManagementTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/basic/ExtendedAssociationManagementTest.java @@ -35,7 +35,7 @@ public void test() { assertEquals( customer, getFieldByReflection( user, "customer" ) ); - // check dirty tracking is set automatically with bi-directional association management + // check dirty tracking is set automatically with bidirectional association management EnhancerTestUtils.checkDirtyTracking( user, "login", "customer" ); User anotherUser = new User(); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/graphs/EntityGraphTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/graphs/EntityGraphTest.java index 1a5aa417e149..77d4bae2e456 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/graphs/EntityGraphTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/graphs/EntityGraphTest.java @@ -171,7 +171,7 @@ public void loadInverseCollection() { assertTrue( Hibernate.isInitialized( result.bar ) ); assertTrue( Hibernate.isInitialized( result.bar.getFoos()) ); assertTrue( Hibernate.isInitialized( result.baz ) ); - // sanity check -- ensure the only bi-directional fetch was the one identified by the graph + // sanity check -- ensure the only bidirectional fetch was the one identified by the graph assertFalse( Hibernate.isInitialized( result.baz.getFoos()) ); em.getTransaction().commit(); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetomany/OneToManyBidirectionalTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetomany/OneToManyBidirectionalTest.java index 02b158c6e298..99cc48c04255 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetomany/OneToManyBidirectionalTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetomany/OneToManyBidirectionalTest.java @@ -514,7 +514,7 @@ public void testRetrievingOrder(SessionFactoryScope scope) { */ // todo (6.0): this was originally intended to produce only a single SQL join, - // but joins are created before fetches, thus we don't know about bi-directional fetching/joining + // but joins are created before fetches, thus we don't know about bidirectional fetching/joining sqlStatementInterceptor.assertNumberOfJoins( 0, SqlAstJoinType.INNER, 2 ); sqlStatementInterceptor.clear(); @@ -559,7 +559,7 @@ public void testRetrievingOrder(SessionFactoryScope scope) { */ // todo (6.0): this was originally intended to produce only a single SQL join, - // but joins are created before fetches, thus we don't know about bi-directional fetching/joining + // but joins are created before fetches, thus we don't know about bidirectional fetching/joining sqlStatementInterceptor.assertNumberOfJoins( 0, SqlAstJoinType.INNER, 2 ); sqlStatementInterceptor.clear(); diff --git a/hibernate-core/src/test/resources/org/hibernate/orm/test/legacy/Marelo.hbm.xml b/hibernate-core/src/test/resources/org/hibernate/orm/test/legacy/Marelo.hbm.xml index 00736a9d9e45..d2e456ec32d0 100644 --- a/hibernate-core/src/test/resources/org/hibernate/orm/test/legacy/Marelo.hbm.xml +++ b/hibernate-core/src/test/resources/org/hibernate/orm/test/legacy/Marelo.hbm.xml @@ -28,7 +28,7 @@ - + diff --git a/hibernate-core/src/test/resources/org/hibernate/orm/test/mapping/schema.sql b/hibernate-core/src/test/resources/org/hibernate/orm/test/mapping/schema.sql index e52986c92686..05e24fa8f668 100644 --- a/hibernate-core/src/test/resources/org/hibernate/orm/test/mapping/schema.sql +++ b/hibernate-core/src/test/resources/org/hibernate/orm/test/mapping/schema.sql @@ -1,7 +1,7 @@ /* Needed because the test model maps a "non standard" schema. The test models `User#detail` and `UserDetail#user` as a - bi-directional one-to-one, meaning that Hibernate would + bidirectional one-to-one, meaning that Hibernate would normally (and correctly) create `t_user_details.user_fk` as unique. The test model changes that cardinality by use of `@Where`. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/AuditMappedBy.java b/hibernate-envers/src/main/java/org/hibernate/envers/AuditMappedBy.java index 0fbd29c1662d..5ba50501cb44 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/AuditMappedBy.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/AuditMappedBy.java @@ -11,10 +11,10 @@ /** *

- * Annotation to specify a "fake" bi-directional relation. Such a relation uses {@code @OneToMany} + + * Annotation to specify a "fake" bidirectional relation. Such a relation uses {@code @OneToMany} + * {@code @JoinColumn} on the one side, and {@code @ManyToOne} + {@code @Column(insertable=false, updatable=false)} on * the many side. Then, Envers won't use a join table to audit this relation, but will store changes as in a normal - * bi-directional relation. + * bidirectional relation. *

*

* This annotation is experimental and may change in future releases. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMappedByResolver.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMappedByResolver.java index 149015bda299..20eb74a6df16 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMappedByResolver.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMappedByResolver.java @@ -168,7 +168,7 @@ private static PersistentClass getReferenceCollectionClass(Collection collection referencedClass = oneToManyValue.getAssociatedClass(); } else if ( collectionValue.getElement() instanceof ManyToOne ) { - // Case for bi-directional relation with @JoinTable on the owning @ManyToOne side. + // Case for bidirectional relation with @JoinTable on the owning @ManyToOne side. final ManyToOne manyToOneValue = (ManyToOne) collectionValue.getElement(); referencedClass = manyToOneValue.getMetadata().getEntityBinding( manyToOneValue.getReferencedEntityName() ); } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/BaseEnversEventListener.java b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/BaseEnversEventListener.java index 6ccb3cdaf032..3b014881a028 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/BaseEnversEventListener.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/BaseEnversEventListener.java @@ -52,7 +52,7 @@ protected final void generateBidirectionalCollectionChangeWorkUnits( } // Checks every property of the entity, if it is an "owned" to-one relation to another entity. - // If the value of that property changed, and the relation is bi-directional, a new revision + // If the value of that property changed, and the relation is bidirectional, a new revision // for the related entity is generated. final String[] propertyNames = entityPersister.getPropertyNames(); diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneIdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneIdMapper.java index b3a507a202c0..64bbf686c1ef 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneIdMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneIdMapper.java @@ -55,7 +55,7 @@ public boolean mapToMapFromEntity( final HashMap newData = new HashMap<>(); // If this property is originally non-insertable, but made insertable because it is in a many-to-one "fake" - // bi-directional relation, we always store the "old", unchanged data, to prevent storing changes made + // bidirectional relation, we always store the "old", unchanged data, to prevent storing changes made // to this field. It is the responsibility of the collection to properly update it if it really changed. Object entity = nonInsertableFake ? oldObj : newObj; diff --git a/tooling/hibernate-ant/src/main/java/org/hibernate/tool/enhance/EnhancementTask.java b/tooling/hibernate-ant/src/main/java/org/hibernate/tool/enhance/EnhancementTask.java index ce83081b792e..57070836a764 100644 --- a/tooling/hibernate-ant/src/main/java/org/hibernate/tool/enhance/EnhancementTask.java +++ b/tooling/hibernate-ant/src/main/java/org/hibernate/tool/enhance/EnhancementTask.java @@ -204,6 +204,10 @@ public boolean doExtendedEnhancement(UnloadedClass classDescriptor) { DEPRECATION_LOGGER.deprecatedSettingForRemoval("extended enhancement", "false"); } + if ( enableAssociationManagement ) { + DEPRECATION_LOGGER.deprecatedSettingForRemoval( "management of bidirectional association persistent attributes", "false" ); + } + final BytecodeProvider bytecodeProvider = buildDefaultBytecodeProvider(); try { Enhancer enhancer = bytecodeProvider.getEnhancer( enhancementContext ); diff --git a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementHelper.java b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementHelper.java index e1133fe7bde2..b659dbd92915 100644 --- a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementHelper.java +++ b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementHelper.java @@ -47,6 +47,9 @@ public static void enhance( if ( !enhancementDsl.getEnableLazyInitialization().get() ) { logger.warn( "The 'enableLazyInitialization' configuration is deprecated and will be removed. Set the value to 'true' to get rid of this warning" ); } + if ( enhancementDsl.getEnableAssociationManagement().get() ) { + logger.warn("Management of bidirectional association persistent attributes is deprecated and will be removed. Set the value to 'false' to get rid of this warning" ); + } if ( !enhancementDsl.getEnableDirtyTracking().get() ) { logger.warn( "The 'enableDirtyTracking' configuration is deprecated and will be removed. Set the value to 'true' to get rid of this warning" ); } diff --git a/tooling/hibernate-maven-plugin/src/main/java/org/hibernate/orm/tooling/maven/EnhancementContext.java b/tooling/hibernate-maven-plugin/src/main/java/org/hibernate/orm/tooling/maven/EnhancementContext.java index 94420f5189b1..f8cbb8b8b0fc 100644 --- a/tooling/hibernate-maven-plugin/src/main/java/org/hibernate/orm/tooling/maven/EnhancementContext.java +++ b/tooling/hibernate-maven-plugin/src/main/java/org/hibernate/orm/tooling/maven/EnhancementContext.java @@ -38,6 +38,9 @@ public ClassLoader getLoadingClassLoader() { @Override public boolean doBiDirectionalAssociationManagement(UnloadedField field) { + if ( enableAssociationManagement ) { + DEPRECATION_LOGGER.deprecatedSettingForRemoval( "management of bidirectional persistent association attributes", "false" ); + } return enableAssociationManagement; }