Fix issues with inverse FK creation and related natural id issues
This commit is contained in:
parent
0fafae4624
commit
5b5254fbd6
|
@ -7,9 +7,11 @@
|
|||
package org.hibernate.action.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -22,10 +24,15 @@ import org.hibernate.cache.spi.access.NaturalIdDataAccess;
|
|||
import org.hibernate.cache.spi.access.SoftLock;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.metamodel.spi.MetamodelImplementor;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.Queryable;
|
||||
import org.hibernate.query.sqm.tree.SqmDmlStatement;
|
||||
import org.hibernate.query.sqm.tree.SqmStatement;
|
||||
import org.hibernate.query.sqm.tree.cte.SqmCteStatement;
|
||||
import org.hibernate.sql.ast.tree.insert.InsertStatement;
|
||||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||
|
||||
/**
|
||||
* An {@link org.hibernate.engine.spi.ActionQueue} {@link org.hibernate.action.spi.Executable} for ensuring
|
||||
|
@ -56,10 +63,10 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
|
|||
* @param session The session to which this request is tied.
|
||||
* @param affectedQueryables The affected entity persisters.
|
||||
*/
|
||||
public BulkOperationCleanupAction(SharedSessionContractImplementor session, Queryable... affectedQueryables) {
|
||||
public BulkOperationCleanupAction(SharedSessionContractImplementor session, EntityPersister... affectedQueryables) {
|
||||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
final LinkedHashSet<String> spacesList = new LinkedHashSet<>();
|
||||
for ( Queryable persister : affectedQueryables ) {
|
||||
for ( EntityPersister persister : affectedQueryables ) {
|
||||
Collections.addAll( spacesList, (String[]) persister.getQuerySpaces() );
|
||||
|
||||
if ( persister.canWriteToCache() ) {
|
||||
|
@ -96,7 +103,7 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
|
|||
|
||||
/**
|
||||
* Constructs an action to cleanup "affected cache regions" based on a
|
||||
* set of affected table spaces. This differs from {@link #BulkOperationCleanupAction(SharedSessionContractImplementor, Queryable[])}
|
||||
* set of affected table spaces. This differs from {@link #BulkOperationCleanupAction(SharedSessionContractImplementor, EntityPersister[])}
|
||||
* in that here we have the affected <strong>table names</strong>. From those
|
||||
* we deduce the entity persisters which are affected based on the defined
|
||||
* {@link EntityPersister#getQuerySpaces() table spaces}; and from there, we
|
||||
|
@ -141,6 +148,37 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
|
|||
this.affectedTableSpaces = spacesList.toArray( new String[ 0 ] );
|
||||
}
|
||||
|
||||
public static void schedule(ExecutionContext executionContext, SqmDmlStatement<?> statement) {
|
||||
final List<EntityPersister> entityPersisters = new ArrayList<>( 1 );
|
||||
final MetamodelImplementor metamodel = executionContext.getSession()
|
||||
.getFactory()
|
||||
.getMetamodel();
|
||||
if ( !( statement instanceof InsertStatement ) ) {
|
||||
entityPersisters.add( metamodel.entityPersister( statement.getTarget().getEntityName() ) );
|
||||
}
|
||||
for ( SqmCteStatement<?> cteStatement : statement.getCteStatements() ) {
|
||||
final SqmStatement<?> cteDefinition = cteStatement.getCteDefinition();
|
||||
if ( cteDefinition instanceof SqmDmlStatement<?> && !( cteDefinition instanceof InsertStatement ) ) {
|
||||
entityPersisters.add(
|
||||
metamodel.entityPersister( ( (SqmDmlStatement<?>) cteDefinition ).getTarget().getEntityName() )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
schedule( executionContext, entityPersisters.toArray( new EntityPersister[0] ) );
|
||||
}
|
||||
|
||||
public static void schedule(ExecutionContext executionContext, EntityPersister... affectedQueryables) {
|
||||
final SharedSessionContractImplementor session = executionContext.getSession();
|
||||
final BulkOperationCleanupAction action = new BulkOperationCleanupAction( session, affectedQueryables );
|
||||
if ( session.isEventSource() ) {
|
||||
( (EventSource) session ).getActionQueue().addAction( action );
|
||||
}
|
||||
else {
|
||||
action.getAfterTransactionCompletionProcess().doAfterTransactionCompletion( true, session );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check whether we should consider an entity as affected by the query. This
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.loader.ast.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
|
@ -15,17 +16,21 @@ import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
|||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||
import org.hibernate.query.ComparisonOperator;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
import org.hibernate.query.spi.QueryParameterBindings;
|
||||
import org.hibernate.query.sqm.sql.FromClauseIndex;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||
import org.hibernate.sql.ast.spi.SqlAliasBaseManager;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||
import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
|
||||
|
@ -41,6 +46,7 @@ import org.hibernate.sql.exec.spi.JdbcSelect;
|
|||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.sql.results.internal.RowTransformerDatabaseSnapshotImpl;
|
||||
import org.hibernate.type.IntegerType;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -63,6 +69,9 @@ class DatabaseSnapshotExecutor {
|
|||
SessionFactoryImplementor sessionFactory) {
|
||||
this.entityDescriptor = entityDescriptor;
|
||||
this.sessionFactory = sessionFactory;
|
||||
this.jdbcParameters = new ArrayList<>(
|
||||
entityDescriptor.getIdentifierMapping().getJdbcTypeCount()
|
||||
);
|
||||
|
||||
final QuerySpec rootQuerySpec = new QuerySpec( true );
|
||||
|
||||
|
@ -71,7 +80,10 @@ class DatabaseSnapshotExecutor {
|
|||
final LoaderSqlAstCreationState state = new LoaderSqlAstCreationState(
|
||||
rootQuerySpec,
|
||||
sqlAliasBaseManager,
|
||||
new FromClauseIndex( null ),
|
||||
LockOptions.READ,
|
||||
(fetchParent, ast, creationState) -> Collections.emptyList(),
|
||||
true,
|
||||
sessionFactory
|
||||
);
|
||||
|
||||
|
@ -88,14 +100,15 @@ class DatabaseSnapshotExecutor {
|
|||
);
|
||||
|
||||
rootQuerySpec.getFromClause().addRoot( rootTableGroup );
|
||||
state.getFromClauseAccess().registerTableGroup( rootPath, rootTableGroup );
|
||||
|
||||
jdbcParameters = new ArrayList<>(
|
||||
entityDescriptor.getIdentifierMapping().getJdbcTypeCount()
|
||||
);
|
||||
|
||||
//noinspection rawtypes
|
||||
// We produce the same state array as if we were creating an entity snapshot
|
||||
final List<DomainResult> domainResults = new ArrayList<>();
|
||||
|
||||
// We just need a literal to have a result set
|
||||
domainResults.add(
|
||||
new QueryLiteral<>( null, IntegerType.INSTANCE ).createDomainResult( null, state )
|
||||
);
|
||||
entityDescriptor.getIdentifierMapping().forEachSelection(
|
||||
(columnIndex, selection) -> {
|
||||
final TableReference tableReference = rootTableGroup.resolveTableReference( selection.getContainingTableExpression() );
|
||||
|
@ -120,69 +133,54 @@ class DatabaseSnapshotExecutor {
|
|||
jdbcParameter
|
||||
)
|
||||
);
|
||||
|
||||
final SqlSelection sqlSelection = state.getSqlExpressionResolver().resolveSqlSelection(
|
||||
columnReference,
|
||||
selection.getJdbcMapping().getJavaTypeDescriptor(),
|
||||
sessionFactory.getTypeConfiguration()
|
||||
);
|
||||
|
||||
//noinspection unchecked
|
||||
domainResults.add(
|
||||
new BasicResult<Object>(
|
||||
sqlSelection.getValuesArrayPosition(),
|
||||
null,
|
||||
selection.getJdbcMapping().getJavaTypeDescriptor()
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
entityDescriptor.visitStateArrayContributors(
|
||||
contributorMapping -> {
|
||||
rootPath.append( contributorMapping.getAttributeName() );
|
||||
contributorMapping.forEachSelection(
|
||||
(columnIndex, selection) -> {
|
||||
final TableReference tableReference = rootTableGroup.resolveTableReference(
|
||||
selection.getContainingTableExpression() );
|
||||
|
||||
final ColumnReference columnReference = (ColumnReference) state.getSqlExpressionResolver()
|
||||
.resolveSqlExpression(
|
||||
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
|
||||
s -> new ColumnReference(
|
||||
tableReference,
|
||||
selection,
|
||||
sessionFactory
|
||||
)
|
||||
);
|
||||
|
||||
final SqlSelection sqlSelection = state.getSqlExpressionResolver()
|
||||
.resolveSqlSelection(
|
||||
columnReference,
|
||||
selection.getJdbcMapping().getJavaTypeDescriptor(),
|
||||
sessionFactory.getTypeConfiguration()
|
||||
);
|
||||
|
||||
//noinspection unchecked
|
||||
domainResults.add(
|
||||
new BasicResult<Object>(
|
||||
sqlSelection.getValuesArrayPosition(),
|
||||
null,
|
||||
selection.getJdbcMapping().getJavaTypeDescriptor()
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
final NavigablePath navigablePath = rootPath.append( contributorMapping.getAttributeName() );
|
||||
if ( contributorMapping instanceof SingularAttributeMapping ) {
|
||||
if ( contributorMapping instanceof EntityAssociationMapping ) {
|
||||
domainResults.add(
|
||||
( (EntityAssociationMapping) contributorMapping ).createDelayedDomainResult(
|
||||
navigablePath,
|
||||
rootTableGroup,
|
||||
null,
|
||||
state
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
domainResults.add(
|
||||
contributorMapping.createDomainResult(
|
||||
navigablePath,
|
||||
rootTableGroup,
|
||||
null,
|
||||
state
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// TODO: Instead use a delayed collection result? Or will we remove this when redesigning this
|
||||
//noinspection unchecked
|
||||
domainResults.add(
|
||||
new BasicResult<Object>(
|
||||
0,
|
||||
null,
|
||||
contributorMapping.getJavaTypeDescriptor()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
final SelectStatement selectStatement = new SelectStatement( rootQuerySpec, domainResults );
|
||||
|
||||
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
|
||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
||||
|
||||
jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, selectStatement )
|
||||
this.jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, selectStatement )
|
||||
.translate( null, QueryOptions.NONE );
|
||||
}
|
||||
|
||||
|
@ -232,10 +230,6 @@ class DatabaseSnapshotExecutor {
|
|||
true
|
||||
);
|
||||
|
||||
if ( list.isEmpty() ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int size = list.size();
|
||||
assert size <= 1;
|
||||
|
||||
|
@ -243,7 +237,17 @@ class DatabaseSnapshotExecutor {
|
|||
return null;
|
||||
}
|
||||
else {
|
||||
return (Object[]) list.get( 0 );
|
||||
final Object[] entitySnapshot = (Object[]) list.get( 0 );
|
||||
// The result of this method is treated like the entity state array which doesn't include the id
|
||||
// So we must exclude it from the array
|
||||
if ( entitySnapshot.length == 1 ) {
|
||||
return ArrayHelper.EMPTY_OBJECT_ARRAY;
|
||||
}
|
||||
else {
|
||||
final Object[] state = new Object[entitySnapshot.length - 1];
|
||||
System.arraycopy( entitySnapshot, 1, state, 0, state.length );
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.loader.ast.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -16,7 +15,6 @@ import javax.persistence.CacheStoreMode;
|
|||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.graph.spi.AppliedGraph;
|
||||
import org.hibernate.metamodel.mapping.AssociationKey;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
|
@ -34,7 +32,6 @@ import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
|||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.spi.SqlAstProcessingState;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
|
@ -82,22 +79,6 @@ public class LoaderSqlAstCreationState
|
|||
);
|
||||
}
|
||||
|
||||
public LoaderSqlAstCreationState(
|
||||
QuerySpec querySpec,
|
||||
SqlAliasBaseManager sqlAliasBaseManager,
|
||||
LockOptions lockOptions,
|
||||
SessionFactoryImplementor sf) {
|
||||
this(
|
||||
querySpec,
|
||||
sqlAliasBaseManager,
|
||||
new FromClauseIndex(),
|
||||
lockOptions,
|
||||
(fetchParent, ast, state) -> Collections.emptyList(),
|
||||
true,
|
||||
sf
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlAstCreationContext getCreationContext() {
|
||||
return sf;
|
||||
|
@ -164,48 +145,6 @@ public class LoaderSqlAstCreationState
|
|||
return null;
|
||||
}
|
||||
|
||||
private static class FromClauseIndex implements FromClauseAccess {
|
||||
private TableGroup tableGroup;
|
||||
|
||||
@Override
|
||||
public TableGroup findTableGroup(NavigablePath navigablePath) {
|
||||
if ( tableGroup != null ) {
|
||||
if ( tableGroup.getNavigablePath().equals( navigablePath ) ) {
|
||||
return tableGroup;
|
||||
}
|
||||
if ( tableGroup.getNavigablePath()
|
||||
.getIdentifierForTableGroup()
|
||||
.equals( navigablePath.getIdentifierForTableGroup() ) ) {
|
||||
return tableGroup;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(
|
||||
"NavigablePath [" + navigablePath + "] did not match base TableGroup ["
|
||||
+ tableGroup.getNavigablePath() + "]"
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerTableGroup(NavigablePath navigablePath, TableGroup tableGroup) {
|
||||
assert tableGroup.getNavigablePath().equals( navigablePath );
|
||||
|
||||
if ( this.tableGroup != null ) {
|
||||
if ( this.tableGroup != tableGroup ) {
|
||||
throw new IllegalArgumentException(
|
||||
"Base TableGroup [" + tableGroup.getNavigablePath() + "] already set - " + navigablePath
|
||||
);
|
||||
}
|
||||
assert this.tableGroup.getNavigablePath().equals( navigablePath );
|
||||
}
|
||||
else {
|
||||
this.tableGroup = tableGroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getTimeout() {
|
||||
return null;
|
||||
|
|
|
@ -14,7 +14,7 @@ import org.hibernate.sql.results.graph.Fetchable;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface AttributeMapping extends ModelPart, ValueMapping, Fetchable {
|
||||
public interface AttributeMapping extends ModelPart, ValueMapping, Fetchable, PropertyBasedMapping {
|
||||
String getAttributeName();
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.mapping;
|
||||
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
|
||||
/**
|
||||
* Commonality between `many-to-one`, `one-to-one` and `any`, as well as entity-valued collection elements and map-keys
|
||||
*
|
||||
|
@ -29,4 +35,15 @@ public interface EntityAssociationMapping extends ModelPart, Association {
|
|||
default boolean incrementFetchDepth(){
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a delayed DomainResult for a specific reference to this ModelPart.
|
||||
*/
|
||||
default <T> DomainResult<T> createDelayedDomainResult(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* 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.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.sql.results.graph.Fetchable;
|
||||
|
||||
/**
|
||||
* Describes an attribute with a property access.
|
||||
*
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
public interface PropertyBasedMapping {
|
||||
|
||||
PropertyAccess getPropertyAccess();
|
||||
}
|
|
@ -121,8 +121,7 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
|
|||
|
||||
for ( int i = 0; i <= attributes.size() - 1; i++ ) {
|
||||
final SingularAttributeMapping attributeMapping = attributes.get( i );
|
||||
final Object domainValue = state[ attributeMapping.getStateArrayPosition() ];
|
||||
values[ i ] = attributeMapping.disassemble( domainValue, session );
|
||||
values[ i ] = state[ attributeMapping.getStateArrayPosition() ];
|
||||
}
|
||||
|
||||
return values;
|
||||
|
|
|
@ -53,13 +53,13 @@ import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
|||
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
|
||||
import org.hibernate.metamodel.mapping.CollectionMappingType;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.mapping.PropertyBasedMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectionMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectionMappings;
|
||||
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||
|
@ -884,7 +884,7 @@ public class MappingModelCreationHelper {
|
|||
if ( attributeMappingSubPart instanceof ToOneAttributeMapping ) {
|
||||
final ToOneAttributeMapping referencedAttributeMapping = (ToOneAttributeMapping) attributeMappingSubPart;
|
||||
|
||||
setRefererencedAttributeForeignKeyDescriptor(
|
||||
setReferencedAttributeForeignKeyDescriptor(
|
||||
attributeMapping,
|
||||
referencedAttributeMapping,
|
||||
(EntityPersister) referencedAttributeMapping.getDeclaringType(),
|
||||
|
@ -921,7 +921,8 @@ public class MappingModelCreationHelper {
|
|||
attributeMapping.setForeignKeyDescriptor(
|
||||
new SimpleForeignKeyDescriptor(
|
||||
keySelectionMapping,
|
||||
simpleFkTarget
|
||||
simpleFkTarget,
|
||||
( (PropertyBasedMapping) simpleFkTarget ).getPropertyAccess()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -959,18 +960,22 @@ public class MappingModelCreationHelper {
|
|||
final EntityPersister referencedEntityDescriptor = creationProcess
|
||||
.getEntityPersister( bootValueMapping.getReferencedEntityName() );
|
||||
|
||||
final String referencedPropertyName;
|
||||
String referencedPropertyName;
|
||||
if ( bootValueMapping instanceof OneToOne ) {
|
||||
referencedPropertyName = ( (OneToOne) bootValueMapping ).getMappedByProperty();
|
||||
OneToOne oneToOne = (OneToOne) bootValueMapping;
|
||||
referencedPropertyName = oneToOne.getMappedByProperty();
|
||||
if ( referencedPropertyName == null ) {
|
||||
referencedPropertyName = oneToOne.getReferencedPropertyName();
|
||||
}
|
||||
}
|
||||
else {
|
||||
referencedPropertyName = bootValueMapping.getReferencedPropertyName();
|
||||
referencedPropertyName = null;
|
||||
}
|
||||
|
||||
if ( referencedPropertyName != null ) {
|
||||
final ModelPart modelPart = referencedEntityDescriptor.findSubPart( referencedPropertyName );
|
||||
if ( modelPart instanceof ToOneAttributeMapping ) {
|
||||
setRefererencedAttributeForeignKeyDescriptor(
|
||||
setReferencedAttributeForeignKeyDescriptor(
|
||||
attributeMapping,
|
||||
(ToOneAttributeMapping) modelPart,
|
||||
referencedEntityDescriptor,
|
||||
|
@ -983,6 +988,7 @@ public class MappingModelCreationHelper {
|
|||
final EmbeddedForeignKeyDescriptor embeddedForeignKeyDescriptor = buildEmbeddableForeignKeyDescriptor(
|
||||
(EmbeddableValuedModelPart) modelPart,
|
||||
bootValueMapping,
|
||||
true,
|
||||
dialect,
|
||||
creationProcess
|
||||
);
|
||||
|
@ -1027,7 +1033,8 @@ public class MappingModelCreationHelper {
|
|||
|
||||
final ForeignKeyDescriptor foreignKeyDescriptor = new SimpleForeignKeyDescriptor(
|
||||
keySelectionMapping,
|
||||
simpleFkTarget
|
||||
simpleFkTarget,
|
||||
( (PropertyBasedMapping) simpleFkTarget ).getPropertyAccess()
|
||||
);
|
||||
attributeMapping.setForeignKeyDescriptor( foreignKeyDescriptor );
|
||||
}
|
||||
|
@ -1053,6 +1060,21 @@ public class MappingModelCreationHelper {
|
|||
Value bootValueMapping,
|
||||
Dialect dialect,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
return buildEmbeddableForeignKeyDescriptor(
|
||||
embeddableValuedModelPart,
|
||||
bootValueMapping,
|
||||
false,
|
||||
dialect,
|
||||
creationProcess
|
||||
);
|
||||
}
|
||||
|
||||
private static EmbeddedForeignKeyDescriptor buildEmbeddableForeignKeyDescriptor(
|
||||
EmbeddableValuedModelPart embeddableValuedModelPart,
|
||||
Value bootValueMapping,
|
||||
boolean inverse,
|
||||
Dialect dialect,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
final SelectionMappings keySelectionMappings;
|
||||
final String keyTableExpression;
|
||||
if ( bootValueMapping instanceof Collection ) {
|
||||
|
@ -1082,17 +1104,29 @@ public class MappingModelCreationHelper {
|
|||
creationProcess.getSqmFunctionRegistry()
|
||||
);
|
||||
}
|
||||
return new EmbeddedForeignKeyDescriptor(
|
||||
embeddableValuedModelPart,
|
||||
keyTableExpression,
|
||||
keySelectionMappings,
|
||||
embeddableValuedModelPart.getContainingTableExpression(),
|
||||
embeddableValuedModelPart.getEmbeddableTypeDescriptor(),
|
||||
creationProcess
|
||||
);
|
||||
if ( inverse ) {
|
||||
return new EmbeddedForeignKeyDescriptor(
|
||||
embeddableValuedModelPart,
|
||||
embeddableValuedModelPart.getContainingTableExpression(),
|
||||
embeddableValuedModelPart.getEmbeddableTypeDescriptor(),
|
||||
keyTableExpression,
|
||||
keySelectionMappings,
|
||||
creationProcess
|
||||
);
|
||||
}
|
||||
else {
|
||||
return new EmbeddedForeignKeyDescriptor(
|
||||
embeddableValuedModelPart,
|
||||
keyTableExpression,
|
||||
keySelectionMappings,
|
||||
embeddableValuedModelPart.getContainingTableExpression(),
|
||||
embeddableValuedModelPart.getEmbeddableTypeDescriptor(),
|
||||
creationProcess
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setRefererencedAttributeForeignKeyDescriptor(
|
||||
private static void setReferencedAttributeForeignKeyDescriptor(
|
||||
AbstractAttributeMapping attributeMapping,
|
||||
ToOneAttributeMapping referencedAttributeMapping,
|
||||
EntityPersister referencedEntityDescriptor,
|
||||
|
|
|
@ -28,10 +28,12 @@ import org.hibernate.mapping.IndexedConsumer;
|
|||
import org.hibernate.mapping.List;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.mapping.Value;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
|
||||
import org.hibernate.metamodel.mapping.CollectionMappingType;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.mapping.PropertyBasedMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectionMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
|
@ -339,7 +341,8 @@ public class PluralAttributeMappingImpl
|
|||
);
|
||||
return new SimpleForeignKeyDescriptor(
|
||||
keySelectionMapping,
|
||||
basicFkTargetPart
|
||||
basicFkTargetPart,
|
||||
( (PropertyBasedMapping) basicFkTargetPart ).getPropertyAccess()
|
||||
);
|
||||
}
|
||||
else if ( fkTargetPart instanceof EmbeddableValuedModelPart ) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
|||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.MappingType;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.query.ComparisonOperator;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
|
@ -51,13 +52,16 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
|||
public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicValuedModelPart, FetchOptions {
|
||||
private final SelectionMapping keySelectionMapping;
|
||||
private final SelectionMapping targetSelectionMapping;
|
||||
private final PropertyAccess propertyAccess;
|
||||
private AssociationKey associationKey;
|
||||
|
||||
public SimpleForeignKeyDescriptor(
|
||||
SelectionMapping keySelectionMapping,
|
||||
SelectionMapping targetSelectionMapping) {
|
||||
SelectionMapping targetSelectionMapping,
|
||||
PropertyAccess propertyAccess) {
|
||||
this.keySelectionMapping = keySelectionMapping;
|
||||
this.targetSelectionMapping = targetSelectionMapping;
|
||||
this.propertyAccess = propertyAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -260,7 +264,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
|
|||
|
||||
@Override
|
||||
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||
return value;
|
||||
return value == null ? null : propertyAccess.getGetter().get( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,12 +7,13 @@
|
|||
package org.hibernate.metamodel.mapping.internal;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.PropertyBasedMapping;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface SingleAttributeIdentifierMapping extends EntityIdentifierMapping {
|
||||
public interface SingleAttributeIdentifierMapping extends EntityIdentifierMapping, PropertyBasedMapping {
|
||||
/**
|
||||
* Access to the identifier attribute's PropertyAccess
|
||||
*/
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.mapping.OneToOne;
|
|||
import org.hibernate.mapping.ToOne;
|
||||
import org.hibernate.metamodel.mapping.AssociationKey;
|
||||
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
|
@ -52,8 +53,10 @@ import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
|
|||
import org.hibernate.sql.results.graph.entity.EntityFetch;
|
||||
import org.hibernate.sql.results.graph.entity.EntityValuedFetchable;
|
||||
import org.hibernate.sql.results.graph.entity.internal.EntityDelayedFetchImpl;
|
||||
import org.hibernate.sql.results.graph.entity.internal.EntityDelayedResultImpl;
|
||||
import org.hibernate.sql.results.graph.entity.internal.EntityFetchJoinedImpl;
|
||||
import org.hibernate.sql.results.graph.entity.internal.EntityFetchSelectImpl;
|
||||
import org.hibernate.sql.results.graph.entity.internal.EntityResultImpl;
|
||||
import org.hibernate.sql.results.graph.entity.internal.EntityResultJoinedSubclassImpl;
|
||||
import org.hibernate.sql.results.internal.domain.CircularBiDirectionalFetchImpl;
|
||||
import org.hibernate.sql.results.internal.domain.CircularFetchImpl;
|
||||
|
@ -494,6 +497,48 @@ public class ToOneAttributeMapping
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DomainResult<T> createDelayedDomainResult(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
// We only need a join if the key is on the referring side i.e. this is an inverse to-one
|
||||
// and if the FK refers to a non-PK, in which case we must load the whole entity
|
||||
if ( !isKeyReferringSide || referencedPropertyName != null ) {
|
||||
final TableGroupJoin tableGroupJoin = createTableGroupJoin(
|
||||
navigablePath,
|
||||
tableGroup,
|
||||
null,
|
||||
tableGroup.isInnerJoinPossible() ? SqlAstJoinType.INNER : SqlAstJoinType.LEFT,
|
||||
null,
|
||||
creationState.getSqlAstCreationState()
|
||||
);
|
||||
|
||||
creationState.getSqlAstCreationState().getFromClauseAccess().registerTableGroup(
|
||||
navigablePath,
|
||||
tableGroupJoin.getJoinedGroup()
|
||||
);
|
||||
}
|
||||
if ( referencedPropertyName == null ) {
|
||||
return new EntityDelayedResultImpl(
|
||||
navigablePath.append( EntityIdentifierMapping.ROLE_LOCAL_NAME ),
|
||||
this,
|
||||
tableGroup,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
else {
|
||||
// We don't support proxies based on a non-PK yet, so we must fetch the whole entity
|
||||
return new EntityResultImpl(
|
||||
navigablePath,
|
||||
this,
|
||||
null,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private TableGroup createTableGroupJoin(
|
||||
NavigablePath fetchablePath,
|
||||
LockMode lockMode,
|
||||
|
@ -653,6 +698,12 @@ public class ToOneAttributeMapping
|
|||
|
||||
@Override
|
||||
public int forEachJdbcValue(Object value, Clause clause, int offset, JdbcValuesConsumer consumer, SharedSessionContractImplementor session) {
|
||||
return foreignKeyDescriptor.forEachJdbcValue( value, clause, offset, consumer, session );
|
||||
return foreignKeyDescriptor.forEachJdbcValue(
|
||||
foreignKeyDescriptor.disassemble( value, session ),
|
||||
clause,
|
||||
offset,
|
||||
consumer,
|
||||
session
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm.internal;
|
||||
|
||||
import org.hibernate.action.internal.BulkOperationCleanupAction;
|
||||
import org.hibernate.query.spi.NonSelectQueryPlan;
|
||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
||||
import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement;
|
||||
|
@ -30,6 +31,7 @@ public class MultiTableDeleteQueryPlan implements NonSelectQueryPlan {
|
|||
|
||||
@Override
|
||||
public int executeUpdate(ExecutionContext executionContext) {
|
||||
BulkOperationCleanupAction.schedule( executionContext, sqmDelete );
|
||||
return deleteStrategy.executeDelete( sqmDelete, domainParameterXref, executionContext );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm.internal;
|
||||
|
||||
import org.hibernate.action.internal.BulkOperationCleanupAction;
|
||||
import org.hibernate.query.spi.NonSelectQueryPlan;
|
||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
||||
import org.hibernate.query.sqm.tree.update.SqmUpdateStatement;
|
||||
|
@ -30,6 +31,7 @@ public class MultiTableUpdateQueryPlan implements NonSelectQueryPlan {
|
|||
|
||||
@Override
|
||||
public int executeUpdate(ExecutionContext executionContext) {
|
||||
BulkOperationCleanupAction.schedule( executionContext, sqmUpdate );
|
||||
return mutationStrategy.executeUpdate( sqmUpdate, domainParameterXref, executionContext );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ package org.hibernate.query.sqm.internal;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.action.internal.BulkOperationCleanupAction;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
|
@ -28,15 +28,14 @@ import org.hibernate.query.sqm.sql.SqmTranslatorFactory;
|
|||
import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||
import org.hibernate.sql.ast.tree.delete.DeleteStatement;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||
import org.hibernate.sql.ast.tree.from.MutatingTableReferenceGroupWrapper;
|
||||
import org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate;
|
||||
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||
import org.hibernate.sql.exec.spi.JdbcDelete;
|
||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||
|
||||
|
@ -90,6 +89,7 @@ public class SimpleDeleteQueryPlan implements NonSelectQueryPlan {
|
|||
|
||||
@Override
|
||||
public int executeUpdate(ExecutionContext executionContext) {
|
||||
BulkOperationCleanupAction.schedule( executionContext, sqmDelete );
|
||||
final SharedSessionContractImplementor session = executionContext.getSession();
|
||||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
final JdbcServices jdbcServices = factory.getJdbcServices();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm.internal;
|
||||
|
||||
import org.hibernate.action.internal.BulkOperationCleanupAction;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
|
@ -78,6 +79,7 @@ public class SimpleInsertQueryPlan implements NonSelectQueryPlan {
|
|||
|
||||
@Override
|
||||
public int executeUpdate(ExecutionContext executionContext) {
|
||||
BulkOperationCleanupAction.schedule( executionContext, sqmInsert );
|
||||
final SharedSessionContractImplementor session = executionContext.getSession();
|
||||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
final JdbcServices jdbcServices = factory.getJdbcServices();
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.query.sqm.internal;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.action.internal.BulkOperationCleanupAction;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
|
@ -51,6 +52,7 @@ public class SimpleUpdateQueryPlan implements NonSelectQueryPlan {
|
|||
|
||||
@Override
|
||||
public int executeUpdate(ExecutionContext executionContext) {
|
||||
BulkOperationCleanupAction.schedule( executionContext, sqmUpdate );
|
||||
final SharedSessionContractImplementor session = executionContext.getSession();
|
||||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
final JdbcServices jdbcServices = factory.getJdbcServices();
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* 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.sql.results.graph.entity.internal;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||
import org.hibernate.query.EntityIdentifierNavigablePath;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.FetchableContainer;
|
||||
import org.hibernate.sql.results.graph.entity.AbstractEntityResultGraphNode;
|
||||
import org.hibernate.sql.results.graph.entity.EntityInitializer;
|
||||
import org.hibernate.sql.results.graph.entity.EntityResult;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
import static org.hibernate.query.results.ResultsHelper.attributeName;
|
||||
|
||||
/**
|
||||
* Selects just the FK and builds a proxy
|
||||
*
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
public class EntityDelayedResultImpl implements DomainResult {
|
||||
|
||||
private final NavigablePath navigablePath;
|
||||
private final EntityAssociationMapping entityValuedModelPart;
|
||||
private final DomainResult identifierResult;
|
||||
|
||||
public EntityDelayedResultImpl(
|
||||
NavigablePath navigablePath,
|
||||
EntityAssociationMapping entityValuedModelPart,
|
||||
TableGroup rootTableGroup,
|
||||
DomainResultCreationState creationState) {
|
||||
this.navigablePath = navigablePath;
|
||||
this.entityValuedModelPart = entityValuedModelPart;
|
||||
this.identifierResult = entityValuedModelPart.getForeignKeyDescriptor()
|
||||
.createDomainResult(
|
||||
navigablePath.append( EntityIdentifierMapping.ROLE_LOCAL_NAME ),
|
||||
rootTableGroup,
|
||||
null,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor getResultJavaTypeDescriptor() {
|
||||
return entityValuedModelPart.getAssociatedEntityMappingType().getMappedJavaTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigablePath getNavigablePath() {
|
||||
return navigablePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResultVariable() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
|
||||
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
|
||||
getNavigablePath(),
|
||||
entityValuedModelPart,
|
||||
() -> new EntityDelayedFetchInitializer(
|
||||
getNavigablePath(),
|
||||
(EntityValuedModelPart) entityValuedModelPart,
|
||||
identifierResult.createResultAssembler( creationState )
|
||||
)
|
||||
);
|
||||
|
||||
return new EntityAssembler( getResultJavaTypeDescriptor(), initializer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EntityDelayedResultImpl {" + getNavigablePath() + "}";
|
||||
}
|
||||
}
|
|
@ -7,11 +7,11 @@
|
|||
package org.hibernate.orm.test.mapping.naturalid.mutable.cached;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.NotImplementedYet;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
|
||||
|
||||
import static org.hibernate.cfg.AvailableSettings.GENERATE_STATISTICS;
|
||||
import static org.hibernate.cfg.AvailableSettings.USE_SECOND_LEVEL_CACHE;
|
||||
import static org.hibernate.testing.cache.CachingRegionFactory.DEFAULT_ACCESSTYPE;
|
||||
|
@ -26,4 +26,5 @@ import static org.hibernate.testing.cache.CachingRegionFactory.DEFAULT_ACCESSTYP
|
|||
@DomainModel( annotatedClasses = {A.class, Another.class, AllCached.class, B.class, SubClass.class} )
|
||||
@SessionFactory
|
||||
public class CachedMutableNaturalIdNonStrictReadWriteTest extends CachedMutableNaturalIdTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -55,28 +55,25 @@ public class CachedMutableNaturalIdStrictReadWriteTest extends CachedMutableNatu
|
|||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-7278" )
|
||||
@NotImplementedYet( reason = "Caching is not yet implemented", strict = false )
|
||||
public void testInsertedNaturalIdCachedAfterTransactionSuccess(SessionFactoryScope scope) {
|
||||
final StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
|
||||
scope.inTransaction(
|
||||
(session) -> session.save( new AllCached( "it" ) )
|
||||
(session) -> session.save( new Another( "it" ) )
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
(session) -> {
|
||||
final Another it = session.bySimpleNaturalId( Another.class ).load( "it" );
|
||||
assertNotNull( it );
|
||||
|
||||
assertEquals( 1, statistics.getNaturalIdCacheHitCount() );
|
||||
}
|
||||
);
|
||||
assertEquals( 1, statistics.getNaturalIdCacheHitCount() );
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-7278" )
|
||||
@NotImplementedYet( reason = "Caching is not yet implemented", strict = false )
|
||||
public void testInsertedNaturalIdNotCachedAfterTransactionFailure(SessionFactoryScope scope) {
|
||||
final StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
|
@ -86,7 +83,7 @@ public class CachedMutableNaturalIdStrictReadWriteTest extends CachedMutableNatu
|
|||
final Transaction transaction = session.getTransaction();
|
||||
transaction.begin();
|
||||
|
||||
session.save( new AllCached( "it" ) );
|
||||
session.save( new Another( "it" ) );
|
||||
session.flush();
|
||||
|
||||
transaction.rollback();
|
||||
|
@ -104,13 +101,12 @@ public class CachedMutableNaturalIdStrictReadWriteTest extends CachedMutableNatu
|
|||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-7278" )
|
||||
@NotImplementedYet( reason = "Caching is not yet implemented", strict = false )
|
||||
public void testChangedNaturalIdCachedAfterTransactionSuccess(SessionFactoryScope scope) {
|
||||
final StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
|
||||
scope.inTransaction(
|
||||
(session) -> session.save( new AllCached( "it" ) )
|
||||
(session) -> session.save( new Another( "it" ) )
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
|
@ -136,13 +132,12 @@ public class CachedMutableNaturalIdStrictReadWriteTest extends CachedMutableNatu
|
|||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-7278" )
|
||||
@NotImplementedYet( reason = "Caching is not yet implemented", strict = false )
|
||||
public void testChangedNaturalIdNotCachedAfterTransactionFailure(SessionFactoryScope scope) {
|
||||
final StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
|
||||
scope.inTransaction(
|
||||
(session) -> session.save( new AllCached( "it" ) )
|
||||
(session) -> session.save( new Another( "it" ) )
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
|
@ -167,13 +162,12 @@ public class CachedMutableNaturalIdStrictReadWriteTest extends CachedMutableNatu
|
|||
assertNotNull( original );
|
||||
}
|
||||
);
|
||||
|
||||
assertEquals( 0, statistics );
|
||||
|
||||
assertEquals(0, statistics.getNaturalIdCacheHitCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-7309" )
|
||||
@NotImplementedYet( reason = "Caching is not yet implemented", strict = false )
|
||||
public void testInsertUpdateEntity_NaturalIdCachedAfterTransactionSuccess(SessionFactoryScope scope) {
|
||||
final StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
|
@ -202,9 +196,8 @@ public class CachedMutableNaturalIdStrictReadWriteTest extends CachedMutableNatu
|
|||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9200" )
|
||||
@NotImplementedYet( reason = "Caching is not yet implemented", strict = false )
|
||||
public void testNaturalIdCacheStatisticsReset(SessionFactoryScope scope) {
|
||||
final String naturalIdCacheRegion = Another.class.getName() + "##NaturalId";
|
||||
final String naturalIdCacheRegion = "hibernate.test." + Another.class.getName() + "##NaturalId";
|
||||
|
||||
final StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
|
|
|
@ -64,7 +64,6 @@ public abstract class CachedMutableNaturalIdTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@NotImplementedYet( reason = "Caching is not yet implemented", strict = false )
|
||||
public void testNaturalIdChangedWhileDetached(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
(session) -> session.save( new Another( "it" ) )
|
||||
|
|
Loading…
Reference in New Issue