Fix PluralAttributMappingImpl issue when both index and element of a Map are Entity types
This commit is contained in:
parent
82de2b0a3f
commit
92aa612f4e
|
@ -29,7 +29,6 @@ import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||||
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
|
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
|
||||||
import org.hibernate.metamodel.mapping.CollectionMappingType;
|
import org.hibernate.metamodel.mapping.CollectionMappingType;
|
||||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||||
import org.hibernate.metamodel.mapping.ColumnConsumer;
|
|
||||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||||
|
@ -42,9 +41,7 @@ import org.hibernate.metamodel.mapping.ordering.OrderByFragment;
|
||||||
import org.hibernate.metamodel.mapping.ordering.OrderByFragmentTranslator;
|
import org.hibernate.metamodel.mapping.ordering.OrderByFragmentTranslator;
|
||||||
import org.hibernate.metamodel.mapping.ordering.TranslationContext;
|
import org.hibernate.metamodel.mapping.ordering.TranslationContext;
|
||||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||||
import org.hibernate.persister.collection.AbstractCollectionPersister;
|
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.entity.AbstractEntityPersister;
|
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.entity.Joinable;
|
import org.hibernate.persister.entity.Joinable;
|
||||||
import org.hibernate.property.access.spi.PropertyAccess;
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
|
@ -112,7 +109,8 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping
|
||||||
private final IndexMetadata indexMetadata;
|
private final IndexMetadata indexMetadata;
|
||||||
|
|
||||||
private ForeignKeyDescriptor fkDescriptor;
|
private ForeignKeyDescriptor fkDescriptor;
|
||||||
private ForeignKeyDescriptor manyToManyFkDescriptor;
|
private ForeignKeyDescriptor elementFkDescriptor;
|
||||||
|
private ForeignKeyDescriptor indexFkDescriptor;
|
||||||
|
|
||||||
private OrderByFragment orderByFragment;
|
private OrderByFragment orderByFragment;
|
||||||
private OrderByFragment manyToManyOrderByFragment;
|
private OrderByFragment manyToManyOrderByFragment;
|
||||||
|
@ -243,68 +241,34 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping
|
||||||
Property bootProperty,
|
Property bootProperty,
|
||||||
Collection bootDescriptor,
|
Collection bootDescriptor,
|
||||||
MappingModelCreationProcess creationProcess) {
|
MappingModelCreationProcess creationProcess) {
|
||||||
if ( collectionDescriptor.getElementType() instanceof EntityType
|
final Dialect dialect = creationProcess.getCreationContext()
|
||||||
|| collectionDescriptor.getIndexType() instanceof EntityType ) {
|
.getSessionFactory()
|
||||||
|
.getJdbcServices()
|
||||||
|
.getDialect();
|
||||||
|
if ( collectionDescriptor.getElementType() instanceof EntityType ) {
|
||||||
creationProcess.registerForeignKeyPostInitCallbacks(
|
creationProcess.registerForeignKeyPostInitCallbacks(
|
||||||
() -> {
|
() -> {
|
||||||
final EntityPersister associatedEntityDescriptor;
|
|
||||||
final ModelPart fkTargetPart;
|
|
||||||
final Value fkBootDescriptorSource;
|
|
||||||
if ( collectionDescriptor.getElementType() instanceof EntityType ) {
|
|
||||||
final EntityType elementEntityType = (EntityType) collectionDescriptor.getElementType();
|
|
||||||
associatedEntityDescriptor = creationProcess.getEntityPersister( elementEntityType.getAssociatedEntityName() );
|
|
||||||
if ( ( (AbstractEntityPersister) associatedEntityDescriptor ).getTableName()
|
|
||||||
.equals( ( (AbstractCollectionPersister) collectionDescriptor ).getTableName() ) ) {
|
|
||||||
fkTargetPart = creationProcess
|
|
||||||
.getEntityPersister( bootDescriptor.getOwner().getEntityName() )
|
|
||||||
.getIdentifierMapping();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fkTargetPart = associatedEntityDescriptor.getIdentifierMapping();
|
|
||||||
}
|
|
||||||
fkBootDescriptorSource = bootDescriptor.getElement();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert collectionDescriptor.getIndexType() != null;
|
|
||||||
assert bootDescriptor instanceof IndexedCollection;
|
|
||||||
|
|
||||||
final EntityType indexEntityType = (EntityType) collectionDescriptor.getIndexType();
|
elementFkDescriptor = createForeignKeyDescriptor(
|
||||||
associatedEntityDescriptor = creationProcess.getEntityPersister( indexEntityType.getAssociatedEntityName() );
|
bootDescriptor.getElement(),
|
||||||
fkTargetPart = indexEntityType.isReferenceToPrimaryKey()
|
(EntityType) collectionDescriptor.getElementType(),
|
||||||
? associatedEntityDescriptor.getIdentifierMapping()
|
creationProcess,
|
||||||
: associatedEntityDescriptor.findSubPart( indexEntityType.getRHSUniqueKeyPropertyName() );
|
dialect
|
||||||
fkBootDescriptorSource = ( (IndexedCollection) bootDescriptor ).getIndex();
|
);
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ( collectionDescriptor.getIndexType() instanceof EntityType ) {
|
||||||
|
creationProcess.registerForeignKeyPostInitCallbacks(
|
||||||
|
() -> {
|
||||||
|
indexFkDescriptor = createForeignKeyDescriptor(
|
||||||
|
( (IndexedCollection) bootDescriptor ).getIndex(),
|
||||||
|
(EntityType) collectionDescriptor.getIndexType(),
|
||||||
|
creationProcess,
|
||||||
|
dialect
|
||||||
|
);
|
||||||
|
|
||||||
final Dialect dialect = creationProcess.getCreationContext()
|
|
||||||
.getSessionFactory()
|
|
||||||
.getJdbcServices()
|
|
||||||
.getDialect();
|
|
||||||
if ( fkTargetPart instanceof BasicValuedModelPart ) {
|
|
||||||
final BasicValuedModelPart basicFkTargetPart = (BasicValuedModelPart) fkTargetPart;
|
|
||||||
final Joinable collectionDescriptorAsJoinable = (Joinable) collectionDescriptor;
|
|
||||||
manyToManyFkDescriptor = new SimpleForeignKeyDescriptor(
|
|
||||||
collectionDescriptorAsJoinable.getTableName(),
|
|
||||||
fkBootDescriptorSource.getColumnIterator().next().getText( dialect ),
|
|
||||||
basicFkTargetPart.getContainingTableExpression(),
|
|
||||||
basicFkTargetPart.getMappedColumnExpression(),
|
|
||||||
basicFkTargetPart.getJdbcMapping()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if ( fkTargetPart instanceof EmbeddableValuedModelPart ) {
|
|
||||||
manyToManyFkDescriptor = MappingModelCreationHelper.buildEmbeddedForeignKeyDescriptor(
|
|
||||||
(EmbeddableValuedModelPart) fkTargetPart,
|
|
||||||
this,
|
|
||||||
fkBootDescriptorSource,
|
|
||||||
dialect,
|
|
||||||
creationProcess
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new NotYetImplementedFor6Exception(
|
|
||||||
"Support for composite foreign keys not yet implemented : " + collectionDescriptor.getRole()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -348,6 +312,44 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ForeignKeyDescriptor createForeignKeyDescriptor(
|
||||||
|
Value fkBootDescriptorSource,
|
||||||
|
EntityType entityType,
|
||||||
|
MappingModelCreationProcess creationProcess,
|
||||||
|
Dialect dialect) {
|
||||||
|
final EntityPersister associatedEntityDescriptor = creationProcess.getEntityPersister( entityType.getAssociatedEntityName() );
|
||||||
|
final ModelPart fkTargetPart = entityType.isReferenceToPrimaryKey()
|
||||||
|
? associatedEntityDescriptor.getIdentifierMapping()
|
||||||
|
: associatedEntityDescriptor.findSubPart( entityType.getRHSUniqueKeyPropertyName() );
|
||||||
|
|
||||||
|
if ( fkTargetPart instanceof BasicValuedModelPart ) {
|
||||||
|
final BasicValuedModelPart basicFkTargetPart = (BasicValuedModelPart) fkTargetPart;
|
||||||
|
final Joinable collectionDescriptorAsJoinable = (Joinable) collectionDescriptor;
|
||||||
|
return new SimpleForeignKeyDescriptor(
|
||||||
|
collectionDescriptorAsJoinable.getTableName(),
|
||||||
|
fkBootDescriptorSource.getColumnIterator().next().getText( dialect ),
|
||||||
|
basicFkTargetPart.getContainingTableExpression(),
|
||||||
|
basicFkTargetPart.getMappedColumnExpression(),
|
||||||
|
basicFkTargetPart.getJdbcMapping()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if ( fkTargetPart instanceof EmbeddableValuedModelPart ) {
|
||||||
|
return MappingModelCreationHelper.buildEmbeddedForeignKeyDescriptor(
|
||||||
|
(EmbeddableValuedModelPart) fkTargetPart,
|
||||||
|
this,
|
||||||
|
fkBootDescriptorSource,
|
||||||
|
dialect,
|
||||||
|
creationProcess
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new NotYetImplementedFor6Exception(
|
||||||
|
"Support for composite foreign keys not yet implemented : " + collectionDescriptor
|
||||||
|
.getRole()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NavigableRole getNavigableRole() {
|
public NavigableRole getNavigableRole() {
|
||||||
return getCollectionDescriptor().getNavigableRole();
|
return getCollectionDescriptor().getNavigableRole();
|
||||||
|
@ -698,68 +700,121 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping
|
||||||
creationContext.getSessionFactory()
|
creationContext.getSessionFactory()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final EntityMappingType elementDescriptorEntityMappingType;
|
||||||
|
if ( elementDescriptor instanceof EntityCollectionPart ) {
|
||||||
|
elementDescriptorEntityMappingType = ( (EntityCollectionPart) elementDescriptor ).getEntityMappingType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
elementDescriptorEntityMappingType = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final EntityMappingType indexDescriptorEntityMappingType;
|
||||||
|
if ( indexDescriptor instanceof EntityCollectionPart ) {
|
||||||
|
indexDescriptorEntityMappingType = ( (EntityCollectionPart) indexDescriptor ).getEntityMappingType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
indexDescriptorEntityMappingType = null;
|
||||||
|
}
|
||||||
|
|
||||||
final BiFunction<String, TableGroup, TableReferenceJoin> tableReferenceJoinCreator;
|
final BiFunction<String, TableGroup, TableReferenceJoin> tableReferenceJoinCreator;
|
||||||
final java.util.function.Predicate<String> tableReferenceJoinNameChecker;
|
|
||||||
if ( elementDescriptor instanceof EntityCollectionPart || indexDescriptor instanceof EntityCollectionPart ) {
|
|
||||||
final EntityCollectionPart entityPartDescriptor;
|
|
||||||
if ( elementDescriptor instanceof EntityCollectionPart ) {
|
|
||||||
entityPartDescriptor = (EntityCollectionPart) elementDescriptor;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
entityPartDescriptor = (EntityCollectionPart) indexDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
final EntityMappingType mappingType = entityPartDescriptor.getEntityMappingType();
|
final java.util.function.Predicate<String> tableReferenceJoinNameChecker = createTableReferenceJoinNameChecker(
|
||||||
final TableReference associatedPrimaryTable = mappingType.createPrimaryTableReference(
|
elementDescriptorEntityMappingType,
|
||||||
|
indexDescriptorEntityMappingType
|
||||||
|
);
|
||||||
|
|
||||||
|
final TableReference elementAssociatedPrimaryTable;
|
||||||
|
final Function<TableGroup, TableReferenceJoin> elementTableGroupFinalizer;
|
||||||
|
// todo (6.0) : not sure it is
|
||||||
|
final boolean elementUseInnerJoin;
|
||||||
|
if ( elementDescriptorEntityMappingType != null ) {
|
||||||
|
elementUseInnerJoin = canUseInnerJoin && !getAttributeMetadataAccess()
|
||||||
|
.resolveAttributeMetadata( elementDescriptorEntityMappingType ).isNullable();
|
||||||
|
final SqlAstJoinType joinType = elementUseInnerJoin
|
||||||
|
? SqlAstJoinType.INNER
|
||||||
|
: SqlAstJoinType.LEFT;
|
||||||
|
elementAssociatedPrimaryTable = elementDescriptorEntityMappingType.createPrimaryTableReference(
|
||||||
sqlAliasBase,
|
sqlAliasBase,
|
||||||
sqlExpressionResolver,
|
sqlExpressionResolver,
|
||||||
creationContext
|
creationContext
|
||||||
);
|
);
|
||||||
|
|
||||||
final boolean useInnerJoin = canUseInnerJoin && !getAttributeMetadataAccess()
|
elementTableGroupFinalizer = createTableGroupFinalizer(
|
||||||
.resolveAttributeMetadata( null ).isNullable();
|
sqlExpressionResolver,
|
||||||
|
creationContext,
|
||||||
|
collectionTableReference,
|
||||||
|
elementAssociatedPrimaryTable,
|
||||||
|
joinType,
|
||||||
|
elementFkDescriptor
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
elementAssociatedPrimaryTable = null;
|
||||||
|
elementTableGroupFinalizer = null;
|
||||||
|
elementUseInnerJoin = false;
|
||||||
|
}
|
||||||
|
|
||||||
final Function<TableGroup,TableReferenceJoin> tableGroupFinalizer = tableGroup -> {
|
TableReference indexAssociatedPrimaryTable;
|
||||||
final SqlAstJoinType joinType = useInnerJoin
|
final Function<TableGroup, TableReferenceJoin> indexTableGroupFinalizer;
|
||||||
? SqlAstJoinType.INNER
|
final boolean indexUseInnerJoin;
|
||||||
: SqlAstJoinType.LEFT;
|
if ( indexDescriptorEntityMappingType != null ) {
|
||||||
final TableReferenceJoin associationJoin = new TableReferenceJoin(
|
indexUseInnerJoin = canUseInnerJoin && !getAttributeMetadataAccess()
|
||||||
joinType,
|
.resolveAttributeMetadata( indexDescriptorEntityMappingType ).isNullable();
|
||||||
associatedPrimaryTable,
|
final SqlAstJoinType joinType = indexUseInnerJoin
|
||||||
manyToManyFkDescriptor.generateJoinPredicate(
|
? SqlAstJoinType.INNER
|
||||||
collectionTableReference,
|
: SqlAstJoinType.LEFT;
|
||||||
associatedPrimaryTable,
|
indexAssociatedPrimaryTable = indexDescriptorEntityMappingType.createPrimaryTableReference(
|
||||||
joinType,
|
sqlAliasBase,
|
||||||
sqlExpressionResolver,
|
sqlExpressionResolver,
|
||||||
creationContext
|
creationContext
|
||||||
)
|
);
|
||||||
);
|
|
||||||
return associationJoin;
|
|
||||||
};
|
|
||||||
|
|
||||||
tableReferenceJoinNameChecker = mappingType::containsTableReference;
|
indexTableGroupFinalizer = createTableGroupFinalizer(
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext,
|
||||||
|
collectionTableReference,
|
||||||
|
indexAssociatedPrimaryTable,
|
||||||
|
joinType,
|
||||||
|
indexFkDescriptor
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
indexAssociatedPrimaryTable = null;
|
||||||
|
indexTableGroupFinalizer = null;
|
||||||
|
indexUseInnerJoin = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( elementDescriptorEntityMappingType != null || indexDescriptorEntityMappingType != null ) {
|
||||||
tableReferenceJoinCreator = (tableExpression, tableGroup) -> {
|
tableReferenceJoinCreator = (tableExpression, tableGroup) -> {
|
||||||
if ( associatedPrimaryTable.getTableExpression().equals( tableExpression ) ) {
|
if ( elementDescriptorEntityMappingType != null
|
||||||
TableReferenceJoin tableReferenceJoin = tableGroupFinalizer.apply( tableGroup );
|
&& elementDescriptorEntityMappingType.containsTableReference( tableExpression ) ) {
|
||||||
return tableReferenceJoin;
|
return createTableReferenceJoin(
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext,
|
||||||
|
sqlAliasBase,
|
||||||
|
elementDescriptorEntityMappingType,
|
||||||
|
elementAssociatedPrimaryTable,
|
||||||
|
elementTableGroupFinalizer,
|
||||||
|
elementUseInnerJoin,
|
||||||
|
tableExpression,
|
||||||
|
tableGroup
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else {
|
else if ( indexDescriptorEntityMappingType != null
|
||||||
StandardTableGroup standardTableGroup = (StandardTableGroup) tableGroup;
|
&& indexDescriptorEntityMappingType.containsTableReference( tableExpression ) ) {
|
||||||
if ( standardTableGroup.getTableReferenceJoins().isEmpty() ) {
|
return createTableReferenceJoin(
|
||||||
TableReferenceJoin tableReferenceJoin = tableGroupFinalizer.apply( tableGroup );
|
sqlExpressionResolver,
|
||||||
standardTableGroup.addTableReferenceJoin( tableReferenceJoin );
|
creationContext,
|
||||||
}
|
sqlAliasBase,
|
||||||
|
indexDescriptorEntityMappingType,
|
||||||
|
indexAssociatedPrimaryTable,
|
||||||
|
indexTableGroupFinalizer,
|
||||||
|
indexUseInnerJoin,
|
||||||
|
tableExpression,
|
||||||
|
tableGroup
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return mappingType.createTableReferenceJoin(
|
throw new IllegalStateException( "could not create join for table `" + tableExpression + "`" );
|
||||||
tableExpression,
|
|
||||||
sqlAliasBase,
|
|
||||||
associatedPrimaryTable,
|
|
||||||
useInnerJoin,
|
|
||||||
sqlExpressionResolver,
|
|
||||||
creationContext
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -768,7 +823,6 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping
|
||||||
"element-collection cannot contain joins : " + collectionTableReference.getTableExpression() + " -> " + tableExpression
|
"element-collection cannot contain joins : " + collectionTableReference.getTableExpression() + " -> " + tableExpression
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
tableReferenceJoinNameChecker = s -> false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final StandardTableGroup tableGroup = new StandardTableGroup(
|
final StandardTableGroup tableGroup = new StandardTableGroup(
|
||||||
|
@ -785,6 +839,75 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping
|
||||||
return tableGroup;
|
return tableGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TableReferenceJoin createTableReferenceJoin(
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext,
|
||||||
|
SqlAliasBase sqlAliasBase,
|
||||||
|
EntityMappingType elementDescriptorEntityMappingType,
|
||||||
|
TableReference elementAssociatedPrimaryTable,
|
||||||
|
Function<TableGroup, TableReferenceJoin> elementTableGroupFinalizer,
|
||||||
|
boolean useInnerJoin,
|
||||||
|
String tableExpression, TableGroup tableGroup) {
|
||||||
|
if ( elementAssociatedPrimaryTable.getTableExpression().equals( tableExpression ) ) {
|
||||||
|
TableReferenceJoin tableReferenceJoin = elementTableGroupFinalizer.apply( tableGroup );
|
||||||
|
return tableReferenceJoin;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
StandardTableGroup standardTableGroup = (StandardTableGroup) tableGroup;
|
||||||
|
if ( standardTableGroup.getTableReferenceJoins().isEmpty() ) {
|
||||||
|
TableReferenceJoin tableReferenceJoin = elementTableGroupFinalizer.apply( tableGroup );
|
||||||
|
standardTableGroup.addTableReferenceJoin( tableReferenceJoin );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return elementDescriptorEntityMappingType.createTableReferenceJoin(
|
||||||
|
tableExpression,
|
||||||
|
sqlAliasBase,
|
||||||
|
elementAssociatedPrimaryTable,
|
||||||
|
useInnerJoin,
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Function<TableGroup, TableReferenceJoin> createTableGroupFinalizer(
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext,
|
||||||
|
TableReference collectionTableReference,
|
||||||
|
TableReference elementAssociatedPrimaryTable,
|
||||||
|
SqlAstJoinType joinType,
|
||||||
|
ForeignKeyDescriptor elementFkDescriptor) {
|
||||||
|
return tableGroup -> {
|
||||||
|
|
||||||
|
final TableReferenceJoin associationJoin = new TableReferenceJoin(
|
||||||
|
joinType,
|
||||||
|
elementAssociatedPrimaryTable,
|
||||||
|
elementFkDescriptor.generateJoinPredicate(
|
||||||
|
collectionTableReference,
|
||||||
|
elementAssociatedPrimaryTable,
|
||||||
|
joinType,
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return associationJoin;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private java.util.function.Predicate<String> createTableReferenceJoinNameChecker(
|
||||||
|
EntityMappingType elementDescriptorEntityMappingType,
|
||||||
|
EntityMappingType indexDescriptorEntityMappingType) {
|
||||||
|
return tableExpression -> {
|
||||||
|
if ( elementDescriptorEntityMappingType != null
|
||||||
|
&& elementDescriptorEntityMappingType.containsTableReference( tableExpression ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( indexDescriptorEntityMappingType != null
|
||||||
|
&& indexDescriptorEntityMappingType.containsTableReference( tableExpression ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableGroup createRootTableGroup(
|
public TableGroup createRootTableGroup(
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* 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.collection.map.hhh7557;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Elizabeth Chatman
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel(
|
||||||
|
annotatedClasses = {
|
||||||
|
MapValue.class, MapKey.class, MapHolder.class
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@SessionFactory
|
||||||
|
public class EntityMapTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInsertIntoMap(SessionFactoryScope scope) {
|
||||||
|
// Session 1: Insert 3 values into the map
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
MapHolder mapHolder = new MapHolder();
|
||||||
|
mapHolder.setMap( new HashMap<>() );
|
||||||
|
addMapEntry( session, mapHolder, "A", "1" );
|
||||||
|
addMapEntry( session, mapHolder, "B", "2" );
|
||||||
|
addMapEntry( session, mapHolder, "C", "3" );
|
||||||
|
session.save( mapHolder );
|
||||||
|
// Verify there are 3 entries in the map
|
||||||
|
assertEquals( 3, mapHolder.getMap().size() );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Session 2: Add a 4th value to the map
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
MapHolder mapHolder = getMapHolder( session );
|
||||||
|
assertEquals( 3, mapHolder.getMap().size() );
|
||||||
|
System.out.println( "Got MapHolder; checked map size -----" );
|
||||||
|
addMapEntry( session, mapHolder, "D", "4" );
|
||||||
|
// Verify there are 4 entries in the map
|
||||||
|
assertEquals( 4, mapHolder.getMap().size() );
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Session 3: Count the entries in the map
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
MapHolder mapHolder = getMapHolder( session );
|
||||||
|
// Fails here (expected:<4> but was:<1>)
|
||||||
|
assertEquals( 4, mapHolder.getMap().size() );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMapEntry(Session session, MapHolder mapHolder, String key, String value) {
|
||||||
|
MapValue entityValue = new MapValue( value );
|
||||||
|
session.save( entityValue );
|
||||||
|
MapKey entityKey = new MapKey( key, entityValue );
|
||||||
|
session.save( entityKey );
|
||||||
|
mapHolder.getMap().put( entityKey, entityValue );
|
||||||
|
}
|
||||||
|
|
||||||
|
private MapHolder getMapHolder(Session session) {
|
||||||
|
List mapHolders = session.createQuery( "select distinct mh from MapHolder mh" ).list();
|
||||||
|
assertEquals( 1, mapHolders.size() );
|
||||||
|
return (MapHolder) mapHolders.get( 0 );
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.collection.map.hhh7557;
|
package org.hibernate.orm.test.collection.map.hhh7557;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
|
@ -4,7 +4,7 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.collection.map.hhh7557;
|
package org.hibernate.orm.test.collection.map.hhh7557;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
|
@ -4,7 +4,7 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.collection.map.hhh7557;
|
package org.hibernate.orm.test.collection.map.hhh7557;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
|
@ -1,88 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.test.collection.map.hhh7557;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.hibernate.Session;
|
|
||||||
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Elizabeth Chatman
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class EntityMapTest extends BaseCoreFunctionalTestCase {
|
|
||||||
@Override
|
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
|
||||||
return new Class[] {MapValue.class, MapKey.class, MapHolder.class};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testInsertIntoMap() throws Exception {
|
|
||||||
{
|
|
||||||
// Session 1: Insert 3 values into the map
|
|
||||||
Session session = openSession();
|
|
||||||
session.beginTransaction();
|
|
||||||
MapHolder mapHolder = new MapHolder();
|
|
||||||
mapHolder.setMap( new HashMap<MapKey, MapValue>() );
|
|
||||||
addMapEntry( session, mapHolder, "A", "1" );
|
|
||||||
addMapEntry( session, mapHolder, "B", "2" );
|
|
||||||
addMapEntry( session, mapHolder, "C", "3" );
|
|
||||||
session.save( mapHolder );
|
|
||||||
// Verify there are 3 entries in the map
|
|
||||||
Assert.assertEquals( 3, mapHolder.getMap().size() );
|
|
||||||
session.getTransaction().commit();
|
|
||||||
session.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// Session 2: Add a 4th value to the map
|
|
||||||
Session session = openSession();
|
|
||||||
session.beginTransaction();
|
|
||||||
MapHolder mapHolder = getMapHolder( session );
|
|
||||||
System.out.println( "Got MapHolder; checking map size -----" );
|
|
||||||
Assert.assertEquals( 3, mapHolder.getMap().size() );
|
|
||||||
System.out.println( "Got MapHolder; checked map size -----" );
|
|
||||||
addMapEntry( session, mapHolder, "D", "4" );
|
|
||||||
// Verify there are 4 entries in the map
|
|
||||||
Assert.assertEquals( 4, mapHolder.getMap().size() );
|
|
||||||
session.getTransaction().commit();
|
|
||||||
session.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// Session 3: Count the entries in the map
|
|
||||||
Session session = openSession();
|
|
||||||
session.beginTransaction();
|
|
||||||
MapHolder mapHolder = getMapHolder( session );
|
|
||||||
// Fails here (expected:<4> but was:<1>)
|
|
||||||
Assert.assertEquals( 4, mapHolder.getMap().size() );
|
|
||||||
session.getTransaction().commit();
|
|
||||||
session.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addMapEntry(Session session, MapHolder mapHolder, String key, String value) {
|
|
||||||
System.out.println( "Inserting (" + key + "," + value + ") into map" );
|
|
||||||
MapValue entityValue = new MapValue( value );
|
|
||||||
session.save( entityValue );
|
|
||||||
MapKey entityKey = new MapKey( key, entityValue );
|
|
||||||
session.save( entityKey );
|
|
||||||
mapHolder.getMap().put( entityKey, entityValue );
|
|
||||||
}
|
|
||||||
|
|
||||||
private MapHolder getMapHolder(Session session) {
|
|
||||||
List mapHolders = session.createQuery( "select distinct mh from MapHolder mh" ).list();
|
|
||||||
Assert.assertEquals( 1, mapHolders.size() );
|
|
||||||
return (MapHolder) mapHolders.get( 0 );
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue