work on aggregate composite identifier
This commit is contained in:
parent
04c5160e02
commit
9a0ad0f21d
|
@ -277,6 +277,7 @@ public class MetamodelSelectBuilderProcess {
|
|||
final ColumnReference columnReference = columnReferences.get( j );
|
||||
final JdbcParameter jdbcParameter = new JdbcParameterImpl( columnReference.getJdbcMapping() );
|
||||
jdbcParameterConsumer.accept( jdbcParameter );
|
||||
tupleParams.add( jdbcParameter );
|
||||
}
|
||||
final SqlTuple paramTuple = new SqlTuple( tupleParams, keyPart );
|
||||
predicate.addExpression( paramTuple );
|
||||
|
|
|
@ -279,7 +279,16 @@ public class EmbeddableMappingType implements ManagedMappingType {
|
|||
JdbcValuesConsumer consumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
attributeMappings.forEach(
|
||||
(s, attributeMapping) -> attributeMapping.visitJdbcValues( value, clause, consumer, session )
|
||||
(s, attributeMapping) -> {
|
||||
Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
||||
attributeMapping.visitJdbcValues( o, clause, consumer, session );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public void visitColumns(ColumnConsumer consumer) {
|
||||
attributeMappings.values().forEach(
|
||||
attributeMapping -> attributeMapping.visitColumns( consumer )
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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.metamodel.mapping;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public interface EmbeddedIdentifierMapping extends EntityIdentifierMapping, EmbeddableValuedModelPart {
|
||||
}
|
|
@ -0,0 +1,284 @@
|
|||
/*
|
||||
* 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.metamodel.mapping.internal;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.mapping.ColumnConsumer;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddedIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||
import org.hibernate.metamodel.mapping.MappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.JoinType;
|
||||
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
||||
import org.hibernate.sql.ast.tree.from.CompositeTableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||
import org.hibernate.sql.ast.tree.from.TableReferenceCollector;
|
||||
import org.hibernate.sql.results.internal.domain.composite.CompositeFetch;
|
||||
import org.hibernate.sql.results.internal.domain.composite.CompositeResult;
|
||||
import org.hibernate.sql.results.spi.DomainResult;
|
||||
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.spi.Fetch;
|
||||
import org.hibernate.sql.results.spi.FetchParent;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public class EmbeddedIdentifierMappingImpl extends AbstractStateArrayContributorMapping
|
||||
implements EmbeddedIdentifierMapping {
|
||||
private final PropertyAccess propertyAccess;
|
||||
private final String tableExpression;
|
||||
private final String[] attrColumnNames;
|
||||
|
||||
public EmbeddedIdentifierMappingImpl(
|
||||
String name,
|
||||
MappingType type,
|
||||
StateArrayContributorMetadataAccess attributeMetadataAccess,
|
||||
FetchStrategy mappedFetchStrategy,
|
||||
int stateArrayPosition,
|
||||
ManagedMappingType declaringType,
|
||||
PropertyAccess propertyAccess,
|
||||
String tableExpression,
|
||||
String[] attrColumnNames) {
|
||||
super( name, type, attributeMetadataAccess, mappedFetchStrategy, stateArrayPosition, declaringType );
|
||||
this.propertyAccess = propertyAccess;
|
||||
this.tableExpression = tableExpression;
|
||||
this.attrColumnNames = attrColumnNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPartName() {
|
||||
return getAttributeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyAccess getPropertyAccess() {
|
||||
return propertyAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getEmbeddableTypeDescriptor() {
|
||||
return getMappedTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getMappedTypeDescriptor() {
|
||||
return (EmbeddableMappingType) super.getMappedTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainingTableExpression() {
|
||||
return tableExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMappedColumnExpressions() {
|
||||
return Arrays.asList( attrColumnNames );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingularAttributeMapping getParentInjectionAttributeMapping() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJdbcTypes(
|
||||
Consumer<JdbcMapping> action,
|
||||
Clause clause,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
getMappedTypeDescriptor().visitJdbcTypes( action,clause,typeConfiguration );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJdbcValues(
|
||||
Object value, Clause clause, JdbcValuesConsumer valuesConsumer, SharedSessionContractImplementor session) {
|
||||
getEmbeddableTypeDescriptor().visitJdbcValues( value, clause, valuesConsumer, session );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public <T> DomainResult<T> createDomainResult(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
return new CompositeResult<>(
|
||||
navigablePath,
|
||||
this,
|
||||
resultVariable,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression toSqlExpression(
|
||||
TableGroup tableGroup,
|
||||
Clause clause,
|
||||
SqmToSqlAstConverter walker,
|
||||
SqlAstCreationState sqlAstCreationState) {
|
||||
final List<ColumnReference> columnReferences = CollectionHelper.arrayList( attrColumnNames.length );
|
||||
final TableReference tableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
|
||||
getEmbeddableTypeDescriptor().visitJdbcTypes(
|
||||
new Consumer<JdbcMapping>() {
|
||||
private int index = 0;
|
||||
|
||||
@Override
|
||||
public void accept(JdbcMapping jdbcMapping) {
|
||||
final String attrColumnExpr = attrColumnNames[ index++ ];
|
||||
|
||||
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
tableReference,
|
||||
attrColumnExpr
|
||||
),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
tableReference.getIdentificationVariable(),
|
||||
attrColumnExpr,
|
||||
jdbcMapping,
|
||||
sqlAstCreationState.getCreationContext().getSessionFactory()
|
||||
)
|
||||
);
|
||||
|
||||
columnReferences.add( (ColumnReference) columnReference );
|
||||
}
|
||||
},
|
||||
clause,
|
||||
sqlAstCreationState.getCreationContext().getSessionFactory().getTypeConfiguration()
|
||||
);
|
||||
|
||||
return new SqlTuple( columnReferences, this );
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableGroupJoin createTableGroupJoin(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup lhs,
|
||||
String explicitSourceAlias,
|
||||
JoinType joinType,
|
||||
LockMode lockMode,
|
||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||
SqlExpressionResolver sqlExpressionResolver,
|
||||
SqlAstCreationContext creationContext) {
|
||||
final CompositeTableGroup compositeTableGroup = new CompositeTableGroup(
|
||||
navigablePath,
|
||||
this,
|
||||
lhs
|
||||
);
|
||||
|
||||
lhs.addTableGroupJoin( new TableGroupJoin( navigablePath, JoinType.INNER, compositeTableGroup, null ) );
|
||||
|
||||
return new TableGroupJoin(
|
||||
navigablePath,
|
||||
joinType,
|
||||
compositeTableGroup
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSqlAliasStem() {
|
||||
return getAttributeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
|
||||
return getMappedTypeDescriptor().findSubPart( name, treatTargetType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSubParts(
|
||||
Consumer<ModelPart> consumer, EntityMappingType treatTargetType) {
|
||||
getMappedTypeDescriptor().visitSubParts( consumer, treatTargetType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTableReferences(
|
||||
SqlAliasBase sqlAliasBase,
|
||||
JoinType baseJoinType,
|
||||
TableReferenceCollector collector,
|
||||
SqlExpressionResolver sqlExpressionResolver,
|
||||
SqlAstCreationContext creationContext) {
|
||||
getEmbeddableTypeDescriptor().visitAttributeMappings(
|
||||
attrMapping -> {
|
||||
if ( attrMapping instanceof TableGroupProducer ) {
|
||||
( (TableGroupProducer) attrMapping ).applyTableReferences(
|
||||
sqlAliasBase,
|
||||
baseJoinType,
|
||||
collector,
|
||||
sqlExpressionResolver,
|
||||
creationContext
|
||||
);
|
||||
}
|
||||
else if ( attrMapping.getMappedTypeDescriptor() instanceof TableGroupProducer ) {
|
||||
( (TableGroupProducer) attrMapping.getMappedTypeDescriptor() ).applyTableReferences(
|
||||
sqlAliasBase,
|
||||
baseJoinType,
|
||||
collector,
|
||||
sqlExpressionResolver,
|
||||
creationContext
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fetch generateFetch(
|
||||
FetchParent fetchParent,
|
||||
NavigablePath fetchablePath,
|
||||
FetchTiming fetchTiming,
|
||||
boolean selected,
|
||||
LockMode lockMode,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
return new CompositeFetch(
|
||||
fetchablePath,
|
||||
this,
|
||||
fetchParent,
|
||||
fetchTiming,
|
||||
getAttributeMetadataAccess().resolveAttributeMetadata( null ).isNullable(),
|
||||
creationState
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfFetchables() {
|
||||
return getEmbeddableTypeDescriptor().getNumberOfAttributeMappings();
|
||||
}
|
||||
|
||||
public void visitColumns(ColumnConsumer consumer) {
|
||||
getEmbeddableTypeDescriptor().visitColumns( consumer );
|
||||
}
|
||||
}
|
|
@ -283,6 +283,8 @@ public class MappingModelCreationHelper {
|
|||
|
||||
public static EntityIdentifierMapping buildEncapsulatedCompositeIdentifierMapping(
|
||||
EntityPersister entityPersister,
|
||||
Property bootProperty,
|
||||
String attributeName,
|
||||
String rootTableName,
|
||||
String[] rootTableKeyColumnNames,
|
||||
CompositeType cidType,
|
||||
|
@ -294,48 +296,29 @@ public class MappingModelCreationHelper {
|
|||
final PropertyAccess propertyAccess = entityPersister.getRepresentationStrategy()
|
||||
.resolvePropertyAccess( bootEntityDescriptor.getIdentifierProperty() );
|
||||
|
||||
return new EntityIdentifierMapping() {
|
||||
@Override
|
||||
public PropertyAccess getPropertyAccess() {
|
||||
return propertyAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingType getMappedTypeDescriptor() {
|
||||
return ( (BasicValuedModelPart) entityPersister.getIdentifierType() ).getMappedTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor getJavaTypeDescriptor() {
|
||||
return getMappedTypeDescriptor().getMappedJavaTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DomainResult<T> createDomainResult(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
return ( (ModelPart) entityPersister.getIdentifierType() ).createDomainResult(
|
||||
navigablePath,
|
||||
tableGroup,
|
||||
resultVariable,
|
||||
creationState
|
||||
final StateArrayContributorMetadataAccess attributeMetadataAccess = getStateArrayContributorMetadataAccess(
|
||||
propertyAccess
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySqlSelections(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
DomainResultCreationState creationState) {
|
||||
( (ModelPart) entityPersister.getIdentifierType() ).applySqlSelections(
|
||||
navigablePath,
|
||||
tableGroup,
|
||||
creationState
|
||||
final EmbeddableMappingType embeddableMappingType = EmbeddableMappingType.from(
|
||||
(Component) bootProperty.getValue(),
|
||||
cidType,
|
||||
attributeMappingType -> new EmbeddedIdentifierMappingImpl(
|
||||
attributeName,
|
||||
attributeMappingType,
|
||||
attributeMetadataAccess,
|
||||
FetchStrategy.IMMEDIATE_JOIN,
|
||||
0,
|
||||
entityPersister,
|
||||
propertyAccess,
|
||||
rootTableName,
|
||||
rootTableKeyColumnNames
|
||||
),
|
||||
creationProcess
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (EmbeddedIdentifierMappingImpl) embeddableMappingType.getEmbeddedValueMapping();
|
||||
}
|
||||
|
||||
public static EntityIdentifierMapping buildNonEncapsulatedCompositeIdentifierMapping(
|
||||
|
@ -639,6 +622,58 @@ public class MappingModelCreationHelper {
|
|||
};
|
||||
}
|
||||
|
||||
protected static StateArrayContributorMetadataAccess getStateArrayContributorMetadataAccess(
|
||||
PropertyAccess propertyAccess) {
|
||||
return entityMappingType -> new StateArrayContributorMetadata() {
|
||||
|
||||
private final MutabilityPlan mutabilityPlan = ImmutableMutabilityPlan.INSTANCE;
|
||||
|
||||
|
||||
@Override
|
||||
public PropertyAccess getPropertyAccess() {
|
||||
return propertyAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutabilityPlan getMutabilityPlan() {
|
||||
return mutabilityPlan;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsertable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdatable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludedInDirtyChecking() {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludedInOptimisticLocking() {
|
||||
// todo (6.0) : do not sure this is correct
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CascadeStyle getCascadeStyle() {
|
||||
// todo (6.0) : do not sure this is correct
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static PluralAttributeMapping buildPluralAttributeMapping(
|
||||
String attrName,
|
||||
int stateArrayPosition,
|
||||
|
|
|
@ -6121,6 +6121,12 @@ public abstract class AbstractEntityPersister
|
|||
return;
|
||||
}
|
||||
|
||||
final RuntimeModelCreationContext creationContext = creationProcess.getCreationContext();
|
||||
|
||||
final PersistentClass bootEntityDescriptor = creationContext
|
||||
.getBootModel()
|
||||
.getEntityBinding( getEntityName() );
|
||||
|
||||
if ( superMappingType != null && shouldProcessSuperMapping() ) {
|
||||
( (InFlightEntityMappingType) superMappingType ).prepareMappingModel( creationProcess );
|
||||
|
||||
|
@ -6131,7 +6137,8 @@ public abstract class AbstractEntityPersister
|
|||
else {
|
||||
identifierMapping = creationProcess.processSubPart(
|
||||
EntityIdentifierMapping.ROLE_LOCAL_NAME,
|
||||
(role, creationProcess1) -> generateIdentifierMapping( creationProcess )
|
||||
(role, creationProcess1) ->
|
||||
generateIdentifierMapping( creationProcess, bootEntityDescriptor.getIdentifierProperty() )
|
||||
);
|
||||
|
||||
if ( getVersionType() == null ) {
|
||||
|
@ -6153,11 +6160,7 @@ public abstract class AbstractEntityPersister
|
|||
naturalIdMapping = null;
|
||||
}
|
||||
|
||||
final RuntimeModelCreationContext creationContext = creationProcess.getCreationContext();
|
||||
|
||||
final PersistentClass bootEntityDescriptor = creationContext
|
||||
.getBootModel()
|
||||
.getEntityBinding( getEntityName() );
|
||||
|
||||
final EntityMetamodel currentEntityMetamodel = this.getEntityMetamodel();
|
||||
int stateArrayPosition = getStateArrayInitialPosition( creationProcess );
|
||||
|
@ -6362,7 +6365,7 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
|
||||
private EntityIdentifierMapping generateIdentifierMapping(MappingModelCreationProcess creationProcess) {
|
||||
private EntityIdentifierMapping generateIdentifierMapping(MappingModelCreationProcess creationProcess, Property identifierProperty) {
|
||||
final Type idType = getIdentifierType();
|
||||
|
||||
if ( idType instanceof CompositeType ) {
|
||||
|
@ -6370,6 +6373,8 @@ public abstract class AbstractEntityPersister
|
|||
if ( ! cidType.isEmbedded() ) {
|
||||
return MappingModelCreationHelper.buildEncapsulatedCompositeIdentifierMapping(
|
||||
this,
|
||||
identifierProperty,
|
||||
identifierProperty.getName(),
|
||||
getRootTableName(),
|
||||
rootTableKeyColumnNames,
|
||||
cidType,
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* 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.sql.exec;
|
||||
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
|
||||
import org.hibernate.testing.orm.domain.gambit.EmbeddedIdEntity;
|
||||
import org.hibernate.testing.orm.domain.gambit.EmbeddedIdEntity.EmbeddedIdEntityId;
|
||||
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.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.IsNull.notNullValue;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
EmbeddedIdEntity.class
|
||||
}
|
||||
)
|
||||
@ServiceRegistry
|
||||
@SessionFactory(generateStatistics = true)
|
||||
public class EmbeddedIdEntityTest {
|
||||
|
||||
private EmbeddedIdEntityId entityId;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp(SessionFactoryScope scope) {
|
||||
final EmbeddedIdEntity entity = new EmbeddedIdEntity();
|
||||
entityId = new EmbeddedIdEntityId( 25, "Acme" );
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
entity.setId( entityId );
|
||||
entity.setData( "test" );
|
||||
session.save( entity );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
sesison ->
|
||||
sesison.createQuery( "delete from EmbeddedIdEntity" ).executeUpdate()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHqlSelectAField(SessionFactoryScope scope) {
|
||||
StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final String value = session.createQuery( "select e.data FROM EmbeddedIdEntity e", String.class )
|
||||
.uniqueResult();
|
||||
assertThat( value, is( "test" ) );
|
||||
}
|
||||
);
|
||||
assertThat( statistics.getPrepareStatementCount(), is( 1L ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHqlSelect(SessionFactoryScope scope) {
|
||||
StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final EmbeddedIdEntity loaded = session.createQuery(
|
||||
"select e FROM EmbeddedIdEntity e",
|
||||
EmbeddedIdEntity.class
|
||||
).uniqueResult();
|
||||
assertThat( loaded.getData(), is( "test" ) );
|
||||
assertThat( loaded.getId(), equalTo( entityId ) );
|
||||
}
|
||||
);
|
||||
assertThat( statistics.getPrepareStatementCount(), is( 1L ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHqlSelectOnlyTheEmbeddedId(SessionFactoryScope scope) {
|
||||
StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final EmbeddedIdEntityId value = session.createQuery(
|
||||
"select e.id FROM EmbeddedIdEntity e",
|
||||
EmbeddedIdEntityId.class
|
||||
).uniqueResult();
|
||||
assertThat( value, equalTo( entityId ) );
|
||||
}
|
||||
);
|
||||
assertThat( statistics.getPrepareStatementCount(), is( 1L ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGet(SessionFactoryScope scope) {
|
||||
StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final EmbeddedIdEntity loaded = session.get( EmbeddedIdEntity.class, entityId );
|
||||
assertThat( loaded, notNullValue() );
|
||||
assertThat( loaded.getId(), notNullValue() );
|
||||
assertThat( loaded.getId(), equalTo( entityId ) );
|
||||
assertThat( loaded.getData(), is( "test" ) );
|
||||
}
|
||||
);
|
||||
assertThat( statistics.getPrepareStatementCount(), is( 1L ) );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* 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.sql.exec;
|
||||
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
|
||||
import org.hibernate.testing.orm.domain.gambit.EntityWithNotAggregateId;
|
||||
import org.hibernate.testing.orm.domain.gambit.EntityWithNotAggregateId.PK;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.FailureExpected;
|
||||
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.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.IsNull.notNullValue;
|
||||
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
EntityWithNotAggregateId.class
|
||||
}
|
||||
)
|
||||
@ServiceRegistry
|
||||
@SessionFactory(generateStatistics = true)
|
||||
@Disabled(value = "non aggregate composit id has not been yet implemented")
|
||||
public class EntityWithNotAggregateIdTest {
|
||||
|
||||
private PK entityId;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp(SessionFactoryScope scope) {
|
||||
final EntityWithNotAggregateId entity = new EntityWithNotAggregateId();
|
||||
entityId = new PK( 25, "Acme" );
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
entity.setId( entityId );
|
||||
entity.setData( "test" );
|
||||
session.save( entity );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
sesison ->
|
||||
sesison.createQuery( "delete from EntityWithIdClass" ).executeUpdate()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHqlSelectAField(SessionFactoryScope scope) {
|
||||
StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final String value = session.createQuery( "select e.data FROM EntityWithIdClass e", String.class )
|
||||
.uniqueResult();
|
||||
assertThat( value, is( "test" ) );
|
||||
}
|
||||
);
|
||||
assertThat( statistics.getPrepareStatementCount(), is( 1L ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHqlSelect(SessionFactoryScope scope) {
|
||||
StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final EntityWithNotAggregateId loaded = session.createQuery(
|
||||
"select e FROM EntityWithIdClass e",
|
||||
EntityWithNotAggregateId.class
|
||||
).uniqueResult();
|
||||
assertThat( loaded.getData(), is( "test" ) );
|
||||
assertThat( loaded.getId(), equalTo( entityId ) );
|
||||
}
|
||||
);
|
||||
assertThat( statistics.getPrepareStatementCount(), is( 1L ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHqlSelectOnlyTheEmbeddedId(SessionFactoryScope scope) {
|
||||
StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final EntityWithNotAggregateId value = session.createQuery(
|
||||
"select e.id FROM EntityWithIdClass e",
|
||||
EntityWithNotAggregateId.class
|
||||
).uniqueResult();
|
||||
assertThat( value, equalTo( entityId ) );
|
||||
}
|
||||
);
|
||||
assertThat( statistics.getPrepareStatementCount(), is( 1L ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGet(SessionFactoryScope scope) {
|
||||
StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final EntityWithNotAggregateId loaded = session.get( EntityWithNotAggregateId.class, entityId );
|
||||
assertThat( loaded, notNullValue() );
|
||||
assertThat( loaded.getId(), notNullValue() );
|
||||
assertThat( loaded.getId(), equalTo( entityId ) );
|
||||
assertThat( loaded.getData(), is( "test" ) );
|
||||
}
|
||||
);
|
||||
assertThat( statistics.getPrepareStatementCount(), is( 1L ) );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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.testing.orm.domain.gambit;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@Entity
|
||||
@IdClass(EntityWithNotAggregateId.PK.class)
|
||||
public class EntityWithNotAggregateId {
|
||||
|
||||
@Id
|
||||
private Integer value1;
|
||||
|
||||
@Id
|
||||
private String value2;
|
||||
|
||||
private String data;
|
||||
|
||||
public PK getId() {
|
||||
return new PK( value1, value2 );
|
||||
}
|
||||
|
||||
public void setId(PK id) {
|
||||
this.value1 = id.getValue1();
|
||||
this.value2 = id.getValue2();
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static class PK implements Serializable {
|
||||
private Integer value1;
|
||||
private String value2;
|
||||
|
||||
public PK() {
|
||||
}
|
||||
|
||||
public PK(Integer value1, String value2) {
|
||||
this.value1 = value1;
|
||||
this.value2 = value2;
|
||||
}
|
||||
|
||||
public Integer getValue1() {
|
||||
return value1;
|
||||
}
|
||||
|
||||
public void setValue1(Integer value1) {
|
||||
this.value1 = value1;
|
||||
}
|
||||
|
||||
public String getValue2() {
|
||||
return value2;
|
||||
}
|
||||
|
||||
public void setValue2(String value2) {
|
||||
this.value2 = value2;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue