Embedded collection member of and Embeddable parameter binding
This commit is contained in:
parent
7e87deb349
commit
38753afab6
|
@ -135,6 +135,15 @@ public class InferredBasicValueResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( jdbcMapping == null ) {
|
||||||
|
throw new MappingException(
|
||||||
|
"Could not determine JavaTypeDescriptor nor SqlTypeDescriptor to use" + "" +
|
||||||
|
" for " + ( (BasicValue) stdIndicators ).getResolvedJavaClass() +
|
||||||
|
"; table = " + table.getName() +
|
||||||
|
"; column = " + selectable.getText()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return new InferredBasicValueResolution(
|
return new InferredBasicValueResolution(
|
||||||
jdbcMapping,
|
jdbcMapping,
|
||||||
jdbcMapping.getJavaTypeDescriptor(),
|
jdbcMapping.getJavaTypeDescriptor(),
|
||||||
|
|
|
@ -167,6 +167,10 @@ public class BasicValue extends SimpleValue implements SqlTypeDescriptorIndicato
|
||||||
return column;
|
return column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Class getResolvedJavaClass() {
|
||||||
|
return resolvedJavaClass;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getColumnLength() {
|
public long getColumnLength() {
|
||||||
if ( column != null && column instanceof Column ) {
|
if ( column != null && column instanceof Column ) {
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.hibernate.metamodel.model.domain.internal.MapMember;
|
||||||
import org.hibernate.metamodel.model.domain.internal.MappedSuperclassTypeImpl;
|
import org.hibernate.metamodel.model.domain.internal.MappedSuperclassTypeImpl;
|
||||||
import org.hibernate.metamodel.model.domain.internal.PluralAttributeBuilder;
|
import org.hibernate.metamodel.model.domain.internal.PluralAttributeBuilder;
|
||||||
import org.hibernate.metamodel.model.domain.internal.SingularAttributeImpl;
|
import org.hibernate.metamodel.model.domain.internal.SingularAttributeImpl;
|
||||||
|
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||||
import org.hibernate.metamodel.spi.ManagedTypeRepresentationStrategy;
|
import org.hibernate.metamodel.spi.ManagedTypeRepresentationStrategy;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.property.access.internal.PropertyAccessMapImpl;
|
import org.hibernate.property.access.internal.PropertyAccessMapImpl;
|
||||||
|
@ -244,7 +245,7 @@ public class AttributeFactory {
|
||||||
.getJavaTypeDescriptorRegistry();
|
.getJavaTypeDescriptorRegistry();
|
||||||
final JavaTypeDescriptor javaTypeDescriptor = registry.resolveDescriptor( embeddableClass );
|
final JavaTypeDescriptor javaTypeDescriptor = registry.resolveDescriptor( embeddableClass );
|
||||||
|
|
||||||
final ManagedTypeRepresentationStrategy representationStrategy = context.getTypeConfiguration()
|
final EmbeddableRepresentationStrategy representationStrategy = context.getTypeConfiguration()
|
||||||
.getMetadataBuildingContext()
|
.getMetadataBuildingContext()
|
||||||
.getBuildingOptions()
|
.getBuildingOptions()
|
||||||
.getManagedTypeRepresentationResolver()
|
.getManagedTypeRepresentationResolver()
|
||||||
|
|
|
@ -347,6 +347,9 @@ public class EmbeddableMappingType implements ManagedMappingType {
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
attributeMappings.forEach(
|
attributeMappings.forEach(
|
||||||
(s, attributeMapping) -> {
|
(s, attributeMapping) -> {
|
||||||
|
if ( attributeMapping instanceof PluralAttributeMapping ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if ( attributeMapping instanceof ToOneAttributeMapping ) {
|
if ( attributeMapping instanceof ToOneAttributeMapping ) {
|
||||||
( (ToOneAttributeMapping) attributeMapping ).getKeyTargetMatchPart().visitJdbcTypes(
|
( (ToOneAttributeMapping) attributeMapping ).getKeyTargetMatchPart().visitJdbcTypes(
|
||||||
action,
|
action,
|
||||||
|
|
|
@ -275,6 +275,14 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return propertyAccess.getGetter().get( value );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Fetch generateFetch(
|
public Fetch generateFetch(
|
||||||
FetchParent fetchParent,
|
FetchParent fetchParent,
|
||||||
|
|
|
@ -40,12 +40,14 @@ import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
||||||
import org.hibernate.sql.ast.tree.from.CompositeTableGroup;
|
import org.hibernate.sql.ast.tree.from.CompositeTableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||||
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
import org.hibernate.sql.results.graph.FetchOptions;
|
import org.hibernate.sql.results.graph.FetchOptions;
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
|
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
|
||||||
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
|
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
|
||||||
|
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableResultImpl;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
@ -92,6 +94,20 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
|
||||||
this.sqlAliasStem = sqlAliasStem;
|
this.sqlAliasStem = sqlAliasStem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> DomainResult<T> createDomainResult(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
TableGroup tableGroup,
|
||||||
|
String resultVariable,
|
||||||
|
DomainResultCreationState creationState) {
|
||||||
|
return new EmbeddableResultImpl<>(
|
||||||
|
navigablePath,
|
||||||
|
this,
|
||||||
|
resultVariable,
|
||||||
|
creationState
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Nature getNature() {
|
public Nature getNature() {
|
||||||
return nature;
|
return nature;
|
||||||
|
|
|
@ -11,6 +11,8 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -44,8 +46,8 @@ public abstract class AbstractManagedType<J>
|
||||||
private final ManagedDomainType<? super J> superType;
|
private final ManagedDomainType<? super J> superType;
|
||||||
private final RepresentationMode representationMode;
|
private final RepresentationMode representationMode;
|
||||||
|
|
||||||
private final Map<String, SingularPersistentAttribute<J, ?>> declaredSingularAttributes = new HashMap<>();
|
private final Map<String, SingularPersistentAttribute<J, ?>> declaredSingularAttributes = new LinkedHashMap<>();
|
||||||
private final Map<String, PluralPersistentAttribute<J, ?, ?>> declaredPluralAttributes = new HashMap<>();
|
private final Map<String, PluralPersistentAttribute<J, ?, ?>> declaredPluralAttributes = new LinkedHashMap<>();
|
||||||
|
|
||||||
private final List<ManagedDomainType> subTypes = new ArrayList<>();
|
private final List<ManagedDomainType> subTypes = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -104,7 +106,7 @@ public abstract class AbstractManagedType<J>
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Set<Attribute<? super J, ?>> getAttributes() {
|
public Set<Attribute<? super J, ?>> getAttributes() {
|
||||||
final HashSet attributes = new HashSet<>( getDeclaredAttributes() );
|
final HashSet attributes = new LinkedHashSet( getDeclaredAttributes() );
|
||||||
|
|
||||||
if ( getSuperType() != null ) {
|
if ( getSuperType() != null ) {
|
||||||
attributes.addAll( getSuperType().getAttributes() );
|
attributes.addAll( getSuperType().getAttributes() );
|
||||||
|
@ -120,7 +122,7 @@ public abstract class AbstractManagedType<J>
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
final HashSet attributes = new HashSet<>( declaredSingularAttributes.values() );
|
final HashSet attributes = new LinkedHashSet( declaredSingularAttributes.values() );
|
||||||
attributes.addAll( declaredPluralAttributes.values() );
|
attributes.addAll( declaredPluralAttributes.values() );
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,6 @@ import org.hibernate.metamodel.spi.ManagedTypeRepresentationStrategy;
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface EmbeddableDomainType<J> extends ManagedDomainType<J>, EmbeddableType<J> {
|
public interface EmbeddableDomainType<J> extends ManagedDomainType<J>, EmbeddableType<J>, AllowableParameterType<J> {
|
||||||
ManagedTypeRepresentationStrategy getRepresentationStrategy();
|
ManagedTypeRepresentationStrategy getRepresentationStrategy();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,16 +7,31 @@
|
||||||
package org.hibernate.metamodel.model.domain.internal;
|
package org.hibernate.metamodel.model.domain.internal;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import javax.persistence.metamodel.Attribute;
|
||||||
|
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.graph.internal.SubGraphImpl;
|
import org.hibernate.graph.internal.SubGraphImpl;
|
||||||
import org.hibernate.graph.spi.SubGraphImplementor;
|
import org.hibernate.graph.spi.SubGraphImplementor;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
||||||
import org.hibernate.metamodel.model.domain.AbstractManagedType;
|
import org.hibernate.metamodel.model.domain.AbstractManagedType;
|
||||||
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
||||||
import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
||||||
|
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||||
import org.hibernate.metamodel.spi.ManagedTypeRepresentationStrategy;
|
import org.hibernate.metamodel.spi.ManagedTypeRepresentationStrategy;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.property.access.internal.PropertyAccessStrategyMixedImpl;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard Hibernate implementation of JPA's {@link javax.persistence.metamodel.EmbeddableType}
|
* Standard Hibernate implementation of JPA's {@link javax.persistence.metamodel.EmbeddableType}
|
||||||
|
@ -27,13 +42,13 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
*/
|
*/
|
||||||
public class EmbeddableTypeImpl<J>
|
public class EmbeddableTypeImpl<J>
|
||||||
extends AbstractManagedType<J>
|
extends AbstractManagedType<J>
|
||||||
implements EmbeddableDomainType<J>, Serializable {
|
implements EmbeddableDomainType<J>, Serializable, MappingModelExpressable<J> {
|
||||||
|
|
||||||
private final ManagedTypeRepresentationStrategy representationStrategy;
|
private final EmbeddableRepresentationStrategy representationStrategy;
|
||||||
|
|
||||||
public EmbeddableTypeImpl(
|
public EmbeddableTypeImpl(
|
||||||
JavaTypeDescriptor<J> javaTypeDescriptor,
|
JavaTypeDescriptor<J> javaTypeDescriptor,
|
||||||
ManagedTypeRepresentationStrategy representationStrategy,
|
EmbeddableRepresentationStrategy representationStrategy,
|
||||||
JpaMetamodel domainMetamodel) {
|
JpaMetamodel domainMetamodel) {
|
||||||
super( javaTypeDescriptor.getJavaType().getName(), javaTypeDescriptor, null, domainMetamodel );
|
super( javaTypeDescriptor.getJavaType().getName(), javaTypeDescriptor, null, domainMetamodel );
|
||||||
this.representationStrategy = representationStrategy;
|
this.representationStrategy = representationStrategy;
|
||||||
|
@ -71,4 +86,75 @@ public class EmbeddableTypeImpl<J>
|
||||||
public <S extends J> SubGraphImplementor<S> makeSubGraph(Class<S> subType) {
|
public <S extends J> SubGraphImplementor<S> makeSubGraph(Class<S> subType) {
|
||||||
return new SubGraphImpl( this, true, jpaMetamodel() );
|
return new SubGraphImpl( this, true, jpaMetamodel() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitJdbcValues(
|
||||||
|
Object value, Clause clause, JdbcValuesConsumer valuesConsumer, SharedSessionContractImplementor session) {
|
||||||
|
Object[] disassemble = (Object[]) disassemble( value, session );
|
||||||
|
|
||||||
|
List<JdbcMapping> jdbcMappings = getJdbcMappings( session.getFactory().getTypeConfiguration() );
|
||||||
|
for ( int i = 0; i < disassemble.length; i++ ) {
|
||||||
|
valuesConsumer.consume( disassemble[i], jdbcMappings.get( i ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitJdbcTypes(
|
||||||
|
Consumer<JdbcMapping> action,
|
||||||
|
Clause clause,
|
||||||
|
TypeConfiguration typeConfiguration) {
|
||||||
|
Set<Attribute<? super J, ?>> attributes = getAttributes();
|
||||||
|
|
||||||
|
for ( Attribute attribute : attributes ) {
|
||||||
|
if ( attribute instanceof SingularAttributeImpl ) {
|
||||||
|
if ( attribute.isAssociation() ) {
|
||||||
|
EntityTypeImpl entityType = (EntityTypeImpl) ( (SingularAttributeImpl) attribute ).getValueGraphType();
|
||||||
|
|
||||||
|
BasicType basicType = jpaMetamodel().getTypeConfiguration()
|
||||||
|
.getBasicTypeForJavaType( entityType.findIdAttribute().getJavaType() );
|
||||||
|
action.accept( basicType.getJdbcMapping() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BasicType basicType = jpaMetamodel().getTypeConfiguration()
|
||||||
|
.getBasicTypeForJavaType( attribute.getJavaType() );
|
||||||
|
action.accept( basicType.getJdbcMapping() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||||
|
final Set<Attribute<? super J, ?>> attributes = getAttributes();
|
||||||
|
final List<Object> result = new ArrayList<>();
|
||||||
|
for ( Attribute attribute : attributes ) {
|
||||||
|
if ( attribute instanceof SingularAttributeImpl ) {
|
||||||
|
final PropertyAccess propertyAccess = PropertyAccessStrategyMixedImpl.INSTANCE
|
||||||
|
.buildPropertyAccess( getJavaType(), attribute.getName() );
|
||||||
|
|
||||||
|
final Object attributeValue = propertyAccess.getGetter().get( value );
|
||||||
|
if ( attribute.isAssociation() ) {
|
||||||
|
final EntityPersister entityDescriptor = session.getFactory().getMetamodel()
|
||||||
|
.findEntityDescriptor( attribute.getJavaType().getName() );
|
||||||
|
final Object disassembled = entityDescriptor.getIdentifierMapping().disassemble(
|
||||||
|
attributeValue,
|
||||||
|
session
|
||||||
|
);
|
||||||
|
if ( disassembled instanceof Object[] ) {
|
||||||
|
for ( Object o : (Object[]) disassembled ) {
|
||||||
|
result.add( o );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.add( disassembled );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.add( attributeValue );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -712,6 +712,10 @@ public class MappingMetamodelImpl implements MappingMetamodel, MetamodelImplemen
|
||||||
throw new NotYetImplementedFor6Exception( "Resolution of embedded-valued SqmExpressable nodes not yet implemented" );
|
throw new NotYetImplementedFor6Exception( "Resolution of embedded-valued SqmExpressable nodes not yet implemented" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( sqmExpressable instanceof EmbeddableTypeImpl ) {
|
||||||
|
return (MappingModelExpressable) sqmExpressable;
|
||||||
|
}
|
||||||
|
|
||||||
throw new UnsupportedOperationException( "Cannot determine proper mapping model expressable for " + sqmExpressable );
|
throw new UnsupportedOperationException( "Cannot determine proper mapping model expressable for " + sqmExpressable );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ import org.hibernate.metamodel.mapping.CollectionPart;
|
||||||
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.internal.BasicValuedCollectionPart;
|
|
||||||
import org.hibernate.metamodel.mapping.internal.EntityCollectionPart;
|
import org.hibernate.metamodel.mapping.internal.EntityCollectionPart;
|
||||||
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
|
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
|
||||||
import org.hibernate.metamodel.model.domain.AllowableParameterType;
|
import org.hibernate.metamodel.model.domain.AllowableParameterType;
|
||||||
|
@ -2178,25 +2177,17 @@ public abstract class BaseSqmToSqlAstConverter
|
||||||
@Override
|
@Override
|
||||||
public MemberOfPredicate visitMemberOfPredicate(SqmMemberOfPredicate predicate) {
|
public MemberOfPredicate visitMemberOfPredicate(SqmMemberOfPredicate predicate) {
|
||||||
final SqmPath<?> pluralPath = predicate.getPluralPath();
|
final SqmPath<?> pluralPath = predicate.getPluralPath();
|
||||||
final PluralAttributeMapping mappingModelExpressable = (PluralAttributeMapping) SqmMappingModelHelper.resolveMappingModelExpressable(
|
final PluralAttributeMapping mappingModelExpressable = (PluralAttributeMapping) determineValueMapping(pluralPath);
|
||||||
pluralPath,
|
|
||||||
getCreationContext().getDomainModel(),
|
|
||||||
getFromClauseAccess()::findTableGroup
|
|
||||||
);
|
|
||||||
|
|
||||||
final CollectionPart elementDescriptor = mappingModelExpressable.getElementDescriptor();
|
if ( mappingModelExpressable.getElementDescriptor() instanceof EntityCollectionPart ) {
|
||||||
|
|
||||||
if ( elementDescriptor instanceof EntityCollectionPart ) {
|
|
||||||
inferableTypeAccessStack.push(
|
inferableTypeAccessStack.push(
|
||||||
() -> ( (EntityCollectionPart) elementDescriptor ).getEntityMappingType().getIdentifierMapping() );
|
() -> ( (EntityCollectionPart) mappingModelExpressable.getElementDescriptor() ).getEntityMappingType()
|
||||||
}
|
.getIdentifierMapping() );
|
||||||
else if ( elementDescriptor instanceof BasicValuedCollectionPart ) {
|
|
||||||
inferableTypeAccessStack.push( () -> elementDescriptor );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new NotYetImplementedFor6Exception(
|
inferableTypeAccessStack.push( () -> mappingModelExpressable );
|
||||||
"Member of with Collection of Embeddable has not yet been implemented" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final Expression lhs;
|
final Expression lhs;
|
||||||
try {
|
try {
|
||||||
lhs = (Expression) predicate.getLeftHandExpression().accept( this );
|
lhs = (Expression) predicate.getLeftHandExpression().accept( this );
|
||||||
|
@ -2234,6 +2225,8 @@ public abstract class BaseSqmToSqlAstConverter
|
||||||
creationContext
|
creationContext
|
||||||
);
|
);
|
||||||
|
|
||||||
|
fromClauseIndex.registerTableGroup( pluralPath.getNavigablePath(), rootTableGroup );
|
||||||
|
|
||||||
querySpec.getFromClause().addRoot( rootTableGroup );
|
querySpec.getFromClause().addRoot( rootTableGroup );
|
||||||
|
|
||||||
final CollectionPart elementDescriptor = mappingModelExpressable.getElementDescriptor();
|
final CollectionPart elementDescriptor = mappingModelExpressable.getElementDescriptor();
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
package org.hibernate.orm.test.annotations.collectionelement;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.persistence.ElementCollection;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.JoinTable;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
|
||||||
|
import org.hibernate.query.spi.QueryImplementor;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrea Boriero
|
||||||
|
*/
|
||||||
|
@DomainModel(annotatedClasses = {
|
||||||
|
EmbeddableElementCollectionMemberOfTest.Person.class,
|
||||||
|
EmbeddableElementCollectionMemberOfTest.City.class
|
||||||
|
})
|
||||||
|
@SessionFactory
|
||||||
|
public class EmbeddableElementCollectionMemberOfTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMemberOfQuery(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
Address a = new Address();
|
||||||
|
a.setStreet( "Lollard Street" );
|
||||||
|
QueryImplementor query = session.createQuery( "from Person p where :address member of p.addresses" );
|
||||||
|
query.setParameter( "address", a );
|
||||||
|
query.list();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Person")
|
||||||
|
public static class Person {
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
private Set<Address> addresses = new HashSet<>();
|
||||||
|
private Address address;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
@JoinTable(
|
||||||
|
name = "addresses",
|
||||||
|
joinColumns = @JoinColumn(name = "PERSON_ID"))
|
||||||
|
public Set<Address> getAddresses() {
|
||||||
|
return addresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddresses(Set<Address> addresses) {
|
||||||
|
this.addresses = addresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(Address address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class Address {
|
||||||
|
public String street;
|
||||||
|
public int number;
|
||||||
|
|
||||||
|
public City city;
|
||||||
|
|
||||||
|
public String getStreet() {
|
||||||
|
return street;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStreet(String street) {
|
||||||
|
this.street = street;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumber(int number) {
|
||||||
|
this.number = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
public City getCity() {
|
||||||
|
return city;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCity(City city) {
|
||||||
|
this.city = city;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "City")
|
||||||
|
public static class City {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -128,7 +128,6 @@ public class EagerManyToOneEmbeddedIdFKTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@FailureExpected(reason = "Embedded parameters has not yet been implemented ")
|
|
||||||
public void testEmbeddedIdParameter(SessionFactoryScope scope) {
|
public void testEmbeddedIdParameter(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
session -> {
|
session -> {
|
||||||
|
|
|
@ -19,7 +19,6 @@ import org.hibernate.Hibernate;
|
||||||
|
|
||||||
import org.hibernate.testing.jdbc.SQLStatementInspector;
|
import org.hibernate.testing.jdbc.SQLStatementInspector;
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
import org.hibernate.testing.orm.junit.FailureExpected;
|
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
@ -150,7 +149,6 @@ public class ManyToOneEmbeddedIdWithToOneFKTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@FailureExpected(reason = "Embedded parameters has not yet been implemented ")
|
|
||||||
public void testEmbeddedIdParameter(SessionFactoryScope scope) {
|
public void testEmbeddedIdParameter(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
session -> {
|
session -> {
|
||||||
|
@ -159,7 +157,7 @@ public class ManyToOneEmbeddedIdWithToOneFKTest {
|
||||||
PK superUserKey = new PK( dataCenter, "Fab" );
|
PK superUserKey = new PK( dataCenter, "Fab" );
|
||||||
|
|
||||||
System system = session.createQuery(
|
System system = session.createQuery(
|
||||||
"from System e join fetch e.user u where u.id = :id",
|
"from System e join fetch e.dataCenterUser u where u.id = :id",
|
||||||
System.class
|
System.class
|
||||||
).setParameter( "id", superUserKey ).uniqueResult();
|
).setParameter( "id", superUserKey ).uniqueResult();
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,6 @@ public class OneToManyEmbeddedIdFKTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@FailureExpected(reason = "Embedded parameters has not yet been implemented ")
|
|
||||||
public void testEmbeddedIdParameter(SessionFactoryScope scope) {
|
public void testEmbeddedIdParameter(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
session -> {
|
session -> {
|
||||||
|
@ -135,7 +134,7 @@ public class OneToManyEmbeddedIdFKTest {
|
||||||
).setParameter( "id", superUserKey ).uniqueResult();
|
).setParameter( "id", superUserKey ).uniqueResult();
|
||||||
|
|
||||||
assertThat( system, is( notNullValue() ) );
|
assertThat( system, is( notNullValue() ) );
|
||||||
assertThat( system.getUsers().size(), is( 2 ) );
|
assertThat( system.getUsers().size(), is( 1 ) );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,11 @@ import java.util.List;
|
||||||
import javax.persistence.Embeddable;
|
import javax.persistence.Embeddable;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
|
||||||
import org.hibernate.testing.junit5.SessionFactoryBasedFunctionalTest;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
import org.hibernate.testing.orm.junit.FailureExpected;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -23,19 +25,18 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
/**
|
/**
|
||||||
* @author Andrea Boriero
|
* @author Andrea Boriero
|
||||||
*/
|
*/
|
||||||
@FailureExpected( reason = "Support for embedded-valued parameters not yet implemented" )
|
@DomainModel(
|
||||||
public class EmbeddableAsParameterTest extends SessionFactoryBasedFunctionalTest {
|
annotatedClasses = {
|
||||||
|
EmbeddableAsParameterTest.Person.class,
|
||||||
@Override
|
EmbeddableAsParameterTest.EntityTest.class
|
||||||
protected Class[] getAnnotatedClasses() {
|
}
|
||||||
return new Class[] {
|
)
|
||||||
Person.class,
|
@SessionFactory
|
||||||
};
|
public class EmbeddableAsParameterTest {
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAsParameterInWhereClause() {
|
public void testAsParameterInWhereClause(SessionFactoryScope scope) {
|
||||||
inTransaction(
|
scope.inTransaction(
|
||||||
session -> {
|
session -> {
|
||||||
List results = session.createQuery( "select p from Person p where p.name = :name" ).
|
List results = session.createQuery( "select p from Person p where p.name = :name" ).
|
||||||
setParameter( "name", new Name( "Fab", "Fab" ) ).list();
|
setParameter( "name", new Name( "Fab", "Fab" ) ).list();
|
||||||
|
@ -45,19 +46,32 @@ public class EmbeddableAsParameterTest extends SessionFactoryBasedFunctionalTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAsParameterReuseInWhereClause() {
|
public void testAsParameterReuseInWhereClause(SessionFactoryScope scope) {
|
||||||
inTransaction(
|
scope.inTransaction(
|
||||||
session -> {
|
session -> {
|
||||||
List results = session.createQuery( "select p from Person p where p.name = :name or p.name = :name " ).
|
List results = session.createQuery( "select p from Person p where p.name = :name or p.name = :name " )
|
||||||
setParameter( "name", new Name( "Fab", "Fab" ) ).list();
|
.
|
||||||
|
setParameter( "name", new Name( "Fab", "Fab" ) )
|
||||||
|
.list();
|
||||||
assertThat( results.size(), is( 1 ) );
|
assertThat( results.size(), is( 1 ) );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAsParameterReuseInWhereClause2(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
List results = session.createQuery( "select p from Person p where p.embeddableTest = :embeddable" ).
|
||||||
|
setParameter( "embeddable", new EmbeddableTest() ).list();
|
||||||
|
assertThat( results.size(), is( 0 ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp(SessionFactoryScope scope) {
|
||||||
inTransaction(
|
scope.inTransaction(
|
||||||
session -> {
|
session -> {
|
||||||
Person person = new Person(
|
Person person = new Person(
|
||||||
1,
|
1,
|
||||||
|
@ -70,8 +84,8 @@ public class EmbeddableAsParameterTest extends SessionFactoryBasedFunctionalTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
public void tearDown() {
|
public void tearDown(SessionFactoryScope scope) {
|
||||||
inTransaction(
|
scope.inTransaction(
|
||||||
session -> {
|
session -> {
|
||||||
session.createQuery( "delete Person" ).executeUpdate();
|
session.createQuery( "delete Person" ).executeUpdate();
|
||||||
}
|
}
|
||||||
|
@ -85,6 +99,8 @@ public class EmbeddableAsParameterTest extends SessionFactoryBasedFunctionalTest
|
||||||
|
|
||||||
private Name name;
|
private Name name;
|
||||||
|
|
||||||
|
private EmbeddableTest embeddableTest;
|
||||||
|
|
||||||
private Integer age;
|
private Integer age;
|
||||||
|
|
||||||
public Person() {
|
public Person() {
|
||||||
|
@ -124,6 +140,46 @@ public class EmbeddableAsParameterTest extends SessionFactoryBasedFunctionalTest
|
||||||
public void setAge(Integer age) {
|
public void setAge(Integer age) {
|
||||||
this.age = age;
|
this.age = age;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EmbeddableTest getEmbeddableTest() {
|
||||||
|
return embeddableTest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmbeddableTest(EmbeddableTest embeddableTest) {
|
||||||
|
this.embeddableTest = embeddableTest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class EmbeddableTest {
|
||||||
|
private String street;
|
||||||
|
|
||||||
|
@OneToMany
|
||||||
|
private List<EntityTest> entityTests;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "EmbeddableTest")
|
||||||
|
public static class EntityTest {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
package org.hibernate.orm.test.query.hql;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrea Boriero
|
||||||
|
*/
|
||||||
|
@DomainModel(
|
||||||
|
annotatedClasses = {
|
||||||
|
EmbeddableWithPluralAttributeTest.A.class,
|
||||||
|
EmbeddableWithPluralAttributeTest.C.class
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@SessionFactory
|
||||||
|
public class EmbeddableWithPluralAttributeTest {
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public void setUp(SessionFactoryScope scope){
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
A a = new A();
|
||||||
|
a.id = 1;
|
||||||
|
|
||||||
|
B b = B.buildB();
|
||||||
|
a.b = b;
|
||||||
|
|
||||||
|
session.save( a );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAsParameterReuseInWhereClauseZeroResults(SessionFactoryScope scope) {
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
List results = session.createQuery( "select a from A a where a.b = :b" ).
|
||||||
|
setParameter( "b", new B() ).list();
|
||||||
|
assertThat( results.size(), is( 0 ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAsParameterReuseInWhereClause(SessionFactoryScope scope) {
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
List results = session.createQuery( "select a from A a where a.b = :b" ).
|
||||||
|
setParameter( "b", B.buildB() ).list();
|
||||||
|
assertThat( results.size(), is( 1 ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "A")
|
||||||
|
public static class A {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private B b;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class B {
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
@OneToMany(cascade = CascadeType.ALL)
|
||||||
|
private List<C> cs;
|
||||||
|
|
||||||
|
public static B buildB() {
|
||||||
|
B b = new B();
|
||||||
|
b.value = "v";
|
||||||
|
C c = new C();
|
||||||
|
|
||||||
|
c.id = 2L;
|
||||||
|
c.name = "c";
|
||||||
|
|
||||||
|
List cs = new ArrayList();
|
||||||
|
cs.add( c );
|
||||||
|
b.cs = cs;
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "C")
|
||||||
|
public static class C {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue