HHH-16188 Register concrete embeddable type to use when creating SqmPath
This commit is contained in:
parent
bec951018b
commit
b198259cef
|
@ -320,6 +320,7 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
|
|||
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 class Property implements Serializable, MetaAttributable {
|
|||
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 class Property implements Serializable, MetaAttributable {
|
|||
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 class AttributeFactory {
|
|||
false,
|
||||
false,
|
||||
property.isOptional(),
|
||||
property.isGenericEmbeddable(),
|
||||
metadataContext
|
||||
);
|
||||
}
|
||||
|
@ -176,6 +177,7 @@ public class AttributeFactory {
|
|||
(SimpleDomainType<Y>) determineSimpleType( attributeMetadata.getValueContext() ),
|
||||
attributeMetadata.getMember(),
|
||||
attributeMetadata.getAttributeClassification(),
|
||||
property.isGenericEmbeddable(),
|
||||
context
|
||||
);
|
||||
}
|
||||
|
|
|
@ -420,20 +420,26 @@ public class MetadataContext {
|
|||
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 @@ public abstract class AbstractIdentifiableType<J>
|
|||
return new EmbeddedSqmPathSource<>(
|
||||
EntityIdentifierMapping.ROLE_LOCAL_NAME,
|
||||
compositeType,
|
||||
Bindable.BindableType.SINGULAR_ATTRIBUTE
|
||||
Bindable.BindableType.SINGULAR_ATTRIBUTE,
|
||||
id.isGeneric()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -441,7 +442,8 @@ public abstract class AbstractIdentifiableType<J>
|
|||
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 @@ public abstract class AbstractManagedType<J>
|
|||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// 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 @@ public abstract class AbstractManagedType<J>
|
|||
}
|
||||
}
|
||||
|
||||
@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 @@ public interface AttributeContainer<J> {
|
|||
);
|
||||
}
|
||||
|
||||
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 @@ import org.hibernate.query.sqm.tree.domain.SqmPath;
|
|||
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 class EmbeddedSqmPathSource<J>
|
|||
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 class SingularAttributeImpl<D,J>
|
|||
boolean isIdentifier,
|
||||
boolean isVersion,
|
||||
boolean isOptional,
|
||||
boolean isGeneric,
|
||||
MetadataContext metadataContext) {
|
||||
super(
|
||||
declaringType,
|
||||
|
@ -77,7 +78,8 @@ public class SingularAttributeImpl<D,J>
|
|||
this.sqmPathSource = SqmMappingModelHelper.resolveSqmPathSource(
|
||||
name,
|
||||
attributeType,
|
||||
BindableType.SINGULAR_ATTRIBUTE
|
||||
BindableType.SINGULAR_ATTRIBUTE,
|
||||
isGeneric
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -121,6 +123,11 @@ public class SingularAttributeImpl<D,J>
|
|||
return sqmPathSource.findSubPathSource( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGeneric() {
|
||||
return sqmPathSource.isGeneric();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmAttributeJoin<D,J> createSqmJoin(
|
||||
SqmFrom lhs,
|
||||
|
@ -154,6 +161,7 @@ public class SingularAttributeImpl<D,J>
|
|||
SimpleDomainType<J> attributeType,
|
||||
Member member,
|
||||
AttributeClassification attributeClassification,
|
||||
boolean isGeneric,
|
||||
MetadataContext metadataContext) {
|
||||
super(
|
||||
declaringType,
|
||||
|
@ -164,6 +172,7 @@ public class SingularAttributeImpl<D,J>
|
|||
true,
|
||||
false,
|
||||
false,
|
||||
isGeneric,
|
||||
metadataContext
|
||||
);
|
||||
}
|
||||
|
@ -204,6 +213,7 @@ public class SingularAttributeImpl<D,J>
|
|||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
metadataContext
|
||||
);
|
||||
}
|
||||
|
|
|
@ -86,4 +86,11 @@ public interface SqmPathSource<J> extends SqmExpressible<J>, Bindable<J>, SqmExp
|
|||
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 class SqmMappingModelHelper {
|
|||
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 class SqmMappingModelHelper {
|
|||
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 class SqmEmbeddedValuedSimplePath<T>
|
|||
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 class SqmPolymorphicRootDescriptor<T> implements EntityDomainType<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 class SqmPolymorphicRootDescriptor<T> implements EntityDomainType<T> {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingularPersistentAttribute<? super T, ?> findDeclaredConcreteEmbeddableAttribute(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Attribute<? super T, ?>> getAttributes() {
|
||||
//noinspection unchecked
|
||||
|
|
Loading…
Reference in New Issue