mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-17 00:24:57 +00:00
Fix issue with fetch deep and hql join fetch recognition
This commit is contained in:
parent
7d74f1c727
commit
c10b4e0f2f
@ -24,4 +24,9 @@ default String getFetchableName() {
|
|||||||
* of this association's foreign-key
|
* of this association's foreign-key
|
||||||
*/
|
*/
|
||||||
ModelPart getKeyTargetMatchPart();
|
ModelPart getKeyTargetMatchPart();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default boolean incrementFetchDepth(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,4 +61,9 @@ default void visitFetchables(Consumer<Fetchable> fetchableConsumer, EntityMappin
|
|||||||
String getSeparateCollectionTable();
|
String getSeparateCollectionTable();
|
||||||
|
|
||||||
boolean isBidirectionalAttributeName(NavigablePath fetchablePath);
|
boolean isBidirectionalAttributeName(NavigablePath fetchablePath);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default boolean incrementFetchDepth(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -710,7 +710,7 @@ private void consumeAttributeJoin(SqmAttributeJoin<?,?> sqmJoin, TableGroup lhsT
|
|||||||
final NavigablePath parentNavigablePath = sqmJoinNavigablePath.getParent();
|
final NavigablePath parentNavigablePath = sqmJoinNavigablePath.getParent();
|
||||||
if ( pathSource instanceof PluralPersistentAttribute ) {
|
if ( pathSource instanceof PluralPersistentAttribute ) {
|
||||||
final ModelPart pluralPart = lhsTableGroup.getModelPart().findSubPart(
|
final ModelPart pluralPart = lhsTableGroup.getModelPart().findSubPart(
|
||||||
sqmJoin.getReferencedPathSource().getPathName(),
|
pathSource.getPathName(),
|
||||||
SqmMappingModelHelper.resolveExplicitTreatTarget( sqmJoin, this )
|
SqmMappingModelHelper.resolveExplicitTreatTarget( sqmJoin, this )
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -751,7 +751,7 @@ private void consumeAttributeJoin(SqmAttributeJoin<?,?> sqmJoin, TableGroup lhsT
|
|||||||
lhsTableGroup.addTableGroupJoin( joinedTableGroupJoin );
|
lhsTableGroup.addTableGroupJoin( joinedTableGroupJoin );
|
||||||
|
|
||||||
fromClauseIndex.register( sqmJoin, joinedTableGroup, elementPath );
|
fromClauseIndex.register( sqmJoin, joinedTableGroup, elementPath );
|
||||||
fromClauseIndex.registerTableGroup( elementPath, joinedTableGroup );
|
// fromClauseIndex.registerTableGroup( elementPath, joinedTableGroup );
|
||||||
}
|
}
|
||||||
else if ( pathSource instanceof EmbeddedSqmPathSource ) {
|
else if ( pathSource instanceof EmbeddedSqmPathSource ) {
|
||||||
final ModelPart joinedPart = lhsTableGroup.getModelPart().findSubPart(
|
final ModelPart joinedPart = lhsTableGroup.getModelPart().findSubPart(
|
||||||
@ -803,8 +803,27 @@ else if ( pathSource instanceof EmbeddedSqmPathSource ) {
|
|||||||
joinedPath = parentNavigablePath.append( sqmJoin.getAttribute().getName() );
|
joinedPath = parentNavigablePath.append( sqmJoin.getAttribute().getName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NavigablePath elementPath;
|
||||||
|
if ( parentNavigablePath == null ) {
|
||||||
|
elementPath = sqmJoinNavigablePath;
|
||||||
|
pluralPersisterElementNavigablePathByFullPath.put(
|
||||||
|
sqmJoin.getNavigablePath().getFullPath(),
|
||||||
|
elementPath
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final NavigablePath elementNavigablePath = pluralPersisterElementNavigablePathByFullPath.get(
|
||||||
|
parentNavigablePath.getFullPath() );
|
||||||
|
if ( elementNavigablePath == null ) {
|
||||||
|
elementPath = sqmJoinNavigablePath;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
elementPath = elementNavigablePath.append( joinedPart.getPartName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
joinedTableGroupJoin = ( (TableGroupJoinProducer) joinedPart ).createTableGroupJoin(
|
joinedTableGroupJoin = ( (TableGroupJoinProducer) joinedPart ).createTableGroupJoin(
|
||||||
joinedPath,
|
elementPath,
|
||||||
lhsTableGroup,
|
lhsTableGroup,
|
||||||
sqmJoin.getExplicitAlias(),
|
sqmJoin.getExplicitAlias(),
|
||||||
sqmJoin.getSqmJoinType().getCorrespondingSqlJoinType(),
|
sqmJoin.getSqmJoinType().getCorrespondingSqlJoinType(),
|
||||||
@ -816,7 +835,7 @@ else if ( pathSource instanceof EmbeddedSqmPathSource ) {
|
|||||||
|
|
||||||
lhsTableGroup.addTableGroupJoin( joinedTableGroupJoin );
|
lhsTableGroup.addTableGroupJoin( joinedTableGroupJoin );
|
||||||
|
|
||||||
fromClauseIndex.register( sqmJoin, joinedTableGroup );
|
fromClauseIndex.register( sqmJoin, joinedTableGroup,elementPath );
|
||||||
}
|
}
|
||||||
|
|
||||||
// add any additional join restrictions
|
// add any additional join restrictions
|
||||||
|
@ -43,6 +43,9 @@ public void register(SqmPath<?> sqmPath, TableGroup tableGroup) {
|
|||||||
|
|
||||||
public void register(SqmPath<?> sqmPath, TableGroup tableGroup, NavigablePath identifierForTableGroup) {
|
public void register(SqmPath<?> sqmPath, TableGroup tableGroup, NavigablePath identifierForTableGroup) {
|
||||||
registerTableGroup( sqmPath.getNavigablePath(), tableGroup );
|
registerTableGroup( sqmPath.getNavigablePath(), tableGroup );
|
||||||
|
if ( identifierForTableGroup != null ) {
|
||||||
|
registerTableGroup( identifierForTableGroup, tableGroup );
|
||||||
|
}
|
||||||
|
|
||||||
if ( sqmPath.getExplicitAlias() != null ) {
|
if ( sqmPath.getExplicitAlias() != null ) {
|
||||||
final TableGroup previousAliasReg = tableGroupByAliasXref.put( sqmPath.getExplicitAlias(), tableGroup );
|
final TableGroup previousAliasReg = tableGroupByAliasXref.put( sqmPath.getExplicitAlias(), tableGroup );
|
||||||
@ -67,11 +70,13 @@ private void registerJoinFetch(SqmAttributeJoin sqmJoin, NavigablePath identifie
|
|||||||
if ( fetchesByPath == null ) {
|
if ( fetchesByPath == null ) {
|
||||||
fetchesByPath = new HashMap<>();
|
fetchesByPath = new HashMap<>();
|
||||||
}
|
}
|
||||||
NavigablePath navigablePath = sqmJoin.getNavigablePath();
|
|
||||||
fetchesByPath.put( navigablePath.getIdentifierForTableGroup(), sqmJoin );
|
|
||||||
if ( identifierForTableGroup != null ) {
|
if ( identifierForTableGroup != null ) {
|
||||||
fetchesByPath.put( identifierForTableGroup.getIdentifierForTableGroup(), sqmJoin );
|
fetchesByPath.put( identifierForTableGroup.getIdentifierForTableGroup(), sqmJoin );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
final NavigablePath navigablePath = sqmJoin.getNavigablePath();
|
||||||
|
fetchesByPath.put( navigablePath.getIdentifierForTableGroup(), sqmJoin );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isResolved(SqmFrom fromElement) {
|
public boolean isResolved(SqmFrom fromElement) {
|
||||||
|
@ -289,8 +289,11 @@ public List<Fetch> visitFetches(FetchParent fetchParent) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final boolean incrementFetchDepth = fetchable.incrementFetchDepth();
|
||||||
try {
|
try {
|
||||||
fetchDepth++;
|
if ( incrementFetchDepth ) {
|
||||||
|
fetchDepth++;
|
||||||
|
}
|
||||||
final Fetch fetch = buildFetch( fetchablePath, fetchParent, fetchable, isKeyFetchable );
|
final Fetch fetch = buildFetch( fetchablePath, fetchParent, fetchable, isKeyFetchable );
|
||||||
|
|
||||||
if ( fetch != null ) {
|
if ( fetch != null ) {
|
||||||
@ -308,7 +311,9 @@ public List<Fetch> visitFetches(FetchParent fetchParent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
fetchDepth--;
|
if ( incrementFetchDepth ) {
|
||||||
|
fetchDepth--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -398,12 +403,9 @@ else if ( getLoadQueryInfluencers().hasEnabledFetchProfiles() ) {
|
|||||||
// lastly, account for any app-defined max-fetch-depth
|
// lastly, account for any app-defined max-fetch-depth
|
||||||
final Integer maxDepth = getCreationContext().getMaximumFetchDepth();
|
final Integer maxDepth = getCreationContext().getMaximumFetchDepth();
|
||||||
if ( maxDepth != null ) {
|
if ( maxDepth != null ) {
|
||||||
if ( fetchDepth == maxDepth ) {
|
if ( fetchDepth >= maxDepth ) {
|
||||||
joined = false;
|
joined = false;
|
||||||
}
|
}
|
||||||
else if ( fetchDepth > maxDepth ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( joined && fetchable instanceof TableGroupJoinProducer ) {
|
if ( joined && fetchable instanceof TableGroupJoinProducer ) {
|
||||||
|
@ -39,4 +39,8 @@ Fetch generateFetch(
|
|||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
DomainResultCreationState creationState);
|
DomainResultCreationState creationState);
|
||||||
|
|
||||||
|
default boolean incrementFetchDepth(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
@ -37,17 +38,17 @@
|
|||||||
@SessionFactory(statementInspectorClass = SQLStatementInspector.class)
|
@SessionFactory(statementInspectorClass = SQLStatementInspector.class)
|
||||||
public class CompositeIdTest {
|
public class CompositeIdTest {
|
||||||
|
|
||||||
// @AfterEach
|
@AfterEach
|
||||||
// public void tearDown(SessionFactoryScope scope) {
|
public void tearDown(SessionFactoryScope scope) {
|
||||||
// scope.inTransaction(
|
scope.inTransaction(
|
||||||
// session -> {
|
session -> {
|
||||||
// session.createQuery( "delete from LineItem" ).executeUpdate();
|
session.createQuery( "delete from LineItem" ).executeUpdate();
|
||||||
// session.createQuery( "delete from Order" ).executeUpdate();
|
session.createQuery( "delete from Order" ).executeUpdate();
|
||||||
// session.createQuery( "delete from Customer" ).executeUpdate();
|
session.createQuery( "delete from Customer" ).executeUpdate();
|
||||||
// session.createQuery( "delete from Product" ).executeUpdate();
|
session.createQuery( "delete from Product" ).executeUpdate();
|
||||||
// }
|
}
|
||||||
// );
|
);
|
||||||
// }
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testQuery(SessionFactoryScope scope) {
|
public void testQuery(SessionFactoryScope scope) {
|
||||||
@ -185,62 +186,6 @@ public void testCompositeIds(SessionFactoryScope scope) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNonLazyFetch_2(SessionFactoryScope scope) {
|
|
||||||
scope.inTransaction(
|
|
||||||
session -> {
|
|
||||||
Product p = new Product();
|
|
||||||
p.setProductId( "A123" );
|
|
||||||
p.setDescription( "nipple ring" );
|
|
||||||
p.setPrice( new BigDecimal( 1.0 ) );
|
|
||||||
p.setNumberAvailable( 1004 );
|
|
||||||
session.persist( p );
|
|
||||||
|
|
||||||
Product p2 = new Product();
|
|
||||||
p2.setProductId( "X525" );
|
|
||||||
p2.setDescription( "nose stud" );
|
|
||||||
p2.setPrice( new BigDecimal( 3.0 ) );
|
|
||||||
p2.setNumberAvailable( 105 );
|
|
||||||
session.persist( p2 );
|
|
||||||
|
|
||||||
Customer c = new Customer();
|
|
||||||
c.setAddress( "St Kilda Rd, MEL, 3000" );
|
|
||||||
c.setName( "Virginia" );
|
|
||||||
c.setCustomerId( "C111" );
|
|
||||||
session.persist( c );
|
|
||||||
|
|
||||||
Order o = new Order( c );
|
|
||||||
o.setOrderDate( Calendar.getInstance() );
|
|
||||||
LineItem li = new LineItem( o, p );
|
|
||||||
li.setQuantity( 2 );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
scope.inTransaction(
|
|
||||||
session -> {
|
|
||||||
Order o = (Order) session.createQuery(
|
|
||||||
"from Order o left join fetch o.lineItems li left join fetch li.product p" )
|
|
||||||
.uniqueResult();
|
|
||||||
assertTrue( Hibernate.isInitialized( o.getLineItems() ) );
|
|
||||||
LineItem li = (LineItem) o.getLineItems().iterator().next();
|
|
||||||
assertTrue( Hibernate.isInitialized( li ) );
|
|
||||||
assertTrue( Hibernate.isInitialized( li.getProduct() ) );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// scope.inTransaction(
|
|
||||||
// session -> {
|
|
||||||
// Order o = (Order) session.createQuery( "from Order o" ).uniqueResult();
|
|
||||||
// assertTrue( Hibernate.isInitialized( o.getLineItems() ) );
|
|
||||||
// LineItem li = (LineItem) o.getLineItems().iterator().next();
|
|
||||||
// assertTrue( Hibernate.isInitialized( li ) );
|
|
||||||
// assertFalse( Hibernate.isInitialized( li.getProduct() ) );
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNonLazyFetch(SessionFactoryScope scope) {
|
public void testNonLazyFetch(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
@ -350,10 +295,15 @@ public void testMultipleCollectionFetch(SessionFactoryScope scope) {
|
|||||||
.uniqueResult();
|
.uniqueResult();
|
||||||
assertTrue( Hibernate.isInitialized( c.getOrders() ) );
|
assertTrue( Hibernate.isInitialized( c.getOrders() ) );
|
||||||
assertEquals( c.getOrders().size(), 2 );
|
assertEquals( c.getOrders().size(), 2 );
|
||||||
assertTrue( Hibernate.isInitialized( ( (Order) c.getOrders().get( 0 ) ).getLineItems() ) );
|
|
||||||
assertTrue( Hibernate.isInitialized( ( (Order) c.getOrders().get( 1 ) ).getLineItems() ) );
|
Order o1 = (Order) c.getOrders().get( 0 );
|
||||||
assertEquals( 2, ( (Order) c.getOrders().get( 0 ) ).getLineItems().size() );
|
assertTrue( Hibernate.isInitialized( o1.getLineItems() ) );
|
||||||
assertEquals( 2, ( (Order) c.getOrders().get( 1 ) ).getLineItems().size() );
|
|
||||||
|
Order o2 = (Order) c.getOrders().get( 1 );
|
||||||
|
assertTrue( Hibernate.isInitialized( o2.getLineItems() ) );
|
||||||
|
|
||||||
|
assertEquals( 2, o1.getLineItems().size() );
|
||||||
|
assertEquals( 2, o2.getLineItems().size() );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user