Initial working support for selecting a "query root" - i.e.

This commit is contained in:
Andrea Boriero 2019-09-13 18:41:31 +01:00
parent c27c53f619
commit 00267022eb
7 changed files with 92 additions and 34 deletions

View File

@ -36,7 +36,12 @@ public class NamedBasicTypeResolution<J> implements BasicValue.Resolution<J> {
this.basicType = basicType; this.basicType = basicType;
this.valueConverter = valueConverter; this.valueConverter = valueConverter;
this.mutabilityPlan = mutabilityPlan; if ( mutabilityPlan == null ) {
this.mutabilityPlan = domainJtd.getMutabilityPlan();
}
else {
this.mutabilityPlan = mutabilityPlan;
}
} }
@Override @Override

View File

@ -6,6 +6,8 @@
*/ */
package org.hibernate.metamodel.mapping; package org.hibernate.metamodel.mapping;
import org.hibernate.property.access.spi.PropertyAccess;
/** /**
* Describes an attribute at the mapping model level. * Describes an attribute at the mapping model level.
* *
@ -25,4 +27,6 @@ public interface AttributeMapping extends ModelPart, ValueMapping {
return false; return false;
} }
PropertyAccess getPropertyAccess();
} }

View File

@ -14,6 +14,7 @@ import org.hibernate.metamodel.mapping.ManagedMappingType;
import org.hibernate.metamodel.mapping.MappingType; import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.metamodel.mapping.SingularAttributeMapping; import org.hibernate.metamodel.mapping.SingularAttributeMapping;
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess; import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.results.spi.DomainResult; import org.hibernate.sql.results.spi.DomainResult;
@ -28,14 +29,18 @@ public class AbstractSingularAttributeMapping
extends AbstractStateArrayContributorMapping extends AbstractStateArrayContributorMapping
implements SingularAttributeMapping { implements SingularAttributeMapping {
private final PropertyAccess propertyAccess;
public AbstractSingularAttributeMapping( public AbstractSingularAttributeMapping(
String name, String name,
int stateArrayPosition, int stateArrayPosition,
StateArrayContributorMetadataAccess attributeMetadataAccess, StateArrayContributorMetadataAccess attributeMetadataAccess,
FetchStrategy mappedFetchStrategy, FetchStrategy mappedFetchStrategy,
MappingType type, MappingType type,
ManagedMappingType declaringType) { ManagedMappingType declaringType,
PropertyAccess propertyAccess) {
super( name, type, attributeMetadataAccess, mappedFetchStrategy, stateArrayPosition, declaringType ); super( name, type, attributeMetadataAccess, mappedFetchStrategy, stateArrayPosition, declaringType );
this.propertyAccess = propertyAccess;
} }
@Override @Override
@ -57,4 +62,9 @@ public class AbstractSingularAttributeMapping
DomainResultCreationState creationState) { DomainResultCreationState creationState) {
throw new NotYetImplementedFor6Exception( getClass() ); throw new NotYetImplementedFor6Exception( getClass() );
} }
@Override
public PropertyAccess getPropertyAccess() {
return propertyAccess;
}
} }

View File

@ -16,6 +16,7 @@ import org.hibernate.metamodel.mapping.ManagedMappingType;
import org.hibernate.metamodel.mapping.SingularAttributeMapping; import org.hibernate.metamodel.mapping.SingularAttributeMapping;
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess; import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.sql.SqlExpressionResolver; import org.hibernate.query.sqm.sql.SqlExpressionResolver;
import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.Clause;
@ -48,8 +49,9 @@ public class BasicValuedSingularAttributeMapping extends AbstractSingularAttribu
BasicValueConverter valueConverter, BasicValueConverter valueConverter,
BasicType basicType, BasicType basicType,
JdbcMapping jdbcMapping, JdbcMapping jdbcMapping,
ManagedMappingType declaringType) { ManagedMappingType declaringType,
super( attributeName, stateArrayPosition, attributeMetadataAccess, mappedFetchStrategy, basicType, declaringType ); PropertyAccess propertyAccess) {
super( attributeName, stateArrayPosition, attributeMetadataAccess, mappedFetchStrategy, basicType, declaringType, propertyAccess );
this.tableExpression = tableExpression; this.tableExpression = tableExpression;
this.mappedColumnExpression = mappedColumnExpression; this.mappedColumnExpression = mappedColumnExpression;
this.valueConverter = valueConverter; this.valueConverter = valueConverter;

View File

@ -10,6 +10,7 @@ import org.hibernate.engine.FetchStrategy;
import org.hibernate.metamodel.mapping.EntityVersionMapping; import org.hibernate.metamodel.mapping.EntityVersionMapping;
import org.hibernate.metamodel.mapping.ManagedMappingType; import org.hibernate.metamodel.mapping.ManagedMappingType;
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess; import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
/** /**
@ -23,7 +24,8 @@ public class EntityVersionMappingImpl extends BasicValuedSingularAttributeMappin
String containingTableExpression, String containingTableExpression,
String mappedColumnExpression, String mappedColumnExpression,
BasicType basicType, BasicType basicType,
ManagedMappingType declaringType) { ManagedMappingType declaringType,
PropertyAccess propertyAccess) {
super( super(
attributeName, attributeName,
stateArrayPosition, stateArrayPosition,
@ -34,7 +36,8 @@ public class EntityVersionMappingImpl extends BasicValuedSingularAttributeMappin
null, null,
basicType, basicType,
basicType, basicType,
declaringType declaringType,
propertyAccess
); );
} }
} }

View File

@ -92,6 +92,7 @@ import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.PersistenceContext.NaturalIdHelper; import org.hibernate.engine.spi.PersistenceContext.NaturalIdHelper;
import org.hibernate.engine.spi.PersistentAttributeInterceptable; import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.engine.spi.PersistentAttributeInterceptor; import org.hibernate.engine.spi.PersistentAttributeInterceptor;
import org.hibernate.engine.spi.SelfDirtinessTracker;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.engine.spi.ValueInclusion; import org.hibernate.engine.spi.ValueInclusion;
@ -132,6 +133,7 @@ import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.Subclass; import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
import org.hibernate.metadata.ClassMetadata; import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.metamodel.mapping.AttributeMapping; import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.AttributeMetadata; import org.hibernate.metamodel.mapping.AttributeMetadata;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
@ -5197,7 +5199,27 @@ public abstract class AbstractEntityPersister
@Override @Override
public void afterInitialize(Object entity, SharedSessionContractImplementor session) { public void afterInitialize(Object entity, SharedSessionContractImplementor session) {
getEntityTuplizer().afterInitialize( entity, session ); if ( entity instanceof PersistentAttributeInterceptable && getRepresentationStrategy().getMode() == RepresentationMode.POJO ) {
final BytecodeLazyAttributeInterceptor interceptor = getEntityMetamodel().getBytecodeEnhancementMetadata()
.extractLazyInterceptor( entity );
if ( interceptor == null || interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
getEntityMetamodel().getBytecodeEnhancementMetadata().injectInterceptor(
entity,
getIdentifier( entity, session ),
session
);
}
else {
if ( interceptor.getLinkedSession() == null ) {
interceptor.setSession( session );
}
}
}
// clear the fields that are marked as dirty in the dirtyness tracker
if ( entity instanceof SelfDirtinessTracker ) {
( (SelfDirtinessTracker) entity ).$$_hibernate_clearDirtyAttributes();
}
} }
public String[] getPropertyNames() { public String[] getPropertyNames() {
@ -5273,15 +5295,15 @@ public abstract class AbstractEntityPersister
accessOptimizer.setPropertyValues( object, values ); accessOptimizer.setPropertyValues( object, values );
} }
else { else {
visitAttributeMappings( int i = 0;
attributeMapping -> { for ( Map.Entry<String, AttributeMapping> entries : declaredAttributeMappings.entrySet() ) {
final Setter setter = attributeMapping.getAttributeMetadataAccess() AttributeMapping attributeMapping = entries.getValue();
.resolveAttributeMetadata( this ) final Setter setter = attributeMapping
.getPropertyAccess() .getPropertyAccess()
.getSetter(); .getSetter();
setter.set( object, values, getFactory() ); setter.set( object, values[i], getFactory() );
} i++;
); }
} }
} }
@ -5343,9 +5365,10 @@ public abstract class AbstractEntityPersister
@Override @Override
public Object instantiate(Serializable id, SharedSessionContractImplementor session) { public Object instantiate(Serializable id, SharedSessionContractImplementor session) {
final Object entity = getRepresentationStrategy().getInstantiator().instantiate( session ); Object instance = getRepresentationStrategy().getInstantiator().instantiate( session );
setIdentifier( entity, id, session ); identifierMapping.getPropertyAccess().getSetter().set( instance, id, factory );
return entity;
return instance;
} }
@Override @Override
@ -5396,23 +5419,24 @@ public abstract class AbstractEntityPersister
return entityMetamodel.getPropertySpan(); return entityMetamodel.getPropertySpan();
} }
public Object[] getPropertyValuesToInsert( public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SharedSessionContractImplementor session)
Object entity, throws HibernateException {
Map mergeMap,
SharedSessionContractImplementor session) throws HibernateException {
if ( shouldGetAllProperties( entity ) && accessOptimizer != null ) { if ( shouldGetAllProperties( entity ) && accessOptimizer != null ) {
return accessOptimizer.getPropertyValues( entity ); return accessOptimizer.getPropertyValues( entity );
} }
final List<Object> values = new ArrayList<>(); final Object[] result = new Object[declaredAttributeMappings.size()];
int i = 0;
visitAttributeMappings( for ( Map.Entry<String, AttributeMapping> entries : declaredAttributeMappings.entrySet() ) {
attributeMapping -> values.add( AttributeMapping attributeMapping = entries.getValue();
attributeMapping.getAttributeMetadataAccess().resolveAttributeMetadata( this ).getPropertyAccess().getGetter().getForInsert( entity, mergeMap, session ) result[i] = attributeMapping.getPropertyAccess().getGetter().getForInsert(
) entity,
); mergeMap,
session
return values.toArray(); );
i++;
}
return result;
} }
protected boolean shouldGetAllProperties(Object entity) { protected boolean shouldGetAllProperties(Object entity) {
@ -6240,6 +6264,8 @@ public abstract class AbstractEntityPersister
? new FetchStrategy( FetchTiming.DELAYED, FetchStyle.SELECT ) ? new FetchStrategy( FetchTiming.DELAYED, FetchStyle.SELECT )
: FetchStrategy.IMMEDIATE_JOIN; : FetchStrategy.IMMEDIATE_JOIN;
final PropertyAccess propertyAccess = getRepresentationStrategy()
.resolvePropertyAccess( bootProperty );
if ( valueConverter != null ) { if ( valueConverter != null ) {
// we want to "decompose" the "type" into its various pieces as expected by the mapping // we want to "decompose" the "type" into its various pieces as expected by the mapping
assert valueConverter.getRelationalJavaDescriptor() == resolution.getRelationalJavaDescriptor(); assert valueConverter.getRelationalJavaDescriptor() == resolution.getRelationalJavaDescriptor();
@ -6250,6 +6276,7 @@ public abstract class AbstractEntityPersister
.getBasicTypeRegistry() .getBasicTypeRegistry()
.resolve( valueConverter.getRelationalJavaDescriptor(), resolution.getRelationalSqlTypeDescriptor() ); .resolve( valueConverter.getRelationalJavaDescriptor(), resolution.getRelationalSqlTypeDescriptor() );
return new BasicValuedSingularAttributeMapping( return new BasicValuedSingularAttributeMapping(
attrName, attrName,
stateArrayPosition, stateArrayPosition,
@ -6260,7 +6287,8 @@ public abstract class AbstractEntityPersister
valueConverter, valueConverter,
mappingBasicType, mappingBasicType,
mappingBasicType.getJdbcMapping(), mappingBasicType.getJdbcMapping(),
declaringType declaringType,
propertyAccess
); );
} }
else { else {
@ -6274,7 +6302,8 @@ public abstract class AbstractEntityPersister
null, null,
(BasicType) attrType, (BasicType) attrType,
(BasicType) attrType, (BasicType) attrType,
declaringType declaringType,
propertyAccess
); );
} }
} }

View File

@ -112,6 +112,11 @@ public class SmokeTests {
); );
List<SimpleEntity> simpleEntities = query.list(); List<SimpleEntity> simpleEntities = query.list();
assertThat( simpleEntities.size(), is( 1 ) ); assertThat( simpleEntities.size(), is( 1 ) );
SimpleEntity simpleEntity = simpleEntities.get( 0 );
assertThat( simpleEntity.getId(), is(1) );
assertThat( simpleEntity.getGender(), is(FEMALE) );
assertThat( simpleEntity.getGender2(), is(MALE) );
assertThat( simpleEntity.getName(), is("Fab") );
} }
); );
} }