Fix issue with TableReference resolution

This commit is contained in:
Andrea Boriero 2020-01-14 13:23:27 +00:00
parent cb5fe2645a
commit 8c806a5a16
8 changed files with 187 additions and 20 deletions

View File

@ -10,14 +10,14 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.SortedMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Consumer;
import java.util.function.Function;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.ArrayHelper;
@ -83,7 +83,8 @@ public class EmbeddableMappingType implements ManagedMappingType {
private final SessionFactoryImplementor sessionFactory;
private final SortedMap<String,AttributeMapping> attributeMappings = new TreeMap<>();
// private final Map<String,AttributeMapping> attributeMappings = new TreeMap<>();
private final Map<String,AttributeMapping> attributeMappings = new LinkedHashMap<>();
private final EmbeddableValuedModelPart valueMapping;

View File

@ -112,7 +112,7 @@ public class EntityCollectionPart implements CollectionPart, EntityAssociationMa
LockMode lockMode,
String resultVariable,
DomainResultCreationState creationState) {
assert fetchParent.getReferencedMappingContainer() instanceof PluralAttributeMapping;
// assert fetchParent.getReferencedMappingContainer() instanceof PluralAttributeMapping;
// find or create the TableGroup associated with this `fetchablePath`
creationState.getSqlAstCreationState().getFromClauseAccess().resolveTableGroup(

View File

@ -40,6 +40,7 @@ import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.exec.spi.JdbcParameterBinding;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.type.BasicType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
@ -317,6 +318,10 @@ public class SqmUtil {
final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
// assume we have (or can create) a mapping for the parameter's Java type
return typeConfiguration.standardBasicTypeForJavaType( parameter.getParameterType() );
BasicType basicType = typeConfiguration.standardBasicTypeForJavaType( parameter.getParameterType() );
if ( basicType == null ) {
return StandardBasicTypes.SERIALIZABLE;
}
return basicType;
}
}

View File

@ -48,17 +48,7 @@ public abstract class AbstractColumnReferenceQualifier implements ColumnReferenc
@Override
public TableReference getTableReference(String tableExpression) {
if ( getPrimaryTableReference().getTableExpression().equals( tableExpression ) ) {
return getPrimaryTableReference();
}
for ( TableReferenceJoin tableJoin : getTableReferenceJoins() ) {
if ( tableJoin.getJoinedTableReference().getTableExpression().equals( tableExpression ) ) {
return tableJoin.getJoinedTableReference();
}
}
return null;
return resolveTableReferenceInternal( tableExpression );
}
protected TableReference resolveTableReferenceInternal(String tableExpression) {

View File

@ -134,7 +134,17 @@ public class CompositeTableGroup implements VirtualTableGroup {
@Override
public TableReference resolveTableReference(String tableExpression) {
return underlyingTableGroup.resolveTableReference( tableExpression );
TableReference tableReference = underlyingTableGroup.getTableReference( tableExpression );
if ( tableReference != null ) {
return tableReference;
}
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference();
if ( primaryTableReference.getTableExpression().equals( tableExpression ) ) {
return primaryTableReference;
}
}
throw new IllegalStateException( "Could not resolve binding for table `" + tableExpression + "`" );
}
}

View File

@ -104,7 +104,7 @@ public class UnionTableGroup implements VirtualTableGroup {
@Override
public TableReference getTableReference(String tableExpression) {
assert tableReference.getTableExpression().equals( tableExpression );
// assert tableReference.getTableExpression().equals( tableExpression );
return tableReference;
}

View File

@ -142,7 +142,7 @@ public class EmbeddedTest {
@Test
@TestForIssue(jiraKey = "HHH-8172")
@FailureExpected(jiraKey = "HHH-8172")
// @FailureExpected(jiraKey = "HHH-8172")
public void testQueryWithEmbeddedParameterAllNull(SessionFactoryScope scope) {
Person person = new Person();
Address a = new Address();
@ -584,7 +584,7 @@ public class EmbeddedTest {
Manager manager = topManagement.iterator().next();
assertEquals( "Wrong element", "Bill", manager.getName() );
session.delete( manager );
session.delete( provider );
session.delete( internetProvider );
}
);
}

View File

@ -0,0 +1,161 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.annotations.embedded;
import org.hibernate.Hibernate;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* @author Andrea Boriero
*/
@DomainModel(
annotatedClasses = {
InternetProvider.class,
CorpType.class,
Nationality.class,
Manager.class
}
)
@SessionFactory
@ServiceRegistry(settings = {
@ServiceRegistry.Setting(name = AvailableSettings.IMPLICIT_NAMING_STRATEGY, value = "jpa")
})
public class EmbeddedTest2 {
@Test
@TestForIssue(jiraKey = "HHH-9642")
public void testEmbeddedAndOneToManyHql(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
InternetProvider provider = new InternetProvider();
provider.setBrandName( "Fido" );
LegalStructure structure = new LegalStructure();
structure.setCountry( "Canada" );
structure.setName( "Rogers" );
provider.setOwner( structure );
session.persist( provider );
Manager manager = new Manager();
manager.setName( "Bill" );
manager.setEmployer( provider );
structure.getTopManagement().add( manager );
session.persist( manager );
}
);
scope.inTransaction(
session -> {
InternetProvider internetProviderQueried =
(InternetProvider) session.createQuery( "from InternetProvider" ).uniqueResult();
assertFalse( Hibernate.isInitialized( internetProviderQueried.getOwner().getTopManagement() ) );
}
);
scope.inTransaction(
session -> {
InternetProvider internetProviderQueried =
(InternetProvider) session.createQuery(
"from InternetProvider i join fetch i.owner.topManagement" )
.uniqueResult();
assertTrue( Hibernate.isInitialized( internetProviderQueried.getOwner().getTopManagement() ) );
}
);
InternetProvider provider = scope.fromTransaction(
session -> {
InternetProvider internetProviderQueried =
(InternetProvider) session.createQuery(
"from InternetProvider i join fetch i.owner o join fetch o.topManagement" )
.uniqueResult();
assertTrue( Hibernate.isInitialized( internetProviderQueried.getOwner().getTopManagement() ) );
return internetProviderQueried;
}
);
scope.inTransaction(
session -> {
InternetProvider internetProvider = session.get( InternetProvider.class, provider.getId() );
Manager manager = internetProvider.getOwner().getTopManagement().iterator().next();
session.delete( manager );
session.delete( internetProvider );
}
);
}
@Test
@TestForIssue(jiraKey = "HHH-9642")
public void testEmbeddedAndOneToManyHqlFetch(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
InternetProvider provider = new InternetProvider();
provider.setBrandName( "Fido" );
LegalStructure structure = new LegalStructure();
structure.setCountry( "Canada" );
structure.setName( "Rogers" );
provider.setOwner( structure );
session.persist( provider );
Manager manager = new Manager();
manager.setName( "Bill" );
manager.setEmployer( provider );
structure.getTopManagement().add( manager );
session.persist( manager );
}
);
// scope.inTransaction(
// session -> {
// InternetProvider internetProviderQueried =
// (InternetProvider) session.createQuery( "from InternetProvider" ).uniqueResult();
// assertFalse( Hibernate.isInitialized( internetProviderQueried.getOwner().getTopManagement() ) );
//
// }
// );
scope.inTransaction(
session -> {
InternetProvider internetProviderQueried =
(InternetProvider) session.createQuery(
"from InternetProvider i join fetch i.owner.topManagement" )
.uniqueResult();
assertTrue( Hibernate.isInitialized( internetProviderQueried.getOwner().getTopManagement() ) );
}
);
InternetProvider provider = scope.fromTransaction(
session -> {
InternetProvider internetProviderQueried =
(InternetProvider) session.createQuery(
"from InternetProvider i join fetch i.owner o join fetch o.topManagement" )
.uniqueResult();
LegalStructure owner = internetProviderQueried.getOwner();
assertTrue( Hibernate.isInitialized( owner ));
assertTrue( Hibernate.isInitialized( owner.getTopManagement() ) );
return internetProviderQueried;
}
);
scope.inTransaction(
session -> {
InternetProvider internetProvider = session.get( InternetProvider.class, provider.getId() );
Manager manager = internetProvider.getOwner().getTopManagement().iterator().next();
session.delete( manager );
session.delete( internetProvider );
}
);
}
}