HHH-15473 Instantiate collections in the default fetch group by default

This commit is contained in:
Yoann Rodière 2022-09-01 14:46:40 +02:00 committed by Sanne Grinovero
parent 767ff43d8c
commit c0afae8cb3
9 changed files with 67 additions and 85 deletions

View File

@ -638,7 +638,8 @@ public interface SessionFactoryBuilder {
* Should collections be included in the default fetch group when bytecode * Should collections be included in the default fetch group when bytecode
* enhancement is used? * enhancement is used?
* *
* @param enabled {@code true} collections should be included * @param enabled {@code true} collections should be included, {@code false} they should not.
* Default is {@code true}.
* *
* @return {@code this}, for method chaining * @return {@code this}, for method chaining
*/ */

View File

@ -196,7 +196,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
private boolean orderUpdatesEnabled; private boolean orderUpdatesEnabled;
private boolean orderInsertsEnabled; private boolean orderInsertsEnabled;
private boolean postInsertIdentifierDelayed; private boolean postInsertIdentifierDelayed;
private boolean collectionsInDefaultFetchGroupEnabled; private boolean collectionsInDefaultFetchGroupEnabled = true;
// JPA callbacks // JPA callbacks
private boolean callbacksEnabled; private boolean callbacksEnabled;

View File

@ -20,10 +20,6 @@ import jakarta.persistence.OneToMany;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.boot.internal.SessionFactoryBuilderImpl;
import org.hibernate.boot.internal.SessionFactoryOptionsBuilder;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.SessionFactoryBuilderService;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner; import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
@ -34,6 +30,7 @@ import org.junit.runner.RunWith;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
/** /**
* @author Christian Beikov * @author Christian Beikov
@ -47,19 +44,9 @@ public class DirtyTrackingCollectionInDefaultFetchGroupTest extends BaseCoreFunc
return new Class<?>[]{StringsEntity.class}; return new Class<?>[]{StringsEntity.class};
} }
@Override @Before
protected void prepareBasicRegistryBuilder(StandardServiceRegistryBuilder serviceRegistryBuilder) { public void checkSettings() {
serviceRegistryBuilder.addService( assertTrue( sessionFactory().getSessionFactoryOptions().isCollectionsInDefaultFetchGroupEnabled() );
SessionFactoryBuilderService.class,
(SessionFactoryBuilderService) (metadata, bootstrapContext) -> {
SessionFactoryOptionsBuilder optionsBuilder = new SessionFactoryOptionsBuilder(
metadata.getMetadataBuildingOptions().getServiceRegistry(),
bootstrapContext
);
optionsBuilder.enableCollectionInDefaultFetchGroup( true );
return new SessionFactoryBuilderImpl( metadata, optionsBuilder );
}
);
} }
@Before @Before

View File

@ -25,18 +25,15 @@ import jakarta.persistence.OrderColumn;
import jakarta.persistence.Temporal; import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType; import jakarta.persistence.TemporalType;
import org.hibernate.boot.internal.SessionFactoryBuilderImpl;
import org.hibernate.boot.internal.SessionFactoryOptionsBuilder;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.SessionFactoryBuilderService;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner; import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.jupiter.api.Assertions.assertTrue;
/** /**
* @author Christian Beikov * @author Christian Beikov
@ -50,19 +47,9 @@ public class DirtyTrackingPersistTest extends BaseCoreFunctionalTestCase {
return new Class<?>[] { HotherEntity.class, Hentity.class }; return new Class<?>[] { HotherEntity.class, Hentity.class };
} }
@Override @Before
protected void prepareBasicRegistryBuilder(StandardServiceRegistryBuilder serviceRegistryBuilder) { public void checkSettings() {
serviceRegistryBuilder.addService( assertTrue( sessionFactory().getSessionFactoryOptions().isCollectionsInDefaultFetchGroupEnabled() );
SessionFactoryBuilderService.class,
(SessionFactoryBuilderService) (metadata, bootstrapContext) -> {
SessionFactoryOptionsBuilder optionsBuilder = new SessionFactoryOptionsBuilder(
metadata.getMetadataBuildingOptions().getServiceRegistry(),
bootstrapContext
);
optionsBuilder.enableCollectionInDefaultFetchGroup( true );
return new SessionFactoryBuilderImpl( metadata, optionsBuilder );
}
);
} }
@Test @Test

View File

@ -116,13 +116,11 @@ public class LazyCollectionLoadingTest extends BaseCoreFunctionalTestCase {
Parent parent = s.find( Parent.class, parentID ); Parent parent = s.find( Parent.class, parentID );
assertThat( parent, notNullValue() ); assertThat( parent, notNullValue() );
assertThat( parent, not( instanceOf( HibernateProxy.class ) ) ); assertThat( parent, not( instanceOf( HibernateProxy.class ) ) );
assertFalse( isPropertyInitialized( parent, "children" ) );
checkDirtyTracking( parent ); checkDirtyTracking( parent );
List<Child> children1 = parent.children; List<Child> children1 = parent.children;
List<Child> children2 = parent.children; List<Child> children2 = parent.children;
assertTrue( isPropertyInitialized( parent, "children" ) );
checkDirtyTracking( parent ); checkDirtyTracking( parent );
assertThat( children1, sameInstance( children2 ) ); assertThat( children1, sameInstance( children2 ) );

View File

@ -15,13 +15,6 @@ import jakarta.persistence.FetchType;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import org.hibernate.boot.internal.SessionFactoryBuilderImpl;
import org.hibernate.boot.internal.SessionFactoryOptionsBuilder;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.SessionFactoryBuilderService;
import org.hibernate.cfg.Configuration;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner; import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Before; import org.junit.Before;
@ -30,6 +23,7 @@ import org.junit.runner.RunWith;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/** /**
* @author Christian Beikov * @author Christian Beikov
@ -42,19 +36,9 @@ public class MultipleBagsInLazyFetchGroupTest extends BaseCoreFunctionalTestCase
return new Class<?>[]{StringsEntity.class}; return new Class<?>[]{StringsEntity.class};
} }
@Override @Before
protected void prepareBasicRegistryBuilder(StandardServiceRegistryBuilder serviceRegistryBuilder) { public void checkSettings() {
serviceRegistryBuilder.addService( assertTrue( sessionFactory().getSessionFactoryOptions().isCollectionsInDefaultFetchGroupEnabled() );
SessionFactoryBuilderService.class,
(SessionFactoryBuilderService) (metadata, bootstrapContext) -> {
SessionFactoryOptionsBuilder optionsBuilder = new SessionFactoryOptionsBuilder(
metadata.getMetadataBuildingOptions().getServiceRegistry(),
bootstrapContext
);
optionsBuilder.enableCollectionInDefaultFetchGroup( true );
return new SessionFactoryBuilderImpl( metadata, optionsBuilder );
}
);
} }
@Before @Before

View File

@ -17,6 +17,10 @@ import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.LazyToOne; import org.hibernate.annotations.LazyToOne;
import org.hibernate.annotations.LazyToOneOption; import org.hibernate.annotations.LazyToOneOption;
import org.hibernate.boot.internal.SessionFactoryBuilderImpl;
import org.hibernate.boot.internal.SessionFactoryOptionsBuilder;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.SessionFactoryBuilderService;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Configuration;
import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.HibernateProxy;
@ -50,6 +54,22 @@ public class UninitializedAssociationsInCacheTest extends BaseCoreFunctionalTest
configuration.setProperty( AvailableSettings.GENERATE_STATISTICS, "true" ); configuration.setProperty( AvailableSettings.GENERATE_STATISTICS, "true" );
} }
@Override
protected void prepareBasicRegistryBuilder(StandardServiceRegistryBuilder serviceRegistryBuilder) {
serviceRegistryBuilder.addService(
SessionFactoryBuilderService.class,
(SessionFactoryBuilderService) (metadata, bootstrapContext) -> {
SessionFactoryOptionsBuilder optionsBuilder = new SessionFactoryOptionsBuilder(
metadata.getMetadataBuildingOptions().getServiceRegistry(),
bootstrapContext
);
// This test only makes sense if association properties *can* be uninitialized.
optionsBuilder.enableCollectionInDefaultFetchGroup( false );
return new SessionFactoryBuilderImpl( metadata, optionsBuilder );
}
);
}
@Test @Test
@TestForIssue( jiraKey = "HHH-11766") @TestForIssue( jiraKey = "HHH-11766")
public void attributeLoadingFromCache() { public void attributeLoadingFromCache() {

View File

@ -12,7 +12,6 @@ import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.FetchType; import jakarta.persistence.FetchType;
@ -21,12 +20,17 @@ import jakarta.persistence.ManyToMany;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import org.hibernate.LazyInitializationException; import org.hibernate.LazyInitializationException;
import org.hibernate.boot.internal.SessionFactoryBuilderImpl;
import org.hibernate.boot.internal.SessionFactoryOptionsBuilder;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.SessionFactoryBuilderService;
import org.hibernate.cfg.Configuration;
import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner; import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions; import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.After; import org.junit.After;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -35,7 +39,7 @@ import org.junit.runner.RunWith;
@RunWith(BytecodeEnhancerRunner.class) @RunWith(BytecodeEnhancerRunner.class)
@EnhancementOptions(lazyLoading = true) @EnhancementOptions(lazyLoading = true)
public class BytecodeEnhancedLazyLoadingOnDeletedEntityTest public class BytecodeEnhancedLazyLoadingOnDeletedEntityTest
extends BaseNonConfigCoreFunctionalTestCase { extends BaseCoreFunctionalTestCase {
@Override @Override
public Class<?>[] getAnnotatedClasses() { public Class<?>[] getAnnotatedClasses() {
@ -43,9 +47,25 @@ public class BytecodeEnhancedLazyLoadingOnDeletedEntityTest
} }
@Override @Override
protected void addSettings(Map<String,Object> settings) { protected void configure(Configuration configuration) {
super.addSettings( settings ); super.configure( configuration );
settings.put( DEFAULT_LIST_SEMANTICS, CollectionClassification.BAG.name() ); configuration.setProperty( DEFAULT_LIST_SEMANTICS, CollectionClassification.BAG.name() );
}
@Override
protected void prepareBasicRegistryBuilder(StandardServiceRegistryBuilder serviceRegistryBuilder) {
serviceRegistryBuilder.addService(
SessionFactoryBuilderService.class,
(SessionFactoryBuilderService) (metadata, bootstrapContext) -> {
SessionFactoryOptionsBuilder optionsBuilder = new SessionFactoryOptionsBuilder(
metadata.getMetadataBuildingOptions().getServiceRegistry(),
bootstrapContext
);
// This test only makes sense if association properties *can* be uninitialized.
optionsBuilder.enableCollectionInDefaultFetchGroup( false );
return new SessionFactoryBuilderImpl( metadata, optionsBuilder );
}
);
} }
@After @After

View File

@ -7,22 +7,17 @@
package org.hibernate.orm.test.bytecode.enhancement.lazy.proxy; package org.hibernate.orm.test.bytecode.enhancement.lazy.proxy;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.boot.internal.SessionFactoryBuilderImpl;
import org.hibernate.boot.internal.SessionFactoryOptionsBuilder;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.SessionFactoryBuilderService;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner; import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions; import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -52,20 +47,10 @@ public class LazyProxyBytecodeEnhancementCollectionInitializationTest
return new Class<?>[] { Parent.class, Child.class }; return new Class<?>[] { Parent.class, Child.class };
} }
@Override @Before
protected void prepareBasicRegistryBuilder(StandardServiceRegistryBuilder serviceRegistryBuilder) { public void checkSettings() {
serviceRegistryBuilder.addService( // We want to test this configuration exactly
SessionFactoryBuilderService.class, assertTrue( sessionFactory().getSessionFactoryOptions().isCollectionsInDefaultFetchGroupEnabled() );
(SessionFactoryBuilderService) (metadata, bootstrapContext) -> {
SessionFactoryOptionsBuilder optionsBuilder = new SessionFactoryOptionsBuilder(
metadata.getMetadataBuildingOptions().getServiceRegistry(),
bootstrapContext
);
// We want to test this configuration exactly
optionsBuilder.enableCollectionInDefaultFetchGroup( true );
return new SessionFactoryBuilderImpl( metadata, optionsBuilder );
}
);
} }
@Before @Before