Skip to content

HHH-19660 - Deprecate enhancement support for automatic association management #10645

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion design/fk.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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()
);
Expand Down Expand Up @@ -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()
);
Expand Down Expand Up @@ -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;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public void accept(String action) {
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Bi-directional model
// Bidirectional model

@Entity( name = "Order" )
@Table( name = "t_order" )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<CustomerInventory> inventoryIdList = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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 );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

<!-- Associations -->

<!-- bi-directional one-to-one association to Commento -->
<!-- bidirectional one-to-one association to Commento -->
<many-to-one name="commento" entity-name="Commento" unique="false" insert="false" update="false">
<column name="MLCOM"/>
</many-to-one>
Expand Down
Original file line number Diff line number Diff line change
@@ -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`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@

/**
* <p>
* 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.
* </p>
* <p>
* This annotation is <b>experimental</b> and may change in future releases.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public boolean mapToMapFromEntity(
final HashMap<String, Object> 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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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" );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
Loading