mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-07 11:48:18 +00:00
HHH-16188 Register concrete embeddable type to use when creating SqmPath
This commit is contained in:
parent
57f5f4aaee
commit
2421496c18
@ -320,6 +320,7 @@ public void doSecondPass(Map persistentClasses) throws MappingException {
|
||||
setTypeName( value, inferredData.getTypeName() );
|
||||
}
|
||||
if ( value instanceof Component ) {
|
||||
actualProperty.setGenericEmbeddable( true );
|
||||
final Component component = ( (Component) value );
|
||||
final Iterator<Property> propertyIterator = component.getPropertyIterator();
|
||||
while ( propertyIterator.hasNext() ) {
|
||||
|
@ -57,6 +57,7 @@ public class Property implements Serializable, MetaAttributable {
|
||||
private java.util.Map metaAttributes;
|
||||
private PersistentClass persistentClass;
|
||||
private boolean naturalIdentifier;
|
||||
private boolean genericEmbeddable;
|
||||
private boolean lob;
|
||||
private java.util.List<CallbackDefinition> callbackDefinitions;
|
||||
private String returnedClassName;
|
||||
@ -417,6 +418,14 @@ public void setNaturalIdentifier(boolean naturalIdentifier) {
|
||||
this.naturalIdentifier = naturalIdentifier;
|
||||
}
|
||||
|
||||
public boolean isGenericEmbeddable() {
|
||||
return genericEmbeddable;
|
||||
}
|
||||
|
||||
public void setGenericEmbeddable(boolean genericEmbeddable) {
|
||||
this.genericEmbeddable = genericEmbeddable;
|
||||
}
|
||||
|
||||
public boolean isLob() {
|
||||
return lob;
|
||||
}
|
||||
@ -473,6 +482,7 @@ public Property copy() {
|
||||
property.setMetaAttributes( getMetaAttributes() );
|
||||
property.setPersistentClass( getPersistentClass() );
|
||||
property.setNaturalIdentifier( isNaturalIdentifier() );
|
||||
property.setGeneric( isGeneric() );
|
||||
property.setLob( isLob() );
|
||||
property.addCallbackDefinitions( getCallbackDefinitions() );
|
||||
property.setReturnedClassName( getReturnedClassName() );
|
||||
|
@ -129,6 +129,7 @@ public static <X, Y> PersistentAttribute<X, Y> buildAttribute(
|
||||
false,
|
||||
false,
|
||||
property.isOptional(),
|
||||
property.isGenericEmbeddable(),
|
||||
metadataContext
|
||||
);
|
||||
}
|
||||
@ -176,6 +177,7 @@ public <X, Y> SingularPersistentAttribute<X, Y> buildIdAttribute(
|
||||
(SimpleDomainType<Y>) determineSimpleType( attributeMetadata.getValueContext() ),
|
||||
attributeMetadata.getMember(),
|
||||
attributeMetadata.getAttributeClassification(),
|
||||
property.isGenericEmbeddable(),
|
||||
context
|
||||
);
|
||||
}
|
||||
|
@ -420,20 +420,26 @@ private void addAttribute(ManagedDomainType<?> type, PersistentAttribute<Object,
|
||||
private void applyIdMetadata(PersistentClass persistentClass, IdentifiableDomainType<?> identifiableType) {
|
||||
if ( persistentClass.hasIdentifierProperty() ) {
|
||||
final Property declaredIdentifierProperty = persistentClass.getDeclaredIdentifierProperty();
|
||||
//noinspection rawtypes
|
||||
final AttributeContainer attributeContainer = (AttributeContainer) identifiableType;
|
||||
if ( declaredIdentifierProperty != null ) {
|
||||
final SingularPersistentAttribute<?, Object> idAttribute = attributeFactory.buildIdAttribute(
|
||||
identifiableType,
|
||||
declaredIdentifierProperty
|
||||
);
|
||||
|
||||
//noinspection unchecked rawtypes
|
||||
( ( AttributeContainer) identifiableType ).getInFlightAccess().applyIdAttribute( idAttribute );
|
||||
//noinspection unchecked
|
||||
attributeContainer.getInFlightAccess().applyIdAttribute( idAttribute );
|
||||
}
|
||||
else if ( persistentClass.getIdentifier() instanceof Component
|
||||
&& persistentClass.getIdentifierProperty() != getSuperclassIdentifier( persistentClass ) ) {
|
||||
// If the identifier is a generic component, we have to call buildIdAttribute anyway,
|
||||
// as this will create and register the EmbeddableType for the subtype
|
||||
attributeFactory.buildIdAttribute( identifiableType, persistentClass.getIdentifierProperty() );
|
||||
final SingularPersistentAttribute<?, Object> concreteEmbeddable = attributeFactory.buildIdAttribute(
|
||||
identifiableType,
|
||||
persistentClass.getIdentifierProperty()
|
||||
);
|
||||
//noinspection unchecked
|
||||
attributeContainer.getInFlightAccess().addConcreteEmbeddableAttribute( concreteEmbeddable );
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -424,7 +424,8 @@ else if ( id != null ) {
|
||||
return new EmbeddedSqmPathSource<>(
|
||||
EntityIdentifierMapping.ROLE_LOCAL_NAME,
|
||||
compositeType,
|
||||
Bindable.BindableType.SINGULAR_ATTRIBUTE
|
||||
Bindable.BindableType.SINGULAR_ATTRIBUTE,
|
||||
id.isGeneric()
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -441,7 +442,8 @@ else if ( nonAggregatedIdAttributes != null && ! nonAggregatedIdAttributes.isEmp
|
||||
return new EmbeddedSqmPathSource<>(
|
||||
EntityIdentifierMapping.ROLE_LOCAL_NAME,
|
||||
idClassType,
|
||||
Bindable.BindableType.SINGULAR_ATTRIBUTE
|
||||
Bindable.BindableType.SINGULAR_ATTRIBUTE,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ public abstract class AbstractManagedType<J>
|
||||
|
||||
private final Map<String, SingularPersistentAttribute<J, ?>> declaredSingularAttributes = new LinkedHashMap<>();
|
||||
private volatile Map<String, PluralPersistentAttribute<J, ?, ?>> declaredPluralAttributes ;
|
||||
private volatile Map<String, SingularPersistentAttribute<J, ?>> declaredConcreteEmbeddedAttributes;
|
||||
|
||||
private final List<ManagedDomainType> subTypes = new ArrayList<>();
|
||||
|
||||
@ -464,6 +465,24 @@ private <E> void checkTypeForPluralAttributes(
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Generic Embeddable attributes
|
||||
|
||||
@Override
|
||||
public SingularPersistentAttribute<? super J, ?> findConcreteEmbeddableAttribute(String name) {
|
||||
SingularPersistentAttribute<? super J, ?> attribute = findDeclaredConcreteEmbeddableAttribute( name );
|
||||
if ( attribute == null && getSuperType() != null ) {
|
||||
attribute = getSuperType().findDeclaredConcreteEmbeddableAttribute( name );
|
||||
}
|
||||
return attribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingularPersistentAttribute<? super J, ?> findDeclaredConcreteEmbeddableAttribute(String name) {
|
||||
return declaredConcreteEmbeddedAttributes == null ? null : declaredConcreteEmbeddedAttributes.get( name );
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Bags
|
||||
|
||||
@ -740,6 +759,14 @@ else if ( attribute instanceof PluralPersistentAttribute ) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addConcreteEmbeddableAttribute(SingularPersistentAttribute<J, ?> attribute) {
|
||||
if ( declaredConcreteEmbeddedAttributes == null ) {
|
||||
declaredConcreteEmbeddedAttributes = new HashMap<>();
|
||||
}
|
||||
declaredConcreteEmbeddedAttributes.put( attribute.getName(), attribute );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishUp() {
|
||||
inFlightAccess = null;
|
||||
|
@ -59,10 +59,12 @@ public interface ManagedDomainType<J> extends SqmExpressible<J>, DomainType<J>,
|
||||
|
||||
SingularPersistentAttribute<? super J,?> findSingularAttribute(String name);
|
||||
PluralPersistentAttribute<? super J, ?,?> findPluralAttribute(String name);
|
||||
SingularPersistentAttribute<? super J, ?> findConcreteEmbeddableAttribute(String name);
|
||||
|
||||
PersistentAttribute<J,?> findDeclaredAttribute(String name);
|
||||
SingularPersistentAttribute<? super J, ?> findDeclaredSingularAttribute(String name);
|
||||
PluralPersistentAttribute<? super J, ?, ?> findDeclaredPluralAttribute(String name);
|
||||
SingularPersistentAttribute<? super J, ?> findDeclaredConcreteEmbeddableAttribute(String name);
|
||||
|
||||
SubGraphImplementor<J> makeSubGraph();
|
||||
<S extends J> SubGraphImplementor<S> makeSubGraph(Class<S> subClassType);
|
||||
|
@ -66,6 +66,12 @@ default void applyNaturalIdAttribute(PersistentAttribute<J, ?> versionAttribute)
|
||||
);
|
||||
}
|
||||
|
||||
default void addConcreteEmbeddableAttribute(SingularPersistentAttribute<J, ?> idAttribute) {
|
||||
throw new UnsupportedMappingException(
|
||||
"AttributeContainer [" + getClass().getName() + "] does not generic embeddables"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when configuration of the type is complete
|
||||
*/
|
||||
|
@ -7,10 +7,10 @@
|
||||
package org.hibernate.metamodel.model.domain.internal;
|
||||
|
||||
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmEmbeddedValuedSimplePath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
@ -18,12 +18,15 @@
|
||||
public class EmbeddedSqmPathSource<J>
|
||||
extends AbstractSqmPathSource<J>
|
||||
implements CompositeSqmPathSource<J> {
|
||||
private final boolean isGeneric;
|
||||
|
||||
public EmbeddedSqmPathSource(
|
||||
String localPathName,
|
||||
EmbeddableDomainType<J> domainType,
|
||||
BindableType jpaBindableType) {
|
||||
BindableType jpaBindableType,
|
||||
boolean isGeneric) {
|
||||
super( localPathName, domainType, jpaBindableType );
|
||||
this.isGeneric = isGeneric;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -37,6 +40,11 @@ public SqmPathSource<?> findSubPathSource(String name) {
|
||||
return (SqmPathSource<?>) getSqmPathType().findAttribute( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGeneric() {
|
||||
return isGeneric;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
|
||||
final NavigablePath navigablePath;
|
||||
|
@ -59,6 +59,7 @@ public SingularAttributeImpl(
|
||||
boolean isIdentifier,
|
||||
boolean isVersion,
|
||||
boolean isOptional,
|
||||
boolean isGeneric,
|
||||
MetadataContext metadataContext) {
|
||||
super(
|
||||
declaringType,
|
||||
@ -77,7 +78,8 @@ public SingularAttributeImpl(
|
||||
this.sqmPathSource = SqmMappingModelHelper.resolveSqmPathSource(
|
||||
name,
|
||||
attributeType,
|
||||
BindableType.SINGULAR_ATTRIBUTE
|
||||
BindableType.SINGULAR_ATTRIBUTE,
|
||||
isGeneric
|
||||
);
|
||||
}
|
||||
|
||||
@ -121,6 +123,11 @@ public SqmPathSource<?> findSubPathSource(String name) {
|
||||
return sqmPathSource.findSubPathSource( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGeneric() {
|
||||
return sqmPathSource.isGeneric();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmAttributeJoin<D,J> createSqmJoin(
|
||||
SqmFrom lhs,
|
||||
@ -154,6 +161,7 @@ public Identifier(
|
||||
SimpleDomainType<J> attributeType,
|
||||
Member member,
|
||||
AttributeClassification attributeClassification,
|
||||
boolean isGeneric,
|
||||
MetadataContext metadataContext) {
|
||||
super(
|
||||
declaringType,
|
||||
@ -164,6 +172,7 @@ public Identifier(
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
isGeneric,
|
||||
metadataContext
|
||||
);
|
||||
}
|
||||
@ -204,6 +213,7 @@ public Version(
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
metadataContext
|
||||
);
|
||||
}
|
||||
|
@ -86,4 +86,11 @@ default SqmPathSource<?> getIntermediatePathSource(SqmPathSource<?> pathSource)
|
||||
default SqmExpressible<J> getExpressible() {
|
||||
return (SqmExpressible<J>) getSqmPathType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this path source is generically typed
|
||||
*/
|
||||
default boolean isGeneric() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,14 @@ public static <J> SqmPathSource<J> resolveSqmPathSource(
|
||||
String name,
|
||||
DomainType<J> valueDomainType,
|
||||
Bindable.BindableType jpaBindableType) {
|
||||
return resolveSqmPathSource( name, valueDomainType, jpaBindableType, false );
|
||||
}
|
||||
|
||||
public static <J> SqmPathSource<J> resolveSqmPathSource(
|
||||
String name,
|
||||
DomainType<J> valueDomainType,
|
||||
Bindable.BindableType jpaBindableType,
|
||||
boolean isGeneric) {
|
||||
|
||||
if ( valueDomainType instanceof BasicDomainType<?> ) {
|
||||
return new BasicSqmPathSource<>(
|
||||
@ -99,7 +107,8 @@ public static <J> SqmPathSource<J> resolveSqmPathSource(
|
||||
return new EmbeddedSqmPathSource<>(
|
||||
name,
|
||||
(EmbeddableDomainType<J>) valueDomainType,
|
||||
jpaBindableType
|
||||
jpaBindableType,
|
||||
isGeneric
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,11 @@
|
||||
*/
|
||||
package org.hibernate.query.sqm.tree.domain;
|
||||
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.metamodel.model.domain.ManagedDomainType;
|
||||
import org.hibernate.metamodel.model.domain.internal.CompositeSqmPathSource;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.query.PathException;
|
||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||
@ -77,6 +80,24 @@ public SqmPath<?> resolvePathPart(
|
||||
return sqmPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPath<?> get(String attributeName) {
|
||||
final DomainType<?> lhsType;
|
||||
final SqmPathSource<T> pathSource = getReferencedPathSource();
|
||||
if ( pathSource.isGeneric() && ( lhsType = getLhs().getReferencedPathSource()
|
||||
.getSqmPathType() ) instanceof ManagedDomainType ) {
|
||||
//noinspection rawtypes
|
||||
final SqmPathSource<?> concreteEmbeddable = ( (ManagedDomainType) lhsType ).findConcreteEmbeddableAttribute(
|
||||
pathSource.getPathName()
|
||||
);
|
||||
if ( concreteEmbeddable != null ) {
|
||||
final SqmPathSource<?> subNavigable = concreteEmbeddable.getSubPathSource( attributeName );
|
||||
return resolvePath( attributeName, subNavigable );
|
||||
}
|
||||
}
|
||||
return super.get( attributeName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitEmbeddableValuedPath( this );
|
||||
|
@ -209,6 +209,11 @@ public void visitDeclaredAttributes(Consumer<? super PersistentAttribute<T, ?>>
|
||||
return (PluralPersistentAttribute<? super T, ?, ?>) findAttribute( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingularPersistentAttribute<? super T, ?> findConcreteEmbeddableAttribute(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistentAttribute<T, ?> findDeclaredAttribute(String name) {
|
||||
return null;
|
||||
@ -224,6 +229,11 @@ public void visitDeclaredAttributes(Consumer<? super PersistentAttribute<T, ?>>
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingularPersistentAttribute<? super T, ?> findDeclaredConcreteEmbeddableAttribute(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Attribute<? super T, ?>> getAttributes() {
|
||||
//noinspection unchecked
|
||||
|
Loading…
x
Reference in New Issue
Block a user