ResultSet mapping
- Basic working support for `@EntityResult`
This commit is contained in:
parent
b1e8f64bda
commit
4ad246536f
|
@ -6,8 +6,11 @@
|
|||
*/
|
||||
package org.hibernate.boot.query;
|
||||
|
||||
import org.hibernate.query.internal.FetchMappingMemento;
|
||||
import org.hibernate.query.EntityIdentifierNavigablePath;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.named.FetchMemento;
|
||||
import org.hibernate.query.internal.ResultSetMappingResolutionContext;
|
||||
import org.hibernate.query.named.ResultMemento;
|
||||
|
||||
/**
|
||||
* Describes the mapping for a fetch as part of a {@link NamedResultSetMappingDescriptor}
|
||||
|
@ -17,5 +20,9 @@ public interface FetchDescriptor {
|
|||
* Resolve the descriptor into a memento capable of being stored in the
|
||||
* {@link org.hibernate.query.named.NamedQueryRepository}
|
||||
*/
|
||||
FetchMappingMemento resolve(ResultSetMappingResolutionContext resolutionContext);
|
||||
FetchMemento resolve(ResultSetMappingResolutionContext resolutionContext);
|
||||
|
||||
ResultMemento asResultMemento(
|
||||
NavigablePath path,
|
||||
ResultSetMappingResolutionContext resolutionContext);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import java.util.List;
|
|||
import org.hibernate.LockMode;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.query.internal.ResultSetMappingResolutionContext;
|
||||
import org.hibernate.query.internal.ScalarResultMappingMemento;
|
||||
import org.hibernate.query.internal.ResultMementoBasicStandard;
|
||||
import org.hibernate.query.named.NamedResultSetMappingMemento;
|
||||
import org.hibernate.type.BasicType;
|
||||
|
||||
|
@ -58,7 +58,7 @@ public class HbmResultSetMappingDescriptor implements NamedResultSetMappingDescr
|
|||
|
||||
@Override
|
||||
public NamedResultSetMappingMemento resolve(ResultSetMappingResolutionContext resolutionContext) {
|
||||
final List<ScalarResultMappingMemento> scalarResultMementos;
|
||||
final List<ResultMementoBasicStandard> scalarResultMementos;
|
||||
if ( scalarResultMappings == null || scalarResultMappings.isEmpty() ) {
|
||||
scalarResultMementos = Collections.emptyList();
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ public class HbmResultSetMappingDescriptor implements NamedResultSetMappingDescr
|
|||
}
|
||||
|
||||
@Override
|
||||
public ScalarResultMappingMemento resolve(ResultSetMappingResolutionContext resolutionContext) {
|
||||
public ResultMementoBasicStandard resolve(ResultSetMappingResolutionContext resolutionContext) {
|
||||
if ( hibernateTypeName != null ) {
|
||||
final BasicType<?> namedType = resolutionContext.getSessionFactory()
|
||||
.getTypeConfiguration()
|
||||
|
@ -159,12 +159,12 @@ public class HbmResultSetMappingDescriptor implements NamedResultSetMappingDescr
|
|||
throw new IllegalArgumentException( "Could not resolve named type : " + hibernateTypeName );
|
||||
}
|
||||
|
||||
return new ScalarResultMappingMemento( columnName, namedType, resolutionContext );
|
||||
return new ResultMementoBasicStandard( columnName, namedType, resolutionContext );
|
||||
}
|
||||
|
||||
// todo (6.0) : column name may be optional in HBM - double check
|
||||
|
||||
return new ScalarResultMappingMemento( columnName, null, resolutionContext );
|
||||
return new ResultMementoBasicStandard( columnName, null, resolutionContext );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.boot.query;
|
||||
|
||||
import org.hibernate.query.internal.FetchMappingMemento;
|
||||
import org.hibernate.query.internal.ResultMappingMemento;
|
||||
import org.hibernate.query.internal.ResultSetMappingResolutionContext;
|
||||
import org.hibernate.query.named.NamedResultSetMappingMemento;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.boot.query;
|
||||
|
||||
import org.hibernate.query.internal.ResultMappingMemento;
|
||||
import org.hibernate.query.named.ResultMemento;
|
||||
import org.hibernate.query.internal.ResultSetMappingResolutionContext;
|
||||
|
||||
/**
|
||||
|
@ -19,5 +19,5 @@ public interface ResultDescriptor {
|
|||
* Resolve the descriptor into a memento capable of being stored in the
|
||||
* {@link org.hibernate.query.named.NamedQueryRepository}
|
||||
*/
|
||||
ResultMappingMemento resolve(ResultSetMappingResolutionContext resolutionContext);
|
||||
ResultMemento resolve(ResultSetMappingResolutionContext resolutionContext);
|
||||
}
|
||||
|
|
|
@ -17,26 +17,35 @@ import javax.persistence.EntityResult;
|
|||
import javax.persistence.FieldResult;
|
||||
import javax.persistence.SqlResultSetMapping;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.boot.BootLogging;
|
||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.util.MutableObject;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.RuntimeMetamodels;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.internal.SingleAttributeIdentifierMapping;
|
||||
import org.hibernate.query.EntityIdentifierNavigablePath;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.internal.BasicFetchMemento;
|
||||
import org.hibernate.query.internal.EntityResultMappingMemento;
|
||||
import org.hibernate.query.internal.FetchMappingMemento;
|
||||
import org.hibernate.query.internal.InstantiationResultMappingMemento;
|
||||
import org.hibernate.query.internal.InstantiationResultMappingMemento.ArgumentMemento;
|
||||
import org.hibernate.query.internal.FetchMementoBasicStandard;
|
||||
import org.hibernate.query.internal.ModelPartResultMementoBasicImpl;
|
||||
import org.hibernate.query.internal.NamedResultSetMappingMementoImpl;
|
||||
import org.hibernate.query.internal.ResultMappingMemento;
|
||||
import org.hibernate.query.internal.ResultMementoBasicStandard;
|
||||
import org.hibernate.query.internal.ResultMementoEntityStandard;
|
||||
import org.hibernate.query.internal.ResultMementoInstantiationStandard;
|
||||
import org.hibernate.query.internal.ResultSetMappingResolutionContext;
|
||||
import org.hibernate.query.internal.ScalarResultMappingMemento;
|
||||
import org.hibernate.query.named.FetchMemento;
|
||||
import org.hibernate.query.named.ModelPartResultMementoBasic;
|
||||
import org.hibernate.query.named.NamedResultSetMappingMemento;
|
||||
import org.hibernate.query.named.ResultMemento;
|
||||
import org.hibernate.query.named.ResultMementoBasic;
|
||||
import org.hibernate.query.named.ResultMementoInstantiation.ArgumentMemento;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
/**
|
||||
|
@ -74,7 +83,7 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
|
|||
for ( int i = 0; i < entityResults.length; i++ ) {
|
||||
final EntityResult entityResult = entityResults[i];
|
||||
resultDescriptors.add(
|
||||
EntityResultDescriptor.from( entityResult, context )
|
||||
new EntityResultDescriptor( entityResult, mappingAnnotation, context )
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -117,7 +126,7 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
|
|||
|
||||
@Override
|
||||
public NamedResultSetMappingMemento resolve(ResultSetMappingResolutionContext resolutionContext) {
|
||||
final List<ResultMappingMemento> resultMementos = CollectionHelper.arrayList( resultDescriptors.size() );
|
||||
final List<ResultMemento> resultMementos = CollectionHelper.arrayList( resultDescriptors.size() );
|
||||
|
||||
resultDescriptors.forEach(
|
||||
resultDescriptor -> resultMementos.add( resultDescriptor.resolve( resolutionContext ) )
|
||||
|
@ -142,14 +151,14 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
|
|||
}
|
||||
|
||||
@Override
|
||||
public ResultMappingMemento resolve(ResultSetMappingResolutionContext resolutionContext) {
|
||||
public ResultMemento resolve(ResultSetMappingResolutionContext resolutionContext) {
|
||||
BootLogging.LOGGER.debugf(
|
||||
"Generating ScalarResultMappingMemento for JPA ColumnResult(%s) for ResultSet mapping `%s`",
|
||||
columnResult.name(),
|
||||
mappingName
|
||||
);
|
||||
|
||||
return new ScalarResultMappingMemento( columnResult, resolutionContext );
|
||||
return new ResultMementoBasicStandard( columnResult, resolutionContext );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,7 +206,7 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
|
|||
}
|
||||
|
||||
@Override
|
||||
public ResultMappingMemento resolve(ResultSetMappingResolutionContext resolutionContext) {
|
||||
public ResultMemento resolve(ResultSetMappingResolutionContext resolutionContext) {
|
||||
BootLogging.LOGGER.debugf(
|
||||
"Generating InstantiationResultMappingMemento for JPA ConstructorResult(%s) for ResultSet mapping `%s`",
|
||||
targetJavaType.getName(),
|
||||
|
@ -215,7 +224,7 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
|
|||
.getJavaTypeDescriptorRegistry()
|
||||
.getDescriptor( targetJavaType );
|
||||
|
||||
return new InstantiationResultMappingMemento( targetJtd, argumentResultMementos );
|
||||
return new ResultMementoInstantiationStandard( targetJtd, argumentResultMementos );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,17 +232,25 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
|
|||
* @see javax.persistence.EntityResult
|
||||
*/
|
||||
public static class EntityResultDescriptor implements ResultDescriptor {
|
||||
private final NavigablePath navigablePath;
|
||||
private String resultSetMappingName;
|
||||
|
||||
private final NavigablePath navigablePath;
|
||||
private final String entityName;
|
||||
private final String discriminatorColumn;
|
||||
|
||||
private final Map<String, AttributeFetchDescriptor> fetchMappings;
|
||||
|
||||
public static EntityResultDescriptor from(EntityResult entityResult, MetadataBuildingContext context) {
|
||||
final String entityName = entityResult.entityClass().getName();
|
||||
public EntityResultDescriptor(
|
||||
EntityResult entityResult,
|
||||
SqlResultSetMapping mappingAnnotation,
|
||||
MetadataBuildingContext context) {
|
||||
this.resultSetMappingName = mappingAnnotation.name();
|
||||
this.entityName = entityResult.entityClass().getName();
|
||||
this.discriminatorColumn = entityResult.discriminatorColumn();
|
||||
|
||||
final Map<String, AttributeFetchDescriptor> fetchMappings = new HashMap<>();
|
||||
this.navigablePath = new NavigablePath( entityName );
|
||||
|
||||
this.fetchMappings = new HashMap<>();
|
||||
for ( int i = 0; i < entityResult.fields().length; i++ ) {
|
||||
final FieldResult fieldResult = entityResult.fields()[ i ];
|
||||
final AttributeFetchDescriptor existing = fetchMappings.get( fieldResult.name() );
|
||||
|
@ -243,62 +260,107 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
|
|||
else {
|
||||
fetchMappings.put(
|
||||
fieldResult.name(),
|
||||
AttributeFetchDescriptor.from( entityName, fieldResult, context )
|
||||
AttributeFetchDescriptor.from( navigablePath, entityName, fieldResult, context )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return new EntityResultDescriptor(
|
||||
entityName,
|
||||
entityResult.discriminatorColumn(),
|
||||
fetchMappings
|
||||
);
|
||||
}
|
||||
|
||||
public EntityResultDescriptor(
|
||||
String entityName,
|
||||
String discriminatorColumn,
|
||||
Map<String, AttributeFetchDescriptor> fetchMappings) {
|
||||
this.navigablePath = new NavigablePath( entityName );
|
||||
|
||||
this.entityName = entityName;
|
||||
this.discriminatorColumn = discriminatorColumn;
|
||||
|
||||
this.fetchMappings = fetchMappings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultMappingMemento resolve(ResultSetMappingResolutionContext resolutionContext) {
|
||||
public ResultMemento resolve(ResultSetMappingResolutionContext resolutionContext) {
|
||||
final RuntimeMetamodels runtimeMetamodels = resolutionContext.getSessionFactory().getRuntimeMetamodels();
|
||||
final EntityMappingType entityDescriptor = runtimeMetamodels.getEntityMappingType( entityName );
|
||||
final EntityIdentifierMapping identifierMapping = entityDescriptor.getIdentifierMapping();
|
||||
final String identifierAttributeName = identifierMapping instanceof SingleAttributeIdentifierMapping
|
||||
? ( (SingleAttributeIdentifierMapping) identifierMapping ).getAttributeName()
|
||||
: EntityIdentifierMapping.ROLE_LOCAL_NAME;
|
||||
|
||||
final Map<String, FetchMappingMemento> fetchMementos = new HashMap<>();
|
||||
fetchMappings.forEach(
|
||||
(attrName, attrMapping) -> fetchMementos.put( attrName, attrMapping.resolve( resolutionContext ) )
|
||||
final MutableObject<ResultMemento> identifierMementoReference = new MutableObject<>();
|
||||
|
||||
final ResultMementoBasic discriminatorMemento = resolveDiscriminatorMemento(
|
||||
entityDescriptor,
|
||||
discriminatorColumn,
|
||||
navigablePath
|
||||
);
|
||||
|
||||
return new EntityResultMappingMemento( entityDescriptor, discriminatorColumn, fetchMementos );
|
||||
final Map<String, FetchMemento> fetchMementos = new HashMap<>();
|
||||
fetchMappings.forEach(
|
||||
(attrName, attrMapping) -> {
|
||||
if ( EntityIdentifierMapping.ROLE_LOCAL_NAME.equals( attrName )
|
||||
|| identifierAttributeName.equals( attrName ) ) {
|
||||
final EntityIdentifierNavigablePath idPath = new EntityIdentifierNavigablePath( navigablePath );
|
||||
identifierMementoReference.set( attrMapping.asResultMemento( idPath, resolutionContext ) );
|
||||
}
|
||||
else {
|
||||
fetchMementos.put( attrName, attrMapping.resolve( resolutionContext ) );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if ( identifierMementoReference.isNotSet() ) {
|
||||
throw new IllegalStateException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"Entity identifier mapping not specified for @EntityResult(%s) for ResultSet mapping `%s`",
|
||||
entityDescriptor.getEntityName(),
|
||||
resultSetMappingName
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return new ResultMementoEntityStandard(
|
||||
entityDescriptor,
|
||||
LockMode.READ,
|
||||
identifierMementoReference.get(),
|
||||
discriminatorMemento,
|
||||
fetchMementos
|
||||
);
|
||||
}
|
||||
|
||||
private static ModelPartResultMementoBasic resolveDiscriminatorMemento(
|
||||
EntityMappingType entityMapping,
|
||||
String discriminatorColumn,
|
||||
NavigablePath entityPath) {
|
||||
final EntityDiscriminatorMapping discriminatorMapping = entityMapping.getDiscriminatorMapping();
|
||||
if ( discriminatorMapping == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ModelPartResultMementoBasicImpl(
|
||||
entityPath.append( EntityDiscriminatorMapping.ROLE_NAME ),
|
||||
discriminatorMapping,
|
||||
discriminatorColumn
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static class AttributeFetchDescriptor implements FetchDescriptor {
|
||||
|
||||
private static AttributeFetchDescriptor from(
|
||||
NavigablePath entityPath,
|
||||
String entityName,
|
||||
FieldResult fieldResult,
|
||||
MetadataBuildingContext context) {
|
||||
return new AttributeFetchDescriptor(
|
||||
entityPath.append( fieldResult.name() ),
|
||||
entityName,
|
||||
fieldResult.name(),
|
||||
fieldResult.column()
|
||||
);
|
||||
}
|
||||
|
||||
private final NavigablePath navigablePath;
|
||||
|
||||
private final String entityName;
|
||||
private final String attributeName;
|
||||
private final List<String> columnNames;
|
||||
|
||||
private AttributeFetchDescriptor(String entityName, String attributeName, String columnName) {
|
||||
private AttributeFetchDescriptor(
|
||||
NavigablePath attributePath,
|
||||
String entityName,
|
||||
String attributeName,
|
||||
String columnName) {
|
||||
this.navigablePath = attributePath;
|
||||
this.entityName = entityName;
|
||||
this.attributeName = attributeName;
|
||||
this.columnNames = new ArrayList<>();
|
||||
|
@ -322,7 +384,9 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
|
|||
}
|
||||
|
||||
@Override
|
||||
public FetchMappingMemento resolve(ResultSetMappingResolutionContext resolutionContext) {
|
||||
public ResultMemento asResultMemento(
|
||||
NavigablePath path,
|
||||
ResultSetMappingResolutionContext resolutionContext) {
|
||||
final RuntimeMetamodels runtimeMetamodels = resolutionContext.getSessionFactory().getRuntimeMetamodels();
|
||||
final EntityMappingType entityMapping = runtimeMetamodels.getEntityMappingType( entityName );
|
||||
|
||||
|
@ -336,7 +400,34 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
|
|||
assert columnNames.size() == 1;
|
||||
final BasicValuedModelPart basicPart = (BasicValuedModelPart) subPart;
|
||||
|
||||
return new BasicFetchMemento( basicPart, columnNames.get( 0 ) );
|
||||
return new ModelPartResultMementoBasicImpl( path, basicPart, columnNames.get( 0 ) );
|
||||
}
|
||||
|
||||
throw new NotYetImplementedFor6Exception(
|
||||
"Only support for basic-valued model-parts have been implemented : " + attributeName + " [" + subPart + "]"
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FetchMemento resolve(ResultSetMappingResolutionContext resolutionContext) {
|
||||
final RuntimeMetamodels runtimeMetamodels = resolutionContext.getSessionFactory().getRuntimeMetamodels();
|
||||
final EntityMappingType entityMapping = runtimeMetamodels.getEntityMappingType( entityName );
|
||||
|
||||
final ModelPart subPart = entityMapping.findSubPart( attributeName, null );
|
||||
|
||||
if ( subPart == null ) {
|
||||
// throw an exception
|
||||
}
|
||||
|
||||
if ( subPart instanceof BasicValuedModelPart ) {
|
||||
assert columnNames.size() == 1;
|
||||
final BasicValuedModelPart basicPart = (BasicValuedModelPart) subPart;
|
||||
|
||||
return new FetchMementoBasicStandard(
|
||||
navigablePath,
|
||||
basicPart,
|
||||
columnNames.get( 0 )
|
||||
);
|
||||
}
|
||||
|
||||
throw new NotYetImplementedFor6Exception(
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
*/
|
||||
package org.hibernate.internal.util;
|
||||
|
||||
/**
|
||||
* A more performant version of {@link java.util.concurrent.atomic.AtomicLong} in cases
|
||||
* where we do not have to worry about concurrency. So usually as a variable referenced in
|
||||
* anonymous-inner or lambda or ...
|
||||
*
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public class MutableLong {
|
||||
private long value;
|
||||
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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.internal.util;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Mutable object reference. Mainly useful with anonymous code blocks
|
||||
* and lambdas.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public class MutableObject<T> {
|
||||
private T reference;
|
||||
|
||||
public T get() {
|
||||
return reference;
|
||||
}
|
||||
|
||||
public boolean isSet() {
|
||||
return reference != null;
|
||||
}
|
||||
|
||||
public boolean isNotSet() {
|
||||
return reference == null;
|
||||
}
|
||||
|
||||
public void set(T reference) {
|
||||
this.reference = reference;
|
||||
}
|
||||
|
||||
public void set(T reference, Consumer<T> existingConsumer) {
|
||||
if ( this.reference != null ) {
|
||||
existingConsumer.accept( this.reference );
|
||||
}
|
||||
|
||||
this.reference = reference;
|
||||
}
|
||||
|
||||
public void setIfNot(T reference) {
|
||||
if ( this.reference == null ) {
|
||||
this.reference = reference;
|
||||
}
|
||||
}
|
||||
|
||||
public void setIfNot(T reference, Supplier<RuntimeException> overwriteHandler) {
|
||||
if ( this.reference == null ) {
|
||||
this.reference = reference;
|
||||
}
|
||||
else {
|
||||
throw overwriteHandler.get();
|
||||
}
|
||||
}
|
||||
|
||||
public void setIfNot(Supplier<T> referenceSupplier) {
|
||||
if ( this.reference == null ) {
|
||||
this.reference = referenceSupplier.get();
|
||||
}
|
||||
}
|
||||
|
||||
public void setIfNot(Supplier<T> referenceSupplier, Supplier<RuntimeException> overwriteHandler) {
|
||||
if ( this.reference == null ) {
|
||||
this.reference = referenceSupplier.get();
|
||||
}
|
||||
else {
|
||||
throw overwriteHandler.get();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -40,7 +40,7 @@ import static org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer.UNFETCH
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface EntityMappingType extends ManagedMappingType, Loadable {
|
||||
public interface EntityMappingType extends ManagedMappingType, EntityValuedModelPart, Loadable {
|
||||
/**
|
||||
* Safety-net.
|
||||
*
|
||||
|
|
|
@ -50,23 +50,29 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
* @author Andrea Boriero
|
||||
*/
|
||||
public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMapping, FetchOptions {
|
||||
|
||||
private final NavigableRole idRole;
|
||||
private final String attributeName;
|
||||
|
||||
private final PropertyAccess propertyAccess;
|
||||
private final EntityPersister entityPersister;
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
private final NavigableRole idRole;
|
||||
|
||||
private final String rootTable;
|
||||
private final String pkColumnName;
|
||||
|
||||
private final BasicType idType;
|
||||
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
public BasicEntityIdentifierMappingImpl(
|
||||
EntityPersister entityPersister,
|
||||
String attributeName,
|
||||
String rootTable,
|
||||
String pkColumnName,
|
||||
BasicType idType,
|
||||
MappingModelCreationProcess creationProcess
|
||||
) {
|
||||
assert entityPersister.hasIdentifierProperty();
|
||||
assert entityPersister.getIdentifierPropertyName() != null;
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
assert attributeName != null;
|
||||
this.attributeName = attributeName;
|
||||
this.rootTable = rootTable;
|
||||
this.pkColumnName = pkColumnName;
|
||||
this.idType = idType;
|
||||
|
@ -88,6 +94,11 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
|
|||
return propertyAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttributeName() {
|
||||
return attributeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getIdentifier(Object entity, SharedSessionContractImplementor session) {
|
||||
if ( entity instanceof HibernateProxy ) {
|
||||
|
|
|
@ -17,4 +17,6 @@ public interface SingleAttributeIdentifierMapping extends EntityIdentifierMappin
|
|||
* Access to the identifier attribute's PropertyAccess
|
||||
*/
|
||||
PropertyAccess getPropertyAccess();
|
||||
|
||||
String getAttributeName();
|
||||
}
|
||||
|
|
|
@ -14,9 +14,7 @@ import org.hibernate.mapping.ManyToOne;
|
|||
import org.hibernate.mapping.OneToOne;
|
||||
import org.hibernate.mapping.ToOne;
|
||||
import org.hibernate.metamodel.mapping.AssociationKey;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
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.ManagedMappingType;
|
||||
|
@ -227,6 +225,8 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
|
|||
|
||||
if ( creationState.isAssociationKeyVisited( associationKey ) ) {
|
||||
NavigablePath parentNavigablePath = fetchablePath.getParent();
|
||||
assert parentNavigablePath.equals( fetchParent.getNavigablePath() );
|
||||
|
||||
ModelPart modelPart = creationState.resolveModelPart( parentNavigablePath );
|
||||
if ( modelPart instanceof EmbeddedIdentifierMappingImpl ) {
|
||||
while ( parentNavigablePath instanceof EntityIdentifierNavigablePath ) {
|
||||
|
@ -235,6 +235,7 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
|
|||
}
|
||||
while ( modelPart instanceof EmbeddableValuedFetchable ) {
|
||||
parentNavigablePath = parentNavigablePath.getParent();
|
||||
assert parentNavigablePath != null;
|
||||
modelPart = creationState.resolveModelPart( parentNavigablePath );
|
||||
}
|
||||
|
||||
|
|
|
@ -6068,6 +6068,7 @@ public abstract class AbstractEntityPersister
|
|||
|
||||
return new BasicEntityIdentifierMappingImpl(
|
||||
this,
|
||||
bootEntityDescriptor.getIdentifierProperty().getName(),
|
||||
getTableName(),
|
||||
rootTableKeyColumnNames[0],
|
||||
(BasicType) idType,
|
||||
|
|
|
@ -77,7 +77,7 @@ import org.hibernate.type.VersionType;
|
|||
* @see org.hibernate.persister.spi.PersisterFactory
|
||||
* @see org.hibernate.persister.spi.PersisterClassResolver
|
||||
*/
|
||||
public interface EntityPersister extends EntityDefinition, EntityValuedModelPart, InFlightEntityMappingType, Loadable, RootTableGroupProducer {
|
||||
public interface EntityPersister extends EntityDefinition, InFlightEntityMappingType, Loadable, RootTableGroupProducer {
|
||||
|
||||
/**
|
||||
* The property name of the "special" identifier property in HQL
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.hibernate.graph.GraphSemantic;
|
|||
import org.hibernate.graph.RootGraph;
|
||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.model.domain.AllowableParameterType;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
@ -84,7 +85,7 @@ public class ProcedureCallImpl<R>
|
|||
private final ProcedureParameterMetadataImpl parameterMetadata;
|
||||
private final ProcedureParamBindings paramBindings;
|
||||
|
||||
private final ResultSetMapping resultSetMapping = new ResultSetMappingImpl();
|
||||
private final ResultSetMapping resultSetMapping;
|
||||
|
||||
private Set<String> synchronizedQuerySpaces;
|
||||
|
||||
|
@ -106,6 +107,8 @@ public class ProcedureCallImpl<R>
|
|||
this.parameterMetadata = new ProcedureParameterMetadataImpl();
|
||||
this.paramBindings = new ProcedureParamBindings( parameterMetadata, getSessionFactory() );
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( procedureName );
|
||||
|
||||
this.synchronizedQuerySpaces = null;
|
||||
}
|
||||
/**
|
||||
|
@ -127,6 +130,10 @@ public class ProcedureCallImpl<R>
|
|||
|
||||
this.synchronizedQuerySpaces = new HashSet<>();
|
||||
|
||||
final String mappingId = procedureName + ":" + StringHelper.join( ",", resultClasses );
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( mappingId );
|
||||
|
||||
Util.resolveResultSetMappingClasses(
|
||||
resultClasses,
|
||||
resultSetMapping,
|
||||
|
@ -157,6 +164,9 @@ public class ProcedureCallImpl<R>
|
|||
|
||||
this.synchronizedQuerySpaces = new HashSet<>();
|
||||
|
||||
final String mappingId = procedureName + ":" + StringHelper.join( ",", resultSetMappingNames );
|
||||
this.resultSetMapping = new ResultSetMappingImpl( mappingId );
|
||||
|
||||
Util.resolveResultSetMappingNames(
|
||||
resultSetMappingNames,
|
||||
resultSetMapping,
|
||||
|
@ -181,6 +191,8 @@ public class ProcedureCallImpl<R>
|
|||
|
||||
this.synchronizedQuerySpaces = CollectionHelper.makeCopy( memento.getQuerySpaces() );
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( memento.getRegistrationName() );
|
||||
|
||||
Util.resolveResultSetMappings(
|
||||
memento.getResultSetMappingNames(),
|
||||
memento.getResultSetMappingClasses(),
|
||||
|
@ -211,6 +223,9 @@ public class ProcedureCallImpl<R>
|
|||
|
||||
this.synchronizedQuerySpaces = CollectionHelper.makeCopy( memento.getQuerySpaces() );
|
||||
|
||||
final String mappingId = procedureName + ":" + StringHelper.join( ",", resultTypes );
|
||||
this.resultSetMapping = new ResultSetMappingImpl( mappingId );
|
||||
|
||||
Util.resolveResultSetMappings(
|
||||
null,
|
||||
resultTypes,
|
||||
|
@ -235,6 +250,9 @@ public class ProcedureCallImpl<R>
|
|||
|
||||
this.synchronizedQuerySpaces = CollectionHelper.makeCopy( memento.getQuerySpaces() );
|
||||
|
||||
final String mappingId = procedureName + ":" + StringHelper.join( ",", resultSetMappingNames );
|
||||
this.resultSetMapping = new ResultSetMappingImpl( mappingId );
|
||||
|
||||
Util.resolveResultSetMappings(
|
||||
resultSetMappingNames,
|
||||
null,
|
||||
|
|
|
@ -1,61 +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.query.internal;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.results.ResultBuilder;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EntityResultMappingMemento implements ResultMappingMemento, FetchMappingMemento.Parent {
|
||||
private final NavigablePath navigablePath;
|
||||
private final EntityMappingType entityDescriptor;
|
||||
private final String discriminatorColumnAlias;
|
||||
private final Map<String,FetchMappingMemento> fetchMementoMap;
|
||||
|
||||
public EntityResultMappingMemento(
|
||||
EntityMappingType entityDescriptor,
|
||||
String discriminatorColumnAlias,
|
||||
Map<String, FetchMappingMemento> fetchMementoMap) {
|
||||
this.navigablePath = new NavigablePath( entityDescriptor.getEntityName() );
|
||||
this.entityDescriptor = entityDescriptor;
|
||||
this.discriminatorColumnAlias = discriminatorColumnAlias;
|
||||
this.fetchMementoMap = fetchMementoMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigablePath getNavigablePath() {
|
||||
return navigablePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedMappingType getMappingType() {
|
||||
return entityDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultBuilder resolve(
|
||||
Consumer<String> querySpaceConsumer,
|
||||
ResultSetMappingResolutionContext context) {
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
// final Map<String, FetchBuilder> fetchBuilderMap = new HashMap<>();
|
||||
// fetchMementoMap.forEach(
|
||||
// (fetchableName, memento) -> fetchBuilderMap.put(
|
||||
// fetchableName,
|
||||
// memento.resolve( this, querySpaceConsumer, context )
|
||||
// )
|
||||
// );
|
||||
// return new DynamicResultBuilderEntityStandard( entityDescriptor, null, discriminatorColumnAlias, fetchBuilderMap );
|
||||
}
|
||||
}
|
|
@ -9,6 +9,10 @@ package org.hibernate.query.internal;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.MappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.named.FetchMementoBasic;
|
||||
import org.hibernate.query.results.FetchBuilder;
|
||||
import org.hibernate.query.results.complete.CompleteFetchBuilderBasicPart;
|
||||
|
||||
|
@ -18,20 +22,40 @@ import org.hibernate.query.results.complete.CompleteFetchBuilderBasicPart;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BasicFetchMemento implements FetchMappingMemento {
|
||||
public class FetchMementoBasicStandard implements FetchMementoBasic {
|
||||
private final NavigablePath navigablePath;
|
||||
private final BasicValuedModelPart fetchedAttribute;
|
||||
private final String columnAlias;
|
||||
|
||||
public BasicFetchMemento(BasicValuedModelPart fetchedAttribute, String columnAlias) {
|
||||
public FetchMementoBasicStandard(
|
||||
NavigablePath navigablePath,
|
||||
BasicValuedModelPart fetchedAttribute,
|
||||
String columnAlias) {
|
||||
this.navigablePath = navigablePath;
|
||||
this.fetchedAttribute = fetchedAttribute;
|
||||
this.columnAlias = columnAlias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigablePath getNavigablePath() {
|
||||
return navigablePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelPart getReferencedModelPart() {
|
||||
return fetchedAttribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingType getMappingType() {
|
||||
return fetchedAttribute.getPartMappingType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FetchBuilder resolve(
|
||||
Parent parent,
|
||||
Consumer<String> querySpaceConsumer,
|
||||
ResultSetMappingResolutionContext context) {
|
||||
return new CompleteFetchBuilderBasicPart( fetchedAttribute, columnAlias );
|
||||
return new CompleteFetchBuilderBasicPart( navigablePath, fetchedAttribute, columnAlias );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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.query.internal;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.named.ModelPartResultMementoBasic;
|
||||
import org.hibernate.query.results.ResultBuilderBasicValued;
|
||||
import org.hibernate.query.results.complete.CompleteResultBuilderBasicModelPart;
|
||||
import org.hibernate.query.results.complete.CompleteResultBuilderBasicValuedStandard;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ModelPartResultMementoBasicImpl implements ModelPartResultMementoBasic {
|
||||
private final NavigablePath navigablePath;
|
||||
private final BasicValuedModelPart modelPart;
|
||||
private final String columnName;
|
||||
|
||||
public ModelPartResultMementoBasicImpl(
|
||||
NavigablePath navigablePath,
|
||||
BasicValuedModelPart modelPart,
|
||||
String columnName) {
|
||||
this.navigablePath = navigablePath;
|
||||
this.modelPart = modelPart;
|
||||
this.columnName = columnName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigablePath getNavigablePath() {
|
||||
return navigablePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicValuedModelPart getReferencedModelPart() {
|
||||
return modelPart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultBuilderBasicValued resolve(
|
||||
Consumer<String> querySpaceConsumer,
|
||||
ResultSetMappingResolutionContext context) {
|
||||
return new CompleteResultBuilderBasicModelPart( navigablePath, modelPart, columnName );
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import java.util.List;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.query.named.NamedResultSetMappingMemento;
|
||||
import org.hibernate.query.named.ResultMemento;
|
||||
import org.hibernate.query.results.ResultSetMapping;
|
||||
|
||||
/**
|
||||
|
@ -19,13 +20,13 @@ import org.hibernate.query.results.ResultSetMapping;
|
|||
*/
|
||||
public class NamedResultSetMappingMementoImpl implements NamedResultSetMappingMemento {
|
||||
private final String name;
|
||||
private final List<ResultMappingMemento> resultMappingMementos;
|
||||
private final List<ResultMemento> resultMementos;
|
||||
|
||||
public NamedResultSetMappingMementoImpl(
|
||||
String name,
|
||||
List<ResultMappingMemento> resultMappingMementos) {
|
||||
List<ResultMemento> resultMementos) {
|
||||
this.name = name;
|
||||
this.resultMappingMementos = resultMappingMementos;
|
||||
this.resultMementos = resultMementos;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -38,7 +39,7 @@ public class NamedResultSetMappingMementoImpl implements NamedResultSetMappingMe
|
|||
ResultSetMapping resultSetMapping,
|
||||
Consumer<String> querySpaceConsumer,
|
||||
ResultSetMappingResolutionContext context) {
|
||||
resultMappingMementos.forEach(
|
||||
resultMementos.forEach(
|
||||
memento -> resultSetMapping.addResultBuilder( memento.resolve( querySpaceConsumer, context ) )
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ import java.util.function.Consumer;
|
|||
import javax.persistence.ColumnResult;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.query.results.ResultBuilder;
|
||||
import org.hibernate.query.named.ResultMementoBasic;
|
||||
import org.hibernate.query.results.ResultBuilderBasicValued;
|
||||
import org.hibernate.query.results.complete.CompleteResultBuilderBasicValuedStandard;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
@ -44,7 +45,7 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ScalarResultMappingMemento implements ResultMappingMemento {
|
||||
public class ResultMementoBasicStandard implements ResultMementoBasic {
|
||||
|
||||
public final String explicitColumnName;
|
||||
|
||||
|
@ -54,7 +55,7 @@ public class ScalarResultMappingMemento implements ResultMappingMemento {
|
|||
/**
|
||||
* Creation of ScalarResultMappingMemento for JPA descriptor
|
||||
*/
|
||||
public ScalarResultMappingMemento(
|
||||
public ResultMementoBasicStandard(
|
||||
ColumnResult definition,
|
||||
ResultSetMappingResolutionContext context) {
|
||||
this.explicitColumnName = definition.name();
|
||||
|
@ -73,7 +74,7 @@ public class ScalarResultMappingMemento implements ResultMappingMemento {
|
|||
explicitType = null;
|
||||
}
|
||||
|
||||
public ScalarResultMappingMemento(
|
||||
public ResultMementoBasicStandard(
|
||||
String explicitColumnName,
|
||||
BasicType<?> explicitType,
|
||||
ResultSetMappingResolutionContext context) {
|
||||
|
@ -85,21 +86,9 @@ public class ScalarResultMappingMemento implements ResultMappingMemento {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ResultBuilder resolve(
|
||||
public ResultBuilderBasicValued resolve(
|
||||
Consumer<String> querySpaceConsumer,
|
||||
ResultSetMappingResolutionContext context) {
|
||||
return new CompleteResultBuilderBasicValuedStandard( this, context );
|
||||
}
|
||||
|
||||
public String getExplicitColumnName() {
|
||||
return explicitColumnName;
|
||||
}
|
||||
|
||||
public BasicType<?> getExplicitType() {
|
||||
return explicitType;
|
||||
}
|
||||
|
||||
public JavaTypeDescriptor<?> getExplicitJavaTypeDescriptor() {
|
||||
return explicitJavaTypeDescriptor;
|
||||
return new CompleteResultBuilderBasicValuedStandard( explicitColumnName, explicitType, explicitJavaTypeDescriptor );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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.query.internal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.named.FetchMemento;
|
||||
import org.hibernate.query.named.ResultMemento;
|
||||
import org.hibernate.query.named.ResultMementoBasic;
|
||||
import org.hibernate.query.named.ResultMementoEntity;
|
||||
import org.hibernate.query.results.FetchBuilder;
|
||||
import org.hibernate.query.results.ResultBuilder;
|
||||
import org.hibernate.query.results.ResultBuilderBasicValued;
|
||||
import org.hibernate.query.results.ResultBuilderEntityValued;
|
||||
import org.hibernate.query.results.complete.CompleteResultBuilderEntityStandard;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ResultMementoEntityStandard implements ResultMementoEntity, FetchMemento.Parent {
|
||||
private final NavigablePath navigablePath;
|
||||
private final EntityMappingType entityDescriptor;
|
||||
private final LockMode lockMode;
|
||||
private final ResultMemento identifierMemento;
|
||||
private final ResultMementoBasic discriminatorMemento;
|
||||
private final Map<String, FetchMemento> fetchMementoMap;
|
||||
|
||||
public ResultMementoEntityStandard(
|
||||
EntityMappingType entityDescriptor,
|
||||
LockMode lockMode,
|
||||
ResultMemento identifierMemento,
|
||||
ResultMementoBasic discriminatorMemento,
|
||||
Map<String, FetchMemento> fetchMementoMap) {
|
||||
this.navigablePath = new NavigablePath( entityDescriptor.getEntityName() );
|
||||
this.entityDescriptor = entityDescriptor;
|
||||
this.lockMode = lockMode;
|
||||
this.identifierMemento = identifierMemento;
|
||||
this.discriminatorMemento = discriminatorMemento;
|
||||
this.fetchMementoMap = fetchMementoMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigablePath getNavigablePath() {
|
||||
return navigablePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityMappingType getReferencedModelPart() {
|
||||
return entityDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedMappingType getMappingType() {
|
||||
return entityDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultBuilderEntityValued resolve(
|
||||
Consumer<String> querySpaceConsumer,
|
||||
ResultSetMappingResolutionContext context) {
|
||||
final ResultBuilder identifierResultBuilder = identifierMemento.resolve(
|
||||
querySpaceConsumer,
|
||||
context
|
||||
);
|
||||
|
||||
final ResultBuilderBasicValued discriminatorResultBuilder = discriminatorMemento != null
|
||||
? discriminatorMemento.resolve( querySpaceConsumer, context )
|
||||
: null;
|
||||
|
||||
final HashMap<String, FetchBuilder> fetchBuilderMap = new HashMap<>();
|
||||
|
||||
fetchMementoMap.forEach(
|
||||
(attrName, fetchMemento) -> fetchBuilderMap.put(
|
||||
attrName,
|
||||
fetchMemento.resolve(this, querySpaceConsumer, context )
|
||||
)
|
||||
);
|
||||
|
||||
return new CompleteResultBuilderEntityStandard(
|
||||
navigablePath,
|
||||
entityDescriptor,
|
||||
lockMode,
|
||||
identifierResultBuilder,
|
||||
discriminatorResultBuilder,
|
||||
fetchBuilderMap
|
||||
);
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import java.util.List;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.query.named.ResultMementoInstantiation;
|
||||
import org.hibernate.query.results.ResultBuilder;
|
||||
import org.hibernate.query.results.complete.CompleteResultBuilderInstantiation;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
@ -17,23 +18,12 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
|||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class InstantiationResultMappingMemento implements ResultMappingMemento {
|
||||
public static class ArgumentMemento {
|
||||
private final ResultMappingMemento argumentMemento;
|
||||
|
||||
public ArgumentMemento(ResultMappingMemento argumentMemento) {
|
||||
this.argumentMemento = argumentMemento;
|
||||
}
|
||||
|
||||
public ResultBuilder resolve(Consumer<String> querySpaceConsumer, ResultSetMappingResolutionContext context) {
|
||||
return argumentMemento.resolve( querySpaceConsumer, context );
|
||||
}
|
||||
}
|
||||
public class ResultMementoInstantiationStandard implements ResultMementoInstantiation {
|
||||
|
||||
private final JavaTypeDescriptor<?> instantiatedJtd;
|
||||
private final List<ArgumentMemento> argumentMementos;
|
||||
|
||||
public InstantiationResultMappingMemento(
|
||||
public ResultMementoInstantiationStandard(
|
||||
JavaTypeDescriptor<?> instantiatedJtd,
|
||||
List<ArgumentMemento> argumentMementos) {
|
||||
this.instantiatedJtd = instantiatedJtd;
|
|
@ -4,30 +4,34 @@
|
|||
* 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.query.internal;
|
||||
package org.hibernate.query.named;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.metamodel.mapping.MappingType;
|
||||
import org.hibernate.query.internal.ResultSetMappingResolutionContext;
|
||||
import org.hibernate.query.results.FetchBuilder;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface FetchMappingMemento {
|
||||
interface Parent {
|
||||
/**
|
||||
* The path for the parent
|
||||
*/
|
||||
NavigablePath getNavigablePath();
|
||||
|
||||
public interface FetchMemento extends ModelPartReferenceMemento {
|
||||
/**
|
||||
* The parent node for the fetch
|
||||
*/
|
||||
interface Parent extends ModelPartReferenceMemento {
|
||||
/**
|
||||
* The entity descriptor that is the base for this path/parent
|
||||
*/
|
||||
ManagedMappingType getMappingType();
|
||||
}
|
||||
|
||||
/**
|
||||
* The mapping descriptor for the fetchable
|
||||
*/
|
||||
MappingType getMappingType();
|
||||
|
||||
/**
|
||||
* Resolve the fetch-memento into the result-graph-node builder
|
||||
*/
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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.query.named;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.query.internal.ResultSetMappingResolutionContext;
|
||||
import org.hibernate.query.named.FetchMemento;
|
||||
import org.hibernate.query.results.FetchBuilder;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface FetchMementoBasic extends FetchMemento {
|
||||
@Override
|
||||
FetchBuilder resolve(
|
||||
Parent parent,
|
||||
Consumer<String> querySpaceConsumer,
|
||||
ResultSetMappingResolutionContext context);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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.query.named;
|
||||
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
|
||||
/**
|
||||
* A ResultMappingMementoNode that is a reference to some part of the user's
|
||||
* domain model
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ModelPartReferenceMemento extends ResultMappingMementoNode {
|
||||
/**
|
||||
* Path to the memento, relative to the result roots
|
||||
*/
|
||||
NavigablePath getNavigablePath();
|
||||
|
||||
/**
|
||||
* The referenced domain model part
|
||||
*/
|
||||
ModelPart getReferencedModelPart();
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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.query.named;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ModelPartResultMemento extends ModelPartReferenceMemento, ResultMemento {
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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.query.named;
|
||||
|
||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ModelPartResultMementoBasic extends ModelPartResultMemento, ResultMementoBasic {
|
||||
@Override
|
||||
BasicValuedModelPart getReferencedModelPart();
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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.query.named;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ModelPartResultMementoEntity extends ModelPartResultMemento, ResultMementoEntity {
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* 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.query.named;
|
||||
|
||||
/**
|
||||
* Any node (result or fetch) in the result graph
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ResultMappingMementoNode {
|
||||
}
|
|
@ -4,15 +4,20 @@
|
|||
* 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.query.internal;
|
||||
package org.hibernate.query.named;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.query.internal.ResultSetMappingResolutionContext;
|
||||
import org.hibernate.query.results.ResultBuilder;
|
||||
|
||||
/**
|
||||
* @since 6.0
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ResultMappingMemento {
|
||||
@Incubating
|
||||
public interface ResultMemento extends ResultMappingMementoNode {
|
||||
ResultBuilder resolve(Consumer<String> querySpaceConsumer, ResultSetMappingResolutionContext context);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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.query.named;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.query.internal.ResultSetMappingResolutionContext;
|
||||
import org.hibernate.query.results.ResultBuilderBasicValued;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ResultMementoBasic extends ResultMemento {
|
||||
@Override
|
||||
ResultBuilderBasicValued resolve(
|
||||
Consumer<String> querySpaceConsumer,
|
||||
ResultSetMappingResolutionContext context);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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.query.named;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.query.internal.ResultSetMappingResolutionContext;
|
||||
import org.hibernate.query.results.ResultBuilderEntityValued;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ResultMementoEntity extends ResultMemento {
|
||||
@Override
|
||||
ResultBuilderEntityValued resolve(
|
||||
Consumer<String> querySpaceConsumer,
|
||||
ResultSetMappingResolutionContext context);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.query.named;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.query.internal.ResultSetMappingResolutionContext;
|
||||
import org.hibernate.query.results.ResultBuilder;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ResultMementoInstantiation extends ResultMemento {
|
||||
class ArgumentMemento {
|
||||
private final ResultMemento argumentMemento;
|
||||
|
||||
public ArgumentMemento(ResultMemento argumentMemento) {
|
||||
this.argumentMemento = argumentMemento;
|
||||
}
|
||||
|
||||
public ResultBuilder resolve(Consumer<String> querySpaceConsumer, ResultSetMappingResolutionContext context) {
|
||||
return argumentMemento.resolve( querySpaceConsumer, context );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,60 +9,233 @@ package org.hibernate.query.results;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.hibernate.Internal;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.mapping.AssociationKey;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.query.results.dynamic.LegacyFetchResolver;
|
||||
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
|
||||
import org.hibernate.sql.ast.spi.SqlAliasBaseManager;
|
||||
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.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.results.ResultsLogger;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DomainResultCreationStateImpl implements DomainResultCreationState {
|
||||
private final List<ResultBuilder> resultBuilders;
|
||||
private final Map<String, Map<String, DynamicFetchBuilderLegacy>> legacyFetchBuilders;
|
||||
private final SqlAstCreationStateImpl sqlAstCreationState;
|
||||
@Internal
|
||||
public class DomainResultCreationStateImpl
|
||||
implements DomainResultCreationState, SqlAstCreationState, SqlAstProcessingState, SqlExpressionResolver {
|
||||
|
||||
private final String stateIdentifier;
|
||||
private final FromClauseAccessImpl fromClauseAccess;
|
||||
|
||||
private final Consumer<SqlSelection> sqlSelectionConsumer;
|
||||
private final Map<String,SqlSelectionImpl> sqlSelectionMap = new HashMap<>();
|
||||
private boolean allowPositionalSelections = true;
|
||||
|
||||
private final SqlAliasBaseManager sqlAliasBaseManager;
|
||||
|
||||
private final LegacyFetchResolverImpl legacyFetchResolver;
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
|
||||
public DomainResultCreationStateImpl(
|
||||
List<ResultBuilder> resultBuilders,
|
||||
String stateIdentifier,
|
||||
Map<String, Map<String, DynamicFetchBuilderLegacy>> legacyFetchBuilders,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
this.resultBuilders = resultBuilders;
|
||||
this.legacyFetchBuilders = legacyFetchBuilders;
|
||||
this.stateIdentifier = stateIdentifier;
|
||||
this.sqlSelectionConsumer = sqlSelectionConsumer;
|
||||
this.fromClauseAccess = new FromClauseAccessImpl();
|
||||
this.sqlAstCreationState = new SqlAstCreationStateImpl( fromClauseAccess, sessionFactory );
|
||||
this.sqlAliasBaseManager = new SqlAliasBaseManager();
|
||||
|
||||
this.legacyFetchResolver = new LegacyFetchResolverImpl();
|
||||
this.legacyFetchResolver = new LegacyFetchResolverImpl( legacyFetchBuilders );
|
||||
|
||||
this.sessionFactory = sessionFactory;
|
||||
}
|
||||
|
||||
public LegacyFetchResolver getLegacyFetchResolver() {
|
||||
return legacyFetchResolver;
|
||||
}
|
||||
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
return sessionFactory;
|
||||
}
|
||||
|
||||
public int getNumberOfProcessedSelections() {
|
||||
return sqlSelectionMap.size();
|
||||
}
|
||||
|
||||
public boolean arePositionalSelectionsAllowed() {
|
||||
return allowPositionalSelections;
|
||||
}
|
||||
|
||||
public void disallowPositionalSelections() {
|
||||
ResultsLogger.LOGGER.debugf( "Disallowing positional selections : %s", stateIdentifier );
|
||||
this.allowPositionalSelections = false;
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// DomainResultCreationState
|
||||
|
||||
@Override
|
||||
public FromClauseAccessImpl getFromClauseAccess() {
|
||||
return fromClauseAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlAstCreationStateImpl getSqlAstCreationState() {
|
||||
return sqlAstCreationState;
|
||||
public DomainResultCreationStateImpl getSqlAstCreationState() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface LegacyFetchResolver {
|
||||
DynamicFetchBuilderLegacy resolve(String ownerTableAlias, String fetchedPartPath);
|
||||
@Override
|
||||
public SqlAliasBaseManager getSqlAliasBaseManager() {
|
||||
return sqlAliasBaseManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean forceIdentifierSelection() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerVisitedAssociationKey(AssociationKey associationKey) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssociationKeyVisited(AssociationKey associationKey) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelPart resolveModelPart(NavigablePath navigablePath) {
|
||||
final TableGroup tableGroup = fromClauseAccess.findTableGroup( navigablePath );
|
||||
if ( tableGroup != null ) {
|
||||
return tableGroup.getModelPart();
|
||||
}
|
||||
|
||||
if ( navigablePath.getParent() != null ) {
|
||||
final TableGroup parentTableGroup = fromClauseAccess.findTableGroup( navigablePath.getParent() );
|
||||
if ( parentTableGroup != null ) {
|
||||
return parentTableGroup.getModelPart().findSubPart( navigablePath.getLocalName(), null );
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// SqlAstCreationState
|
||||
|
||||
@Override
|
||||
public DomainResultCreationStateImpl getSqlExpressionResolver() {
|
||||
return getCurrentProcessingState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockMode determineLockMode(String identificationVariable) {
|
||||
return LockMode.READ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainResultCreationStateImpl getCurrentProcessingState() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlAstCreationContext getCreationContext() {
|
||||
return getSessionFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlAliasBaseGenerator getSqlAliasBaseGenerator() {
|
||||
return sqlAliasBaseManager;
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// SqlAstProcessingState
|
||||
|
||||
@Override
|
||||
public SqlAstProcessingState getParentState() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// SqlExpressionResolver
|
||||
|
||||
@Override
|
||||
public Expression resolveSqlExpression(
|
||||
String key,
|
||||
Function<SqlAstProcessingState, Expression> creator) {
|
||||
final SqlSelectionImpl existing = sqlSelectionMap.get( key );
|
||||
if ( existing != null ) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
final Expression created = creator.apply( this );
|
||||
|
||||
if ( created instanceof SqlSelectionImpl ) {
|
||||
sqlSelectionMap.put( key, (SqlSelectionImpl) created );
|
||||
sqlSelectionConsumer.accept( (SqlSelectionImpl) created );
|
||||
}
|
||||
else if ( created instanceof ColumnReference ) {
|
||||
final ColumnReference columnReference = (ColumnReference) created;
|
||||
|
||||
final SqlSelectionImpl sqlSelection = new SqlSelectionImpl(
|
||||
sqlSelectionMap.size() + 1,
|
||||
columnReference.getJdbcMapping()
|
||||
);
|
||||
|
||||
sqlSelectionMap.put( key, sqlSelection );
|
||||
sqlSelectionConsumer.accept( sqlSelection );
|
||||
}
|
||||
|
||||
return created;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlSelection resolveSqlSelection(
|
||||
Expression expression,
|
||||
JavaTypeDescriptor javaTypeDescriptor,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
assert expression instanceof SqlSelectionImpl;
|
||||
return (SqlSelection) expression;
|
||||
}
|
||||
|
||||
private static class LegacyFetchResolverImpl implements LegacyFetchResolver {
|
||||
private final Map<String,Map<String, DynamicFetchBuilderLegacy>> legacyFetchResolvers;
|
||||
private final Map<String,Map<String, DynamicFetchBuilderLegacy>> legacyFetchBuilders;
|
||||
|
||||
public LegacyFetchResolverImpl() {
|
||||
this.legacyFetchResolvers = new HashMap<>();
|
||||
public LegacyFetchResolverImpl(Map<String, Map<String, DynamicFetchBuilderLegacy>> legacyFetchBuilders) {
|
||||
this.legacyFetchBuilders = legacyFetchBuilders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicFetchBuilderLegacy resolve(String ownerTableAlias, String fetchedPartPath) {
|
||||
final Map<String, DynamicFetchBuilderLegacy> fetchBuilders = legacyFetchResolvers.get( ownerTableAlias );
|
||||
if ( legacyFetchBuilders == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Map<String, DynamicFetchBuilderLegacy> fetchBuilders = legacyFetchBuilders.get( ownerTableAlias );
|
||||
if ( fetchBuilders == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -71,10 +244,6 @@ public class DomainResultCreationStateImpl implements DomainResultCreationState
|
|||
}
|
||||
}
|
||||
|
||||
public LegacyFetchResolver getLegacyFetchResolver() {
|
||||
return legacyFetchResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Fetch> visitFetches(FetchParent fetchParent) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
|
@ -7,12 +7,10 @@
|
|||
package org.hibernate.query.results;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
|
@ -28,11 +26,9 @@ import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
|||
*/
|
||||
@Incubating
|
||||
public interface FetchBuilder {
|
||||
|
||||
Fetch buildFetch(
|
||||
FetchParent parent,
|
||||
NavigablePath fetchPath, JdbcValuesMetadata jdbcResultsMetadata,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.query.results;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
||||
/**
|
||||
* Indicates that a column defined as part of a SQL ResultSet mapping was not part
|
||||
* of the query's ResultSet
|
||||
*
|
||||
* @see ResultSetMapping
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class MissingSqlSelectionException extends HibernateException {
|
||||
public MissingSqlSelectionException(String message) {
|
||||
super( message );
|
||||
}
|
||||
|
||||
public MissingSqlSelectionException(String message, Throwable cause) {
|
||||
super( message, cause );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* 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.query.results;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class PositionalSelectionsNotAllowedException extends HibernateException {
|
||||
public PositionalSelectionsNotAllowedException(String message) {
|
||||
super( message );
|
||||
}
|
||||
}
|
|
@ -7,11 +7,9 @@
|
|||
package org.hibernate.query.results;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||
|
@ -28,6 +26,5 @@ public interface ResultBuilder {
|
|||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
int resultPosition,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState);
|
||||
}
|
||||
|
|
|
@ -7,10 +7,8 @@
|
|||
package org.hibernate.query.results;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||
|
@ -26,6 +24,5 @@ public interface ResultBuilderBasicValued extends ResultBuilder {
|
|||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
int resultPosition,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState);
|
||||
}
|
||||
|
|
|
@ -7,10 +7,8 @@
|
|||
package org.hibernate.query.results;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.entity.EntityResult;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||
|
@ -26,6 +24,5 @@ public interface ResultBuilderEntityValued extends ResultBuilder {
|
|||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
int resultPosition,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState);
|
||||
}
|
||||
|
|
|
@ -36,9 +36,15 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
@Incubating
|
||||
@Internal
|
||||
public class ResultSetMappingImpl implements ResultSetMapping {
|
||||
private final String mappingIdentifier;
|
||||
|
||||
private List<ResultBuilder> resultBuilders;
|
||||
private Map<String, Map<String, DynamicFetchBuilderLegacy>> legacyFetchBuilders;
|
||||
|
||||
public ResultSetMappingImpl(String mappingIdentifier) {
|
||||
this.mappingIdentifier = mappingIdentifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfResultBuilders() {
|
||||
return resultBuilders == null ? 0 : resultBuilders.size();
|
||||
|
@ -108,8 +114,9 @@ public class ResultSetMappingImpl implements ResultSetMapping {
|
|||
final List<DomainResult<?>> domainResults = new ArrayList<>( numberOfResults );
|
||||
|
||||
final DomainResultCreationStateImpl creationState = new DomainResultCreationStateImpl(
|
||||
resultBuilders,
|
||||
mappingIdentifier,
|
||||
legacyFetchBuilders,
|
||||
sqlSelections::add,
|
||||
sessionFactory
|
||||
);
|
||||
|
||||
|
@ -131,22 +138,15 @@ public class ResultSetMappingImpl implements ResultSetMapping {
|
|||
domainResult = resultBuilder.buildResult(
|
||||
jdbcResultsMetadata,
|
||||
domainResults.size(),
|
||||
(entityName, fetchableName) -> {
|
||||
if ( legacyFetchBuilders == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Map<String, DynamicFetchBuilderLegacy> fetchBuilderMap = legacyFetchBuilders.get( entityName );
|
||||
if ( fetchBuilderMap == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return fetchBuilderMap.get( fetchableName );
|
||||
},
|
||||
sqlSelections::add,
|
||||
creationState.getLegacyFetchResolver()::resolve,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
|
||||
if ( domainResult.containsAnyNonScalarResults() ) {
|
||||
creationState.disallowPositionalSelections();
|
||||
}
|
||||
|
||||
domainResults.add( domainResult );
|
||||
}
|
||||
|
||||
|
|
|
@ -24,18 +24,6 @@ public class ResultsHelper {
|
|||
return unwrap( creationState );
|
||||
}
|
||||
|
||||
public static FromClauseAccessImpl extractFromClauseAccess(DomainResultCreationState creationState) {
|
||||
return unwrap( creationState ).getFromClauseAccess();
|
||||
}
|
||||
|
||||
public static SqlAstCreationStateImpl extractSqlAstCreationState(DomainResultCreationState creationState) {
|
||||
return unwrap( creationState ).getSqlAstCreationState();
|
||||
}
|
||||
|
||||
public static SqlAstProcessingStateImpl extractSqlAstProcessingState(DomainResultCreationState creationState) {
|
||||
return unwrap( creationState ).getSqlAstCreationState().getCurrentProcessingState();
|
||||
}
|
||||
|
||||
private static DomainResultCreationStateImpl unwrap(DomainResultCreationState creationState) {
|
||||
if ( creationState instanceof DomainResultCreationStateImpl ) {
|
||||
return ( (DomainResultCreationStateImpl) creationState );
|
||||
|
|
|
@ -6,44 +6,83 @@
|
|||
*/
|
||||
package org.hibernate.query.results;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.hibernate.Internal;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.sql.ast.spi.FromClauseAccess;
|
||||
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
|
||||
import org.hibernate.sql.ast.spi.SqlAliasBaseManager;
|
||||
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.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* SqlAstCreationState implementation for result-set mapping handling
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SqlAstCreationStateImpl implements SqlAstCreationState {
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
@Internal
|
||||
public class SqlAstCreationStateImpl implements SqlAstCreationState, SqlAstProcessingState, SqlExpressionResolver {
|
||||
|
||||
private final FromClauseAccessImpl fromClauseAccess;
|
||||
private final SqlAstProcessingStateImpl processingState;
|
||||
private final SqlAliasBaseManager sqlAliasBaseManager;
|
||||
|
||||
private final Consumer<SqlSelection> sqlSelectionConsumer;
|
||||
private final Map<String,SqlSelectionImpl> sqlSelectionMap = new HashMap<>();
|
||||
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
public SqlAstCreationStateImpl(
|
||||
FromClauseAccessImpl fromClauseAccess,
|
||||
SqlAliasBaseManager sqlAliasBaseManager,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
this.fromClauseAccess = fromClauseAccess;
|
||||
this.processingState = new SqlAstProcessingStateImpl( this, fromClauseAccess );
|
||||
this.sqlAliasBaseManager = sqlAliasBaseManager;
|
||||
this.sqlSelectionConsumer = sqlSelectionConsumer;
|
||||
this.sessionFactory = sessionFactory;
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// SqlAstProcessingState
|
||||
|
||||
@Override
|
||||
public SqlAstProcessingState getParentState() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlAstCreationState getSqlAstCreationState() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// SqlAstCreationState
|
||||
|
||||
@Override
|
||||
public SqlAstCreationContext getCreationContext() {
|
||||
return sessionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlAstProcessingStateImpl getCurrentProcessingState() {
|
||||
return processingState;
|
||||
public SqlAstCreationStateImpl getCurrentProcessingState() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlAstProcessingStateImpl getSqlExpressionResolver() {
|
||||
return processingState;
|
||||
public SqlAstCreationStateImpl getSqlExpressionResolver() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,13 +92,31 @@ public class SqlAstCreationStateImpl implements SqlAstCreationState {
|
|||
|
||||
@Override
|
||||
public SqlAliasBaseGenerator getSqlAliasBaseGenerator() {
|
||||
return stem -> {
|
||||
throw new UnsupportedOperationException();
|
||||
};
|
||||
return sqlAliasBaseManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockMode determineLockMode(String identificationVariable) {
|
||||
return LockMode.READ;
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// SqlExpressionResolver
|
||||
|
||||
|
||||
@Override
|
||||
public Expression resolveSqlExpression(
|
||||
String key,
|
||||
Function<SqlAstProcessingState, Expression> creator) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlSelection resolveSqlSelection(
|
||||
Expression expression,
|
||||
JavaTypeDescriptor javaTypeDescriptor,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,10 @@ package org.hibernate.query.results;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.hibernate.Internal;
|
||||
import org.hibernate.sql.ast.spi.FromClauseAccess;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.spi.SqlAstProcessingState;
|
||||
|
@ -23,17 +25,22 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Internal
|
||||
public class SqlAstProcessingStateImpl implements SqlAstProcessingState, SqlExpressionResolver {
|
||||
private final SqlAstCreationState sqlAstCreationState;
|
||||
private final FromClauseAccessImpl fromClauseAccess;
|
||||
|
||||
private final Map<String,SqlSelectionImpl> sqlSelectionMap = new HashMap<>();
|
||||
private final Consumer<SqlSelection> sqlSelectionConsumer;
|
||||
|
||||
private final SqlAstCreationState sqlAstCreationState;
|
||||
|
||||
public SqlAstProcessingStateImpl(
|
||||
SqlAstCreationState sqlAstCreationState,
|
||||
FromClauseAccessImpl fromClauseAccess) {
|
||||
this.sqlAstCreationState = sqlAstCreationState;
|
||||
FromClauseAccessImpl fromClauseAccess,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
SqlAstCreationState sqlAstCreationState) {
|
||||
this.fromClauseAccess = fromClauseAccess;
|
||||
this.sqlSelectionConsumer = sqlSelectionConsumer;
|
||||
this.sqlAstCreationState = sqlAstCreationState;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -69,6 +76,7 @@ public class SqlAstProcessingStateImpl implements SqlAstProcessingState, SqlExpr
|
|||
|
||||
if ( created instanceof SqlSelectionImpl ) {
|
||||
sqlSelectionMap.put( key, (SqlSelectionImpl) created );
|
||||
sqlSelectionConsumer.accept( (SqlSelectionImpl) created );
|
||||
}
|
||||
else if ( created instanceof ColumnReference ) {
|
||||
final ColumnReference columnReference = (ColumnReference) created;
|
||||
|
@ -77,7 +85,9 @@ public class SqlAstProcessingStateImpl implements SqlAstProcessingState, SqlExpr
|
|||
sqlSelectionMap.size() + 1,
|
||||
columnReference.getJdbcMapping()
|
||||
);
|
||||
|
||||
sqlSelectionMap.put( key, sqlSelection );
|
||||
sqlSelectionConsumer.accept( sqlSelection );
|
||||
}
|
||||
|
||||
return created;
|
||||
|
|
|
@ -7,19 +7,16 @@
|
|||
package org.hibernate.query.results.complete;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.results.DomainResultCreationStateImpl;
|
||||
import org.hibernate.query.results.FromClauseAccessImpl;
|
||||
import org.hibernate.query.results.SqlAstCreationStateImpl;
|
||||
import org.hibernate.query.results.SqlAstProcessingStateImpl;
|
||||
import org.hibernate.query.results.MissingSqlSelectionException;
|
||||
import org.hibernate.query.results.PositionalSelectionsNotAllowedException;
|
||||
import org.hibernate.query.results.SqlSelectionImpl;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
|
@ -34,13 +31,23 @@ import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnRefere
|
|||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CompleteFetchBuilderBasicPart implements CompleteFetchBuilder {
|
||||
public class CompleteFetchBuilderBasicPart implements CompleteFetchBuilder, ModelPartReferenceBasic {
|
||||
private final NavigablePath navigablePath;
|
||||
private final BasicValuedModelPart referencedModelPart;
|
||||
private final String columnName;
|
||||
private final String selectionAlias;
|
||||
|
||||
public CompleteFetchBuilderBasicPart(BasicValuedModelPart referencedModelPart, String columnName) {
|
||||
public CompleteFetchBuilderBasicPart(
|
||||
NavigablePath navigablePath,
|
||||
BasicValuedModelPart referencedModelPart,
|
||||
String selectionAlias) {
|
||||
this.navigablePath = navigablePath;
|
||||
this.referencedModelPart = referencedModelPart;
|
||||
this.columnName = columnName;
|
||||
this.selectionAlias = selectionAlias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigablePath getNavigablePath() {
|
||||
return navigablePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -54,49 +61,48 @@ public class CompleteFetchBuilderBasicPart implements CompleteFetchBuilder {
|
|||
NavigablePath fetchPath,
|
||||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState) {
|
||||
final DomainResultCreationStateImpl domainResultCreationStateImpl = impl( domainResultCreationState );
|
||||
final SqlAstCreationStateImpl sqlAstCreationState = domainResultCreationStateImpl.getSqlAstCreationState();
|
||||
final FromClauseAccessImpl fromClauseAccess = domainResultCreationStateImpl.getFromClauseAccess();
|
||||
final SqlAstProcessingStateImpl sqlAstProcessingState = sqlAstCreationState.getCurrentProcessingState();
|
||||
final DomainResultCreationStateImpl creationState = impl( domainResultCreationState );
|
||||
|
||||
final String mappedTable = referencedModelPart.getContainingTableExpression();
|
||||
final String mappedColumn = referencedModelPart.getMappedColumnExpression();
|
||||
|
||||
final TableGroup tableGroup = fromClauseAccess.getTableGroup( parent.getNavigablePath() );
|
||||
final TableGroup tableGroup = creationState.getFromClauseAccess().getTableGroup( parent.getNavigablePath() );
|
||||
final TableReference tableReference = tableGroup.getTableReference( mappedTable );
|
||||
|
||||
final String selectedAlias;
|
||||
final int jdbcPosition;
|
||||
|
||||
if ( columnName == null ) {
|
||||
jdbcPosition = sqlAstProcessingState.getNumberOfProcessedSelections();
|
||||
selectedAlias = jdbcResultsMetadata.resolveColumnName( jdbcPosition );
|
||||
if ( selectionAlias != null ) {
|
||||
try {
|
||||
jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( selectionAlias );
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MissingSqlSelectionException(
|
||||
"ResultSet mapping specified selected-alias `" + selectionAlias
|
||||
+ "` which was not part of the ResultSet",
|
||||
e
|
||||
);
|
||||
}
|
||||
selectedAlias = selectionAlias;
|
||||
}
|
||||
else {
|
||||
jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( columnName );
|
||||
selectedAlias = columnName;
|
||||
if ( ! creationState.arePositionalSelectionsAllowed() ) {
|
||||
throw new PositionalSelectionsNotAllowedException(
|
||||
"Positional SQL selection resolution not allowed"
|
||||
);
|
||||
}
|
||||
jdbcPosition = creationState.getNumberOfProcessedSelections();
|
||||
selectedAlias = jdbcResultsMetadata.resolveColumnName( jdbcPosition );
|
||||
}
|
||||
|
||||
final int valuesArrayPosition = jdbcPositionToValuesArrayPosition( jdbcPosition );
|
||||
|
||||
// we just care about the registration here. The ModelPart will find it later
|
||||
|
||||
sqlAstProcessingState.resolveSqlExpression(
|
||||
creationState.resolveSqlExpression(
|
||||
createColumnReferenceKey( tableReference, mappedColumn ),
|
||||
processingState -> new SqlSelectionImpl( valuesArrayPosition, referencedModelPart )
|
||||
);
|
||||
// final Expression expression = sqlAstProcessingState.resolveSqlExpression(
|
||||
// createColumnReferenceKey( tableReference, mappedColumn ),
|
||||
// processingState -> new SqlSelectionImpl( valuesArrayPosition, referencedModelPart )
|
||||
// );
|
||||
//
|
||||
// final SqlSelection sqlSelection = sqlAstProcessingState.resolveSqlSelection(
|
||||
// expression,
|
||||
// referencedModelPart.getJavaTypeDescriptor(),
|
||||
// sqlAstCreationState.getCreationContext().getSessionFactory().getTypeConfiguration()
|
||||
// );
|
||||
|
||||
return referencedModelPart.generateFetch(
|
||||
parent,
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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.query.results.complete;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.results.DomainResultCreationStateImpl;
|
||||
import org.hibernate.query.results.SqlSelectionImpl;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||
|
||||
import static org.hibernate.query.results.ResultsHelper.impl;
|
||||
import static org.hibernate.query.results.ResultsHelper.jdbcPositionToValuesArrayPosition;
|
||||
|
||||
/**
|
||||
* CompleteResultBuilder for basic-valued ModelParts
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CompleteResultBuilderBasicModelPart
|
||||
implements CompleteResultBuilderBasicValued, ModelPartReferenceBasic {
|
||||
private final NavigablePath navigablePath;
|
||||
private final BasicValuedModelPart modelPart;
|
||||
private final String columnAlias;
|
||||
|
||||
public CompleteResultBuilderBasicModelPart(
|
||||
NavigablePath navigablePath,
|
||||
BasicValuedModelPart modelPart,
|
||||
String columnAlias) {
|
||||
this.navigablePath = navigablePath;
|
||||
this.modelPart = modelPart;
|
||||
this.columnAlias = columnAlias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigablePath getNavigablePath() {
|
||||
return navigablePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicValuedModelPart getReferencedPart() {
|
||||
return modelPart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicResult<?> buildResult(
|
||||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
int resultPosition,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
DomainResultCreationState domainResultCreationState) {
|
||||
final DomainResultCreationStateImpl creationStateImpl = impl( domainResultCreationState );
|
||||
|
||||
final TableGroup tableGroup = creationStateImpl.getFromClauseAccess().getTableGroup( navigablePath.getParent() );
|
||||
final TableReference tableReference = tableGroup.getTableReference( modelPart.getContainingTableExpression() );
|
||||
final String mappedColumn = modelPart.getMappedColumnExpression();
|
||||
|
||||
final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias );
|
||||
final int valuesArrayPosition = jdbcPositionToValuesArrayPosition( jdbcPosition );
|
||||
|
||||
creationStateImpl.resolveSqlSelection(
|
||||
creationStateImpl.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey( tableReference, mappedColumn ),
|
||||
processingState -> new SqlSelectionImpl( valuesArrayPosition, modelPart )
|
||||
),
|
||||
modelPart.getJavaTypeDescriptor(),
|
||||
creationStateImpl.getSessionFactory().getTypeConfiguration()
|
||||
);
|
||||
|
||||
//noinspection unchecked
|
||||
return new BasicResult(
|
||||
valuesArrayPosition,
|
||||
columnAlias,
|
||||
modelPart.getJavaTypeDescriptor()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -7,24 +7,22 @@
|
|||
package org.hibernate.query.results.complete;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.query.internal.ResultSetMappingResolutionContext;
|
||||
import org.hibernate.query.internal.ScalarResultMappingMemento;
|
||||
import org.hibernate.query.results.DomainResultCreationStateImpl;
|
||||
import org.hibernate.query.results.ResultsHelper;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.query.results.SqlSelectionImpl;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import static org.hibernate.query.results.ResultsHelper.impl;
|
||||
|
||||
/**
|
||||
* ResultBuilder for scalar results defined via:<ul>
|
||||
* <li>JPA {@link javax.persistence.ColumnResult}</li>
|
||||
|
@ -37,15 +35,16 @@ public class CompleteResultBuilderBasicValuedStandard implements CompleteResultB
|
|||
|
||||
private final String explicitColumnName;
|
||||
|
||||
private final BasicType<?> explicitType;
|
||||
private final BasicValuedMapping explicitType;
|
||||
private final JavaTypeDescriptor<?> explicitJavaTypeDescriptor;
|
||||
|
||||
public CompleteResultBuilderBasicValuedStandard(
|
||||
ScalarResultMappingMemento memento,
|
||||
ResultSetMappingResolutionContext context) {
|
||||
this.explicitColumnName = memento.getExplicitColumnName();
|
||||
this.explicitType = memento.getExplicitType();
|
||||
this.explicitJavaTypeDescriptor = memento.getExplicitJavaTypeDescriptor();
|
||||
String explicitColumnName,
|
||||
BasicValuedMapping explicitType,
|
||||
JavaTypeDescriptor<?> explicitJavaTypeDescriptor) {
|
||||
this.explicitColumnName = explicitColumnName;
|
||||
this.explicitType = explicitType;
|
||||
this.explicitJavaTypeDescriptor = explicitJavaTypeDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,11 +52,9 @@ public class CompleteResultBuilderBasicValuedStandard implements CompleteResultB
|
|||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
int resultPosition,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState) {
|
||||
final SessionFactoryImplementor sessionFactory = domainResultCreationState.getSqlAstCreationState()
|
||||
.getCreationContext()
|
||||
.getSessionFactory();
|
||||
final DomainResultCreationStateImpl creationStateImpl = impl( domainResultCreationState );
|
||||
final SessionFactoryImplementor sessionFactory = creationStateImpl.getSessionFactory();
|
||||
|
||||
final int jdbcPosition;
|
||||
final String columnName;
|
||||
|
@ -73,7 +70,7 @@ public class CompleteResultBuilderBasicValuedStandard implements CompleteResultB
|
|||
|
||||
final int valuesArrayPosition = ResultsHelper.jdbcPositionToValuesArrayPosition( jdbcPosition );
|
||||
|
||||
final BasicType<?> basicType;
|
||||
final BasicValuedMapping basicType;
|
||||
|
||||
if ( explicitType != null ) {
|
||||
basicType = explicitType;
|
||||
|
@ -94,10 +91,16 @@ public class CompleteResultBuilderBasicValuedStandard implements CompleteResultB
|
|||
basicType = typeConfiguration.getBasicTypeRegistry().resolve( javaTypeDescriptor, sqlTypeDescriptor );
|
||||
}
|
||||
|
||||
final SqlSelectionImpl sqlSelection = new SqlSelectionImpl( valuesArrayPosition, (BasicValuedMapping) basicType );
|
||||
sqlSelectionConsumer.accept( sqlSelection );
|
||||
creationStateImpl.resolveSqlSelection(
|
||||
creationStateImpl.resolveSqlExpression(
|
||||
columnName,
|
||||
processingState -> new SqlSelectionImpl( valuesArrayPosition, basicType )
|
||||
),
|
||||
explicitJavaTypeDescriptor,
|
||||
sessionFactory.getTypeConfiguration()
|
||||
);
|
||||
|
||||
return new BasicResult<>( valuesArrayPosition, columnName, basicType.getJavaTypeDescriptor() );
|
||||
return new BasicResult<>( valuesArrayPosition, columnName, basicType.getMappedTypeDescriptor().getMappedJavaTypeDescriptor() );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* 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.query.results.complete;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.results.DomainResultCreationStateImpl;
|
||||
import org.hibernate.query.results.FetchBuilder;
|
||||
import org.hibernate.query.results.ResultBuilder;
|
||||
import org.hibernate.query.results.ResultBuilderBasicValued;
|
||||
import org.hibernate.query.results.ResultsHelper;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.sql.results.graph.entity.EntityResult;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CompleteResultBuilderEntityStandard implements CompleteResultBuilderEntityValued {
|
||||
private final NavigablePath navigablePath;
|
||||
private final EntityMappingType entityDescriptor;
|
||||
private final LockMode lockMode;
|
||||
private final ResultBuilder identifierResultBuilder;
|
||||
private final ResultBuilderBasicValued discriminatorResultBuilder;
|
||||
private final HashMap<String, FetchBuilder> fetchBuilderMap;
|
||||
|
||||
public CompleteResultBuilderEntityStandard(
|
||||
NavigablePath navigablePath,
|
||||
EntityMappingType entityDescriptor,
|
||||
LockMode lockMode,
|
||||
ResultBuilder identifierResultBuilder,
|
||||
ResultBuilderBasicValued discriminatorResultBuilder,
|
||||
HashMap<String, FetchBuilder> fetchBuilderMap) {
|
||||
this.navigablePath = navigablePath;
|
||||
this.entityDescriptor = entityDescriptor;
|
||||
this.lockMode = lockMode;
|
||||
this.identifierResultBuilder = identifierResultBuilder;
|
||||
this.discriminatorResultBuilder = discriminatorResultBuilder;
|
||||
this.fetchBuilderMap = fetchBuilderMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigablePath getNavigablePath() {
|
||||
return navigablePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityMappingType getReferencedPart() {
|
||||
return entityDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityResult buildResult(
|
||||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
int resultPosition,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
DomainResultCreationState domainResultCreationState) {
|
||||
final DomainResultCreationStateImpl impl = ResultsHelper.impl( domainResultCreationState );
|
||||
|
||||
// we just want it added to the registry
|
||||
impl.getFromClauseAccess().resolveTableGroup(
|
||||
navigablePath,
|
||||
np -> entityDescriptor.createRootTableGroup(
|
||||
navigablePath,
|
||||
null,
|
||||
false,
|
||||
lockMode,
|
||||
impl.getSqlAliasBaseManager(),
|
||||
impl.getSqlAstCreationState().getSqlExpressionResolver(),
|
||||
() -> predicate -> {},
|
||||
impl.getSqlAstCreationState().getCreationContext()
|
||||
)
|
||||
);
|
||||
|
||||
final DomainResult<?> identifierResult = identifierResultBuilder.buildResult(
|
||||
jdbcResultsMetadata,
|
||||
resultPosition,
|
||||
legacyFetchResolver,
|
||||
domainResultCreationState
|
||||
);
|
||||
|
||||
final BasicResult<?> discriminatorResult;
|
||||
if ( discriminatorResultBuilder != null ) {
|
||||
discriminatorResult = discriminatorResultBuilder.buildResult(
|
||||
jdbcResultsMetadata,
|
||||
resultPosition,
|
||||
legacyFetchResolver,
|
||||
domainResultCreationState
|
||||
);
|
||||
}
|
||||
else {
|
||||
discriminatorResult = null;
|
||||
}
|
||||
|
||||
return new EntityResultImpl(
|
||||
navigablePath,
|
||||
entityDescriptor,
|
||||
null,
|
||||
lockMode,
|
||||
identifierResult,
|
||||
discriminatorResult,
|
||||
fetchParent -> {
|
||||
final List<Fetch> fetches = new ArrayList<>( fetchBuilderMap.size() );
|
||||
|
||||
fetchBuilderMap.forEach(
|
||||
(fetchableName, fetchBuilder) -> fetches.add(
|
||||
fetchBuilder.buildFetch(
|
||||
fetchParent,
|
||||
navigablePath.append( fetchableName ),
|
||||
jdbcResultsMetadata,
|
||||
legacyFetchResolver,
|
||||
domainResultCreationState
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
return fetches;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@ import org.hibernate.query.results.ResultBuilderEntityValued;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface CompleteResultBuilderEntityValued
|
||||
extends CompleteResultBuilder, ModelPartReference, ResultBuilderEntityValued {
|
||||
extends CompleteResultBuilder, ModelPartReferenceEntity, ResultBuilderEntityValued {
|
||||
@Override
|
||||
EntityMappingType getReferencedPart();
|
||||
}
|
||||
|
|
|
@ -9,13 +9,11 @@ package org.hibernate.query.results.complete;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.query.DynamicInstantiationNature;
|
||||
import org.hibernate.query.results.ResultBuilderInstantiationValued;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.query.results.ResultBuilder;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.instantiation.internal.ArgumentDomainResult;
|
||||
|
@ -46,19 +44,17 @@ public class CompleteResultBuilderInstantiation
|
|||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
int resultPosition,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState) {
|
||||
final List<ArgumentDomainResult<?>> argumentDomainResults = new ArrayList<>( argumentResultBuilders.size() );
|
||||
|
||||
for ( int i = 0; i < argumentResultBuilders.size(); i++ ) {
|
||||
final ResultBuilder argumentResultBuilder = argumentResultBuilders.get( i );
|
||||
|
||||
final ArgumentDomainResult<Object> argumentDomainResult = new ArgumentDomainResult<>(
|
||||
@SuppressWarnings({"unchecked", "rawtypes"}) final ArgumentDomainResult<?> argumentDomainResult = new ArgumentDomainResult(
|
||||
argumentResultBuilder.buildResult(
|
||||
jdbcResultsMetadata,
|
||||
i,
|
||||
legacyFetchResolver,
|
||||
sqlSelectionConsumer,
|
||||
domainResultCreationState
|
||||
)
|
||||
);
|
||||
|
@ -66,7 +62,7 @@ public class CompleteResultBuilderInstantiation
|
|||
argumentDomainResults.add( argumentDomainResult );
|
||||
}
|
||||
|
||||
return new DynamicInstantiationResultImpl(
|
||||
return new DynamicInstantiationResultImpl<>(
|
||||
null,
|
||||
DynamicInstantiationNature.CLASS,
|
||||
javaTypeDescriptor,
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* 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.query.results.complete;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
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.Fetch;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
import org.hibernate.sql.results.graph.Fetchable;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.sql.results.graph.entity.EntityInitializer;
|
||||
import org.hibernate.sql.results.graph.entity.EntityResult;
|
||||
import org.hibernate.sql.results.graph.entity.internal.EntityAssembler;
|
||||
import org.hibernate.sql.results.graph.entity.internal.EntityResultInitializer;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EntityResultImpl implements EntityResult {
|
||||
private final NavigablePath navigablePath;
|
||||
private final EntityValuedModelPart entityValuedModelPart;
|
||||
|
||||
private final DomainResult identifierResult;
|
||||
private final BasicResult discriminatorResult;
|
||||
private final List<Fetch> fetches;
|
||||
|
||||
private final String resultAlias;
|
||||
private final LockMode lockMode;
|
||||
|
||||
public EntityResultImpl(
|
||||
NavigablePath navigablePath,
|
||||
EntityValuedModelPart entityValuedModelPart,
|
||||
String resultAlias,
|
||||
LockMode lockMode,
|
||||
DomainResult identifierResult,
|
||||
BasicResult discriminatorResult,
|
||||
Function<FetchParent,List<Fetch>> fetchesProducer) {
|
||||
this.navigablePath = navigablePath;
|
||||
this.entityValuedModelPart = entityValuedModelPart;
|
||||
this.resultAlias = resultAlias;
|
||||
this.lockMode = lockMode;
|
||||
this.identifierResult = identifierResult;
|
||||
this.discriminatorResult = discriminatorResult;
|
||||
|
||||
this.fetches = fetchesProducer.apply( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigablePath getNavigablePath() {
|
||||
return navigablePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityValuedModelPart getReferencedMappingType() {
|
||||
return entityValuedModelPart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityValuedModelPart getEntityValuedModelPart() {
|
||||
return entityValuedModelPart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResultVariable() {
|
||||
return resultAlias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Fetch> getFetches() {
|
||||
return fetches;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fetch findFetch(Fetchable fetchable) {
|
||||
for ( int i = 0; i < fetches.size(); i++ ) {
|
||||
if ( fetches.get( i ).getFetchedMapping() == fetchable ) {
|
||||
return fetches.get( i );
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
|
||||
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
|
||||
getNavigablePath(),
|
||||
getReferencedModePart(),
|
||||
() -> new EntityResultInitializer(
|
||||
this,
|
||||
getNavigablePath(),
|
||||
lockMode,
|
||||
identifierResult,
|
||||
discriminatorResult,
|
||||
null,
|
||||
null,
|
||||
creationState
|
||||
)
|
||||
);
|
||||
|
||||
return new EntityAssembler( getResultJavaTypeDescriptor(), initializer );
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.query.results.complete;
|
||||
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.results.FetchBuilder;
|
||||
import org.hibernate.query.results.ResultBuilder;
|
||||
|
||||
|
@ -17,10 +18,10 @@ import org.hibernate.query.results.ResultBuilder;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ModelPartReference {
|
||||
NavigablePath getNavigablePath();
|
||||
|
||||
/**
|
||||
* The part of the domain model that is referenced
|
||||
*/
|
||||
ModelPart getReferencedPart();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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.query.results.complete;
|
||||
|
||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ModelPartReferenceBasic extends ModelPartReference {
|
||||
@Override
|
||||
BasicValuedModelPart getReferencedPart();
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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.query.results.complete;
|
||||
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ModelPartReferenceCollection extends ModelPartReference {
|
||||
@Override
|
||||
PluralAttributeMapping getReferencedPart();
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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.query.results.complete;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ModelPartReferenceEmbeddable extends ModelPartReference {
|
||||
@Override
|
||||
EmbeddableValuedModelPart getReferencedPart();
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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.query.results.complete;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ModelPartReferenceEntity extends ModelPartReference {
|
||||
@Override
|
||||
EntityValuedModelPart getReferencedPart();
|
||||
}
|
|
@ -8,15 +8,13 @@ package org.hibernate.query.results.dynamic;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.query.NativeQuery;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.results.FromClauseAccessImpl;
|
||||
import org.hibernate.query.results.DomainResultCreationStateImpl;
|
||||
import org.hibernate.query.results.ResultsHelper;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
|
@ -64,11 +62,10 @@ public class DynamicFetchBuilderLegacy implements DynamicFetchBuilder, NativeQue
|
|||
NavigablePath fetchPath,
|
||||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState) {
|
||||
final FromClauseAccessImpl fromClauseAccess = ResultsHelper.extractFromClauseAccess( domainResultCreationState );
|
||||
final DomainResultCreationStateImpl creationState = ResultsHelper.impl( domainResultCreationState );
|
||||
|
||||
final TableGroup ownerTableGroup = fromClauseAccess.findByAlias( ownerTableAlias );
|
||||
final TableGroup ownerTableGroup = creationState.getFromClauseAccess().findByAlias( ownerTableAlias );
|
||||
|
||||
// todo (6.0) : create the TableGroupJoin for the fetch and then build the fetch
|
||||
|
||||
|
|
|
@ -9,14 +9,12 @@ package org.hibernate.query.results.dynamic;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.query.NativeQuery;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.results.FromClauseAccessImpl;
|
||||
import org.hibernate.query.results.DomainResultCreationStateImpl;
|
||||
import org.hibernate.query.results.ResultsHelper;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
|
@ -47,11 +45,10 @@ public class DynamicFetchBuilderStandard
|
|||
NavigablePath fetchPath,
|
||||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState) {
|
||||
final FromClauseAccessImpl fromClauseAccess = ResultsHelper.extractFromClauseAccess( domainResultCreationState );
|
||||
final DomainResultCreationStateImpl creationStateImpl = ResultsHelper.impl( domainResultCreationState );
|
||||
|
||||
final TableGroup ownerTableGroup = fromClauseAccess.getTableGroup( parent.getNavigablePath() );
|
||||
final TableGroup ownerTableGroup = creationStateImpl.getFromClauseAccess().getTableGroup( parent.getNavigablePath() );
|
||||
|
||||
// todo (6.0) : create the TableGroupJoin for the fetch and then build the fetch
|
||||
|
||||
|
|
|
@ -8,12 +8,12 @@ package org.hibernate.query.results.dynamic;
|
|||
|
||||
import java.util.Locale;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.BasicValuedSingularAttributeMapping;
|
||||
import org.hibernate.query.results.ResultsHelper;
|
||||
import org.hibernate.query.results.SqlSelectionImpl;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
|
@ -59,15 +59,21 @@ public class DynamicResultBuilderAttribute implements DynamicResultBuilder {
|
|||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
int resultPosition,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState) {
|
||||
final int resultSetPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias );
|
||||
final int valuesArrayPosition = resultSetPosition - 1;
|
||||
|
||||
// todo (6.0) : TableGroups + `attributeMapping#buldResult`
|
||||
|
||||
final SqlSelectionImpl sqlSelection = new SqlSelectionImpl( valuesArrayPosition, attributeMapping );
|
||||
sqlSelectionConsumer.accept( sqlSelection );
|
||||
final SqlExpressionResolver sqlExpressionResolver = domainResultCreationState.getSqlAstCreationState().getSqlExpressionResolver();
|
||||
sqlExpressionResolver.resolveSqlSelection(
|
||||
sqlExpressionResolver.resolveSqlExpression(
|
||||
columnAlias,
|
||||
state -> new SqlSelectionImpl( valuesArrayPosition, attributeMapping )
|
||||
),
|
||||
attributeMapping.getJavaTypeDescriptor(),
|
||||
domainResultCreationState.getSqlAstCreationState().getCreationContext().getSessionFactory().getTypeConfiguration()
|
||||
);
|
||||
|
||||
return new BasicResult<>(
|
||||
valuesArrayPosition,
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
package org.hibernate.query.results.dynamic;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import javax.persistence.AttributeConverter;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
|
@ -19,7 +18,7 @@ import org.hibernate.query.results.SqlSelectionImpl;
|
|||
import org.hibernate.resource.beans.spi.ManagedBean;
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||
import org.hibernate.resource.beans.spi.ProvidedInstanceManagedBeanImpl;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||
|
@ -97,7 +96,6 @@ public class DynamicResultBuilderBasicConverted<O,R> implements DynamicResultBui
|
|||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
int resultPosition,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState) {
|
||||
final int currentJdbcPosition = resultPosition + 1;
|
||||
|
||||
|
@ -121,8 +119,11 @@ public class DynamicResultBuilderBasicConverted<O,R> implements DynamicResultBui
|
|||
|
||||
final int valuesArrayPosition = ResultsHelper.jdbcPositionToValuesArrayPosition( jdbcPosition );
|
||||
|
||||
final SqlSelectionImpl sqlSelection = new SqlSelectionImpl( valuesArrayPosition, (BasicValuedMapping) basicType );
|
||||
sqlSelectionConsumer.accept( sqlSelection );
|
||||
final SqlExpressionResolver sqlExpressionResolver = domainResultCreationState.getSqlAstCreationState().getSqlExpressionResolver();
|
||||
sqlExpressionResolver.resolveSqlExpression(
|
||||
columnAlias,
|
||||
state -> new SqlSelectionImpl( valuesArrayPosition, (BasicValuedMapping) basicType )
|
||||
);
|
||||
|
||||
//noinspection unchecked
|
||||
return new BasicResult( valuesArrayPosition, columnAlias, domainJtd, basicValueConverter );
|
||||
|
|
|
@ -7,13 +7,12 @@
|
|||
package org.hibernate.query.results.dynamic;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.query.results.ResultsHelper;
|
||||
import org.hibernate.query.results.SqlSelectionImpl;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||
|
@ -76,7 +75,6 @@ public class DynamicResultBuilderBasicStandard implements DynamicResultBuilderBa
|
|||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
int resultPosition,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState) {
|
||||
final SessionFactoryImplementor sessionFactory = domainResultCreationState.getSqlAstCreationState()
|
||||
.getCreationContext()
|
||||
|
@ -106,8 +104,15 @@ public class DynamicResultBuilderBasicStandard implements DynamicResultBuilderBa
|
|||
basicType = typeConfiguration.getBasicTypeRegistry().resolve( javaTypeDescriptor, sqlTypeDescriptor );
|
||||
}
|
||||
|
||||
final SqlSelectionImpl sqlSelection = new SqlSelectionImpl( valuesArrayPosition, (BasicValuedMapping) basicType );
|
||||
sqlSelectionConsumer.accept( sqlSelection );
|
||||
final SqlExpressionResolver sqlExpressionResolver = domainResultCreationState.getSqlAstCreationState().getSqlExpressionResolver();
|
||||
sqlExpressionResolver.resolveSqlSelection(
|
||||
sqlExpressionResolver.resolveSqlExpression(
|
||||
columnName,
|
||||
state -> new SqlSelectionImpl( valuesArrayPosition, (BasicValuedMapping) basicType )
|
||||
),
|
||||
basicType.getJavaTypeDescriptor(),
|
||||
sessionFactory.getTypeConfiguration()
|
||||
);
|
||||
|
||||
return new BasicResult<>( valuesArrayPosition, resultAlias, explicitJavaTypeDescriptor );
|
||||
}
|
||||
|
|
|
@ -7,10 +7,8 @@
|
|||
package org.hibernate.query.results.dynamic;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.query.results.ResultBuilderEntityValued;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.entity.EntityResult;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||
|
@ -24,6 +22,5 @@ public interface DynamicResultBuilderEntity extends DynamicResultBuilder, Result
|
|||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
int resultPosition,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState);
|
||||
}
|
||||
|
|
|
@ -7,16 +7,14 @@
|
|||
package org.hibernate.query.results.dynamic;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.results.FromClauseAccessImpl;
|
||||
import org.hibernate.query.results.DomainResultCreationStateImpl;
|
||||
import org.hibernate.query.results.ResultsHelper;
|
||||
import org.hibernate.query.results.TableGroupImpl;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.entity.EntityResult;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||
|
@ -54,9 +52,8 @@ public class DynamicResultBuilderEntityCalculated implements DynamicResultBuilde
|
|||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
int resultPosition,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState) {
|
||||
final FromClauseAccessImpl fromClauseAccess = ResultsHelper.extractFromClauseAccess( domainResultCreationState );
|
||||
final DomainResultCreationStateImpl creationStateImpl = ResultsHelper.impl( domainResultCreationState );
|
||||
|
||||
TableGroupImpl.TableReferenceImpl tableReference = new TableGroupImpl.TableReferenceImpl(
|
||||
entityMapping.getEntityName(),
|
||||
|
@ -73,7 +70,7 @@ public class DynamicResultBuilderEntityCalculated implements DynamicResultBuilde
|
|||
explicitLockMode
|
||||
);
|
||||
|
||||
fromClauseAccess.registerTableGroup( navigablePath, tableGroup );
|
||||
creationStateImpl.getFromClauseAccess().registerTableGroup( navigablePath, tableGroup );
|
||||
|
||||
return (EntityResult) entityMapping.createDomainResult(
|
||||
navigablePath,
|
||||
|
|
|
@ -7,14 +7,12 @@
|
|||
package org.hibernate.query.results.dynamic;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.query.NativeQuery;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.entity.EntityResult;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||
|
@ -64,7 +62,6 @@ public class DynamicResultBuilderEntityStandard
|
|||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
int resultPosition,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState) {
|
||||
// final FromClauseAccessImpl fromClauseAccess = ResultsHelper.extractFromClauseAccess( domainResultCreationState );
|
||||
// final TableGroup tableGroup = fromClauseAccess.resolveTableGroup(
|
||||
|
|
|
@ -9,13 +9,11 @@ package org.hibernate.query.results.dynamic;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.query.DynamicInstantiationNature;
|
||||
import org.hibernate.query.NativeQuery;
|
||||
import org.hibernate.query.results.Builders;
|
||||
import org.hibernate.query.results.ResultBuilderInstantiationValued;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.instantiation.internal.ArgumentDomainResult;
|
||||
|
@ -59,7 +57,6 @@ public class DynamicResultBuilderInstantiation<J>
|
|||
JdbcValuesMetadata jdbcResultsMetadata,
|
||||
int resultPosition,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
|
||||
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||
DomainResultCreationState domainResultCreationState) {
|
||||
if ( argumentResultBuilders.isEmpty() ) {
|
||||
throw new IllegalStateException( "DynamicResultBuilderInstantiation defined no arguments" );
|
||||
|
@ -70,12 +67,11 @@ public class DynamicResultBuilderInstantiation<J>
|
|||
for ( int i = 0; i < argumentResultBuilders.size(); i++ ) {
|
||||
final InstantiationArgument argument = argumentResultBuilders.get( i );
|
||||
|
||||
final ArgumentDomainResult<Object> argumentDomainResult = new ArgumentDomainResult<>(
|
||||
final ArgumentDomainResult<?> argumentDomainResult = new ArgumentDomainResult(
|
||||
argument.argumentBuilder.buildResult(
|
||||
jdbcResultsMetadata,
|
||||
i,
|
||||
legacyFetchResolver,
|
||||
sqlSelectionConsumer,
|
||||
domainResultCreationState
|
||||
)
|
||||
);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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.query.results.dynamic;
|
||||
|
||||
/**
|
||||
* Contract for handling Hibernate's legacy way of representing fetches through
|
||||
* {@link org.hibernate.query.NativeQuery#addFetch}, {@link org.hibernate.query.NativeQuery#addJoin},
|
||||
* `hbm.xml` mappings, etc
|
||||
*
|
||||
* @see org.hibernate.query.results.DomainResultCreationStateImpl#getLegacyFetchResolver()
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface LegacyFetchResolver {
|
||||
DynamicFetchBuilderLegacy resolve(String ownerTableAlias, String fetchedPartPath);
|
||||
}
|
|
@ -63,9 +63,9 @@ import org.hibernate.query.named.NamedResultSetMappingMemento;
|
|||
import org.hibernate.query.results.Builders;
|
||||
import org.hibernate.query.results.ResultBuilder;
|
||||
import org.hibernate.query.results.ResultSetMappingImpl;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.query.results.dynamic.DynamicResultBuilderEntityStandard;
|
||||
import org.hibernate.query.results.dynamic.DynamicResultBuilderInstantiation;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.query.spi.AbstractQuery;
|
||||
import org.hibernate.query.spi.MutableQueryOptions;
|
||||
import org.hibernate.query.spi.NonSelectQueryPlan;
|
||||
|
@ -105,12 +105,12 @@ public class NativeQueryImpl<R>
|
|||
private final List<QueryParameterImplementor<?>> occurrenceOrderedParamList;
|
||||
private final QueryParameterBindings parameterBindings;
|
||||
|
||||
private final ResultSetMappingImpl resultSetMapping;
|
||||
|
||||
private final QueryOptionsImpl queryOptions = new QueryOptionsImpl();
|
||||
|
||||
private Set<String> querySpaces;
|
||||
|
||||
private ResultSetMappingImpl resultSetMapping = new ResultSetMappingImpl();
|
||||
|
||||
private Object collectionKey;
|
||||
private NativeQueryInterpreter nativeQueryInterpreter;
|
||||
|
||||
|
@ -125,11 +125,30 @@ public class NativeQueryImpl<R>
|
|||
this.sqlString = memento.getSqlString();
|
||||
|
||||
final ParameterInterpretation parameterInterpretation = resolveParameterInterpretation( session );
|
||||
|
||||
this.parameterMetadata = parameterInterpretation.toParameterMetadata( session );
|
||||
this.occurrenceOrderedParamList = parameterInterpretation.getOccurrenceOrderedParameters();
|
||||
this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() );
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( sqlString );
|
||||
|
||||
applyOptions( memento );
|
||||
}
|
||||
|
||||
private NativeQueryImpl(
|
||||
String resultMappingIdentifier,
|
||||
NamedNativeQueryMemento memento,
|
||||
SharedSessionContractImplementor session) {
|
||||
super( session );
|
||||
|
||||
this.sqlString = memento.getSqlString();
|
||||
|
||||
final ParameterInterpretation parameterInterpretation = resolveParameterInterpretation( session );
|
||||
this.parameterMetadata = parameterInterpretation.toParameterMetadata( session );
|
||||
this.occurrenceOrderedParamList = parameterInterpretation.getOccurrenceOrderedParameters();
|
||||
this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() );
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( resultMappingIdentifier );
|
||||
|
||||
applyOptions( memento );
|
||||
}
|
||||
|
||||
|
@ -155,7 +174,7 @@ public class NativeQueryImpl<R>
|
|||
NamedNativeQueryMemento memento,
|
||||
String resultSetMappingName,
|
||||
SharedSessionContractImplementor session) {
|
||||
this( memento, session );
|
||||
this( resultSetMappingName, memento, session );
|
||||
|
||||
session.getFactory()
|
||||
.getQueryEngine()
|
||||
|
@ -171,6 +190,8 @@ public class NativeQueryImpl<R>
|
|||
super( session );
|
||||
|
||||
this.sqlString = sqlString;
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( resultSetMappingMemento.getName() );
|
||||
resultSetMappingMemento.resolve( resultSetMapping, (s) -> {}, this );
|
||||
|
||||
final ParameterInterpretation parameterInterpretation = resolveParameterInterpretation( session );
|
||||
|
@ -231,6 +252,8 @@ public class NativeQueryImpl<R>
|
|||
this.parameterMetadata = parameterInterpretation.toParameterMetadata( session );
|
||||
this.occurrenceOrderedParamList = parameterInterpretation.getOccurrenceOrderedParameters();
|
||||
this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() );
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( sqlString );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.hibernate.internal.util.collections.CollectionHelper;
|
|||
import org.hibernate.internal.util.collections.Stack;
|
||||
import org.hibernate.internal.util.collections.StandardStack;
|
||||
import org.hibernate.loader.MultipleBagFetchException;
|
||||
import org.hibernate.metamodel.CollectionClassification;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
|
@ -294,12 +295,16 @@ public class StandardSqmSelectTranslator
|
|||
final Fetch fetch = buildFetch( fetchablePath, fetchParent, fetchable, isKeyFetchable );
|
||||
|
||||
if ( fetch != null ) {
|
||||
if ( fetch.getTiming() == FetchTiming.IMMEDIATE &&
|
||||
fetchable instanceof PluralAttributeMapping &&
|
||||
( (PluralAttributeMapping) fetchable ).getMappedTypeDescriptor()
|
||||
.getCollectionSemantics() instanceof BagSemantics ) {
|
||||
bagRoles.add( fetchable.getNavigableRole().getNavigableName() );
|
||||
if ( fetch.getTiming() == FetchTiming.IMMEDIATE && fetchable instanceof PluralAttributeMapping ) {
|
||||
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) fetchable;
|
||||
final CollectionClassification collectionClassification = pluralAttributeMapping.getMappedTypeDescriptor()
|
||||
.getCollectionSemantics()
|
||||
.getCollectionClassification();
|
||||
if ( collectionClassification == CollectionClassification.BAG ) {
|
||||
bagRoles.add( fetchable.getNavigableRole().getNavigableName() );
|
||||
}
|
||||
}
|
||||
|
||||
fetches.add( fetch );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,13 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface DomainResultGraphNode {
|
||||
/**
|
||||
* Does this node contain any non-scalar (sub-)results?
|
||||
*/
|
||||
default boolean containsAnyNonScalarResults() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// todo (6.0) : result variable (selection alias)? - even fetches can have alias
|
||||
|
||||
JavaTypeDescriptor getResultJavaTypeDescriptor();
|
||||
|
|
|
@ -56,8 +56,13 @@ public interface Fetch extends DomainResultGraphNode {
|
|||
*/
|
||||
boolean hasTableGroup();
|
||||
|
||||
@Override
|
||||
default boolean containsAnyNonScalarResults() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the assembler for this fetch
|
||||
*/
|
||||
DomainResultAssembler createAssembler(FetchParentAccess parentAccess, AssemblerCreationState creationState);
|
||||
DomainResultAssembler<?> createAssembler(FetchParentAccess parentAccess, AssemblerCreationState creationState);
|
||||
}
|
||||
|
|
|
@ -73,6 +73,11 @@ public class CollectionDomainResult implements DomainResult, CollectionResultGra
|
|||
return resultVariable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAnyNonScalarResults() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor getResultJavaTypeDescriptor() {
|
||||
return loadingAttribute.getJavaTypeDescriptor();
|
||||
|
|
|
@ -61,6 +61,11 @@ public class EmbeddableForeignKeyResultImpl<T>
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAnyNonScalarResults() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void generateFetches(
|
||||
List<SqlSelection> sqlSelections,
|
||||
NavigablePath navigablePath,
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
*/
|
||||
package org.hibernate.sql.results.graph.embeddable.internal;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
|
@ -18,6 +20,8 @@ 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.DomainResultGraphNode;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableInitializer;
|
||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
@ -27,6 +31,7 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
|||
*/
|
||||
public class EmbeddableResultImpl<T> extends AbstractFetchParent implements EmbeddableResultGraphNode, DomainResult<T> {
|
||||
private final String resultVariable;
|
||||
private final boolean containsAnyNonScalars;
|
||||
|
||||
public EmbeddableResultImpl(
|
||||
NavigablePath navigablePath,
|
||||
|
@ -56,6 +61,19 @@ public class EmbeddableResultImpl<T> extends AbstractFetchParent implements Embe
|
|||
);
|
||||
|
||||
afterInitialize( creationState );
|
||||
|
||||
// after-after-initialize :D
|
||||
containsAnyNonScalars = determineIfContainedAnyScalars( fetches );
|
||||
}
|
||||
|
||||
private static boolean determineIfContainedAnyScalars(List<Fetch> fetches) {
|
||||
for ( int i = 0; i < fetches.size(); i++ ) {
|
||||
if ( fetches.get( i ).containsAnyNonScalarResults() ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -63,6 +81,11 @@ public class EmbeddableResultImpl<T> extends AbstractFetchParent implements Embe
|
|||
return resultVariable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAnyNonScalarResults() {
|
||||
return containsAnyNonScalars;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getFetchContainer() {
|
||||
return (EmbeddableMappingType) super.getFetchContainer();
|
||||
|
|
|
@ -12,4 +12,8 @@ import org.hibernate.sql.results.graph.Fetch;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface EntityFetch extends EntityResultGraphNode, Fetch {
|
||||
@Override
|
||||
default boolean containsAnyNonScalarResults() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,10 @@ public interface EntityResultGraphNode extends DomainResultGraphNode, FetchParen
|
|||
NavigablePath getNavigablePath();
|
||||
|
||||
EntityValuedModelPart getEntityValuedModelPart();
|
||||
@Override
|
||||
default boolean containsAnyNonScalarResults() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
default JavaTypeDescriptor getResultJavaTypeDescriptor() {
|
||||
|
|
|
@ -14,9 +14,9 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ArgumentDomainResult<A> implements DomainResult<A> {
|
||||
private final DomainResult realDomainResult;
|
||||
private final DomainResult<A> realDomainResult;
|
||||
|
||||
public ArgumentDomainResult(DomainResult realDomainResult) {
|
||||
public ArgumentDomainResult(DomainResult<A> realDomainResult) {
|
||||
this.realDomainResult = realDomainResult;
|
||||
}
|
||||
|
||||
|
@ -26,15 +26,19 @@ public class ArgumentDomainResult<A> implements DomainResult<A> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAnyNonScalarResults() {
|
||||
return realDomainResult.containsAnyNonScalarResults();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
public JavaTypeDescriptor getResultJavaTypeDescriptor() {
|
||||
return realDomainResult.getResultJavaTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArgumentReader<A> createResultAssembler(
|
||||
AssemblerCreationState creationState) {
|
||||
//noinspection unchecked
|
||||
return new ArgumentReader(
|
||||
public ArgumentReader<A> createResultAssembler(AssemblerCreationState creationState) {
|
||||
return new ArgumentReader<>(
|
||||
realDomainResult.createResultAssembler( creationState ),
|
||||
getResultVariable()
|
||||
);
|
||||
|
|
|
@ -22,12 +22,12 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
|||
public class DynamicInstantiationAssemblerConstructorImpl<R> implements DomainResultAssembler<R> {
|
||||
private final Constructor<R> targetConstructor;
|
||||
private final JavaTypeDescriptor<R> resultType;
|
||||
private final List<ArgumentReader> argumentReaders;
|
||||
private final List<ArgumentReader<?>> argumentReaders;
|
||||
|
||||
public DynamicInstantiationAssemblerConstructorImpl(
|
||||
Constructor<R> targetConstructor,
|
||||
JavaTypeDescriptor<R> resultType,
|
||||
List<ArgumentReader> argumentReaders) {
|
||||
List<ArgumentReader<?>> argumentReaders) {
|
||||
this.targetConstructor = targetConstructor;
|
||||
this.resultType = resultType;
|
||||
this.argumentReaders = argumentReaders;
|
||||
|
|
|
@ -14,8 +14,6 @@ import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
|
|||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* A QueryResultAssembler implementation representing handling for dynamic-
|
||||
* instantiations targeting a List (per-"row"),
|
||||
|
@ -24,30 +22,28 @@ import org.jboss.logging.Logger;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DynamicInstantiationAssemblerListImpl implements DomainResultAssembler<List> {
|
||||
private static final Logger log = Logger.getLogger( DynamicInstantiationAssemblerListImpl.class );
|
||||
|
||||
private final JavaTypeDescriptor<List> listJavaDescriptor;
|
||||
public class DynamicInstantiationAssemblerListImpl implements DomainResultAssembler<List<?>> {
|
||||
private final JavaTypeDescriptor<List<?>> listJavaDescriptor;
|
||||
private final List<ArgumentReader<?>> argumentReaders;
|
||||
|
||||
public DynamicInstantiationAssemblerListImpl(
|
||||
JavaTypeDescriptor<List> listJavaDescriptor,
|
||||
JavaTypeDescriptor<List<?>> listJavaDescriptor,
|
||||
List<ArgumentReader<?>> argumentReaders) {
|
||||
this.listJavaDescriptor = listJavaDescriptor;
|
||||
this.argumentReaders = argumentReaders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor<List> getAssembledJavaTypeDescriptor() {
|
||||
public JavaTypeDescriptor<List<?>> getAssembledJavaTypeDescriptor() {
|
||||
return listJavaDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List assemble(
|
||||
public List<?> assemble(
|
||||
RowProcessingState rowProcessingState,
|
||||
JdbcValuesSourceProcessingOptions options) {
|
||||
final ArrayList<Object> result = new ArrayList<>();
|
||||
for ( ArgumentReader argumentReader : argumentReaders ) {
|
||||
for ( ArgumentReader<?> argumentReader : argumentReaders ) {
|
||||
result.add( argumentReader.assemble( rowProcessingState, options ) );
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -24,18 +24,18 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DynamicInstantiationAssemblerMapImpl implements DomainResultAssembler<Map> {
|
||||
private final JavaTypeDescriptor<Map> mapJavaDescriptor;
|
||||
public class DynamicInstantiationAssemblerMapImpl implements DomainResultAssembler<Map<?,?>> {
|
||||
private final JavaTypeDescriptor<Map<?,?>> mapJavaDescriptor;
|
||||
private final List<ArgumentReader<?>> argumentReaders;
|
||||
|
||||
public DynamicInstantiationAssemblerMapImpl(
|
||||
JavaTypeDescriptor<Map> mapJavaDescriptor,
|
||||
JavaTypeDescriptor<Map<?,?>> mapJavaDescriptor,
|
||||
List<ArgumentReader<?>> argumentReaders) {
|
||||
this.mapJavaDescriptor = mapJavaDescriptor;
|
||||
this.argumentReaders = argumentReaders;
|
||||
|
||||
final Set<String> aliases = new HashSet<>();
|
||||
for ( ArgumentReader argumentReader : argumentReaders ) {
|
||||
for ( ArgumentReader<?> argumentReader : argumentReaders ) {
|
||||
if ( argumentReader.getAlias() == null ) {
|
||||
throw new IllegalStateException( "alias for Map dynamic instantiation argument cannot be null" );
|
||||
}
|
||||
|
@ -48,17 +48,17 @@ public class DynamicInstantiationAssemblerMapImpl implements DomainResultAssembl
|
|||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor<Map> getAssembledJavaTypeDescriptor() {
|
||||
public JavaTypeDescriptor<Map<?,?>> getAssembledJavaTypeDescriptor() {
|
||||
return mapJavaDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map assemble(
|
||||
public Map<?,?> assemble(
|
||||
RowProcessingState rowProcessingState,
|
||||
JdbcValuesSourceProcessingOptions options) {
|
||||
final HashMap<String,Object> result = new HashMap<>();
|
||||
|
||||
for ( ArgumentReader argumentReader : argumentReaders ) {
|
||||
for ( ArgumentReader<?> argumentReader : argumentReaders ) {
|
||||
result.put(
|
||||
argumentReader.getAlias(),
|
||||
argumentReader.assemble( rowProcessingState, options )
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.lang.reflect.Constructor;
|
|||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
|
@ -32,13 +33,13 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
|
|||
|
||||
private final DynamicInstantiationNature nature;
|
||||
private final JavaTypeDescriptor<R> javaTypeDescriptor;
|
||||
private final List<ArgumentDomainResult> argumentResults;
|
||||
private final List<ArgumentDomainResult<?>> argumentResults;
|
||||
|
||||
public DynamicInstantiationResultImpl(
|
||||
String resultVariable,
|
||||
DynamicInstantiationNature nature,
|
||||
JavaTypeDescriptor<R> javaTypeDescriptor,
|
||||
List<ArgumentDomainResult> argumentResults) {
|
||||
List<ArgumentDomainResult<?>> argumentResults) {
|
||||
this.resultVariable = resultVariable;
|
||||
this.nature = nature;
|
||||
this.javaTypeDescriptor = javaTypeDescriptor;
|
||||
|
@ -46,7 +47,7 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
|
|||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor getResultJavaTypeDescriptor() {
|
||||
public JavaTypeDescriptor<R> getResultJavaTypeDescriptor() {
|
||||
return javaTypeDescriptor;
|
||||
}
|
||||
|
||||
|
@ -55,6 +56,19 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
|
|||
return resultVariable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAnyNonScalarResults() {
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for ( int i = 0; i < argumentResults.size(); i++ ) {
|
||||
final ArgumentDomainResult<?> argumentResult = argumentResults.get( i );
|
||||
if ( argumentResult.containsAnyNonScalarResults() ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainResultAssembler<R> createResultAssembler(AssemblerCreationState creationState) {
|
||||
boolean areAllArgumentsAliased = true;
|
||||
|
@ -64,7 +78,7 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
|
|||
final List<ArgumentReader<?>> argumentReaders = new ArrayList<>();
|
||||
|
||||
if ( argumentResults != null ) {
|
||||
for ( ArgumentDomainResult argumentResult : argumentResults ) {
|
||||
for ( ArgumentDomainResult<?> argumentResult : argumentResults ) {
|
||||
final String argumentAlias = argumentResult.getResultVariable();
|
||||
if ( argumentAlias == null ) {
|
||||
areAllArgumentsAliased = false;
|
||||
|
@ -107,7 +121,7 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
|
|||
log.debug( "One or more arguments for List dynamic instantiation (`new list(...)`) specified an alias; ignoring" );
|
||||
}
|
||||
return (DomainResultAssembler<R>) new DynamicInstantiationAssemblerListImpl(
|
||||
(JavaTypeDescriptor<List>) javaTypeDescriptor,
|
||||
(JavaTypeDescriptor<List<?>>) javaTypeDescriptor,
|
||||
argumentReaders
|
||||
);
|
||||
}
|
||||
|
@ -121,21 +135,21 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
|
|||
);
|
||||
}
|
||||
return (DomainResultAssembler<R>) new DynamicInstantiationAssemblerMapImpl(
|
||||
(JavaTypeDescriptor) javaTypeDescriptor,
|
||||
(JavaTypeDescriptor<Map<?,?>>) javaTypeDescriptor,
|
||||
argumentReaders
|
||||
);
|
||||
}
|
||||
else {
|
||||
// find a constructor matching argument types
|
||||
constructor_loop:
|
||||
for ( Constructor constructor : javaTypeDescriptor.getJavaType().getDeclaredConstructors() ) {
|
||||
for ( Constructor<?> constructor : javaTypeDescriptor.getJavaType().getDeclaredConstructors() ) {
|
||||
if ( constructor.getParameterTypes().length != argumentReaders.size() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < argumentReaders.size(); i++ ) {
|
||||
final ArgumentReader argumentReader = argumentReaders.get( i );
|
||||
final JavaTypeDescriptor argumentTypeDescriptor = creationState.getSqlAstCreationContext()
|
||||
final ArgumentReader<?> argumentReader = argumentReaders.get( i );
|
||||
final JavaTypeDescriptor<?> argumentTypeDescriptor = creationState.getSqlAstCreationContext()
|
||||
.getDomainModel()
|
||||
.getTypeConfiguration()
|
||||
.getJavaTypeDescriptorRegistry()
|
||||
|
@ -159,6 +173,7 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
|
|||
}
|
||||
|
||||
constructor.setAccessible( true );
|
||||
//noinspection rawtypes
|
||||
return new DynamicInstantiationAssemblerConstructorImpl(
|
||||
constructor,
|
||||
javaTypeDescriptor,
|
||||
|
@ -185,7 +200,10 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
|
|||
);
|
||||
}
|
||||
|
||||
return new DynamicInstantiationAssemblerInjectionImpl( javaTypeDescriptor, argumentReaders );
|
||||
return new DynamicInstantiationAssemblerInjectionImpl<>(
|
||||
javaTypeDescriptor,
|
||||
argumentReaders
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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.instantiation.internal;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class InstantiationHelper {
|
||||
|
||||
private InstantiationHelper() {
|
||||
// disallow direct instantiation
|
||||
}
|
||||
}
|
|
@ -6,10 +6,12 @@
|
|||
*/
|
||||
package org.hibernate.orm.test.query.named.resultmapping;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.ColumnResult;
|
||||
import javax.persistence.ConstructorResult;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityResult;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.FieldResult;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.SqlResultSetMapping;
|
||||
|
@ -40,7 +42,7 @@ import javax.persistence.SqlResultSetMapping;
|
|||
)
|
||||
)
|
||||
@SqlResultSetMapping(
|
||||
name = "entity",
|
||||
name = "entity-id-name",
|
||||
entities = @EntityResult(
|
||||
entityClass = SimpleEntityWithNamedMappings.class,
|
||||
fields = {
|
||||
|
@ -49,18 +51,45 @@ import javax.persistence.SqlResultSetMapping;
|
|||
}
|
||||
)
|
||||
)
|
||||
@SqlResultSetMapping(
|
||||
name = "entity-id-notes",
|
||||
entities = @EntityResult(
|
||||
entityClass = SimpleEntityWithNamedMappings.class,
|
||||
fields = {
|
||||
@FieldResult( name = "id", column = "id" ),
|
||||
@FieldResult( name = "notes", column = "notes" )
|
||||
}
|
||||
)
|
||||
)
|
||||
@SqlResultSetMapping(
|
||||
name = "entity",
|
||||
entities = @EntityResult(
|
||||
entityClass = SimpleEntityWithNamedMappings.class,
|
||||
fields = {
|
||||
@FieldResult( name = "id", column = "id" ),
|
||||
@FieldResult( name = "name", column = "name" ),
|
||||
@FieldResult( name = "notes", column = "notes" )
|
||||
}
|
||||
)
|
||||
)
|
||||
public class SimpleEntityWithNamedMappings {
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
private String notes;
|
||||
|
||||
protected SimpleEntityWithNamedMappings() {
|
||||
}
|
||||
|
||||
public SimpleEntityWithNamedMappings(Integer id, String name) {
|
||||
this( id, name, null );
|
||||
}
|
||||
|
||||
public SimpleEntityWithNamedMappings(Integer id, String name, String notes) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.notes = notes;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
|
@ -79,6 +108,15 @@ public class SimpleEntityWithNamedMappings {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
@Basic( fetch = FetchType.LAZY )
|
||||
public String getNotes() {
|
||||
return notes;
|
||||
}
|
||||
|
||||
public void setNotes(String notes) {
|
||||
this.notes = notes;
|
||||
}
|
||||
|
||||
public static class DropDownDto {
|
||||
private final Integer id;
|
||||
private final String text;
|
||||
|
|
|
@ -34,7 +34,7 @@ public class SimpleNamedMappingTests {
|
|||
final NamedQueryRepository namedQueryRepository = queryEngine.getNamedQueryRepository();
|
||||
final NamedResultSetMappingMemento mappingMemento = namedQueryRepository.getResultSetMappingMemento( "name" );
|
||||
|
||||
final ResultSetMapping mapping = new ResultSetMappingImpl();
|
||||
final ResultSetMapping mapping = new ResultSetMappingImpl( "test" );
|
||||
|
||||
final ResultSetMappingResolutionContext resolutionContext = new ResultSetMappingResolutionContext() {
|
||||
@Override
|
||||
|
|
|
@ -78,7 +78,6 @@ public class UsageTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected( reason = "Entity result mappings not yet implemented" )
|
||||
public void testSimpleEntityResultMapping(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
|
@ -90,7 +89,7 @@ public class UsageTests {
|
|||
assertThat( mappingMemento, notNullValue() );
|
||||
|
||||
// apply it to a native-query
|
||||
final String qryString = "select id, name from SimpleEntityWithNamedMappings";
|
||||
final String qryString = "select id, name, notes from SimpleEntityWithNamedMappings";
|
||||
final List<SimpleEntityWithNamedMappings> results
|
||||
= session.createNativeQuery( qryString, "entity" ).list();
|
||||
assertThat( results.size(), is( 1 ) );
|
||||
|
|
Loading…
Reference in New Issue