Navigate all possible targetKeyPropertyNames

This commit is contained in:
Fabio Massimo Ercoli 2021-10-31 17:43:10 +01:00
parent fdcb07420f
commit 47605bf93b
4 changed files with 87 additions and 37 deletions

View File

@ -425,8 +425,8 @@ public String getTargetKeyPropertyName() {
return targetKeyPropertyName;
}
public boolean isTargetKeyPropertyPath(String path) {
return targetKeyPropertyNames.contains( path );
public Set<String> getTargetKeyPropertyNames() {
return targetKeyPropertyNames;
}
public Cardinality getCardinality() {

View File

@ -10,7 +10,6 @@
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.internal.AbstractDomainPath;
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
import org.hibernate.metamodel.mapping.ordering.TranslationContext;
import org.hibernate.query.NavigablePath;
@ -20,9 +19,10 @@
* @author Steve Ebersole
*/
public class DomainPathContinuation extends AbstractDomainPath {
private final NavigablePath navigablePath;
protected final NavigablePath navigablePath;
protected final ModelPart referencedModelPart;
private final DomainPath lhs;
private final ModelPart referencedModelPart;
public DomainPathContinuation(NavigablePath navigablePath, DomainPath lhs, ModelPart referencedModelPart) {
this.navigablePath = navigablePath;
@ -65,25 +65,6 @@ public SequencePart resolvePathPart(
subPart
);
}
if ( referencedModelPart instanceof ToOneAttributeMapping ) {
ToOneAttributeMapping toOneAttribute = (ToOneAttributeMapping) referencedModelPart;
if ( name.equals( toOneAttribute.getTargetKeyPropertyName() ) ) {
final ModelPart subPart = toOneAttribute.findSubPart( name );
if ( subPart == null ) {
throw new PathResolutionException(
"Could not resolve path token : " + referencedModelPart + " -> " + name
);
}
return new DomainPathContinuation(
navigablePath.append( name ),
this,
// unfortunately at this stage the foreign key descriptor could not be set
// on the attribute mapping yet, so we need to defer the sub part extraction later
referencedModelPart
);
}
}
throw new PathResolutionException(
"Domain path of type `" + referencedModelPart.getPartMappingType() +

View File

@ -0,0 +1,65 @@
/*
* 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.metamodel.mapping.ordering.ast;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.ModelPartContainer;
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
import org.hibernate.metamodel.mapping.ordering.TranslationContext;
import org.hibernate.query.NavigablePath;
public class FkDomainPathContinuation extends DomainPathContinuation {
private final Set<String> possiblePaths;
public FkDomainPathContinuation(
NavigablePath navigablePath, DomainPath lhs,
ToOneAttributeMapping referencedModelPart) {
super( navigablePath, lhs, referencedModelPart );
this.possiblePaths = referencedModelPart.getTargetKeyPropertyNames();
}
public FkDomainPathContinuation(
NavigablePath navigablePath, DomainPath lhs,
ModelPart referencedModelPart, Set<String> possiblePaths) {
super( navigablePath, lhs, referencedModelPart );
this.possiblePaths = possiblePaths;
}
@Override
public SequencePart resolvePathPart(String name, boolean isTerminal, TranslationContext translationContext) {
HashSet<String> furtherPaths = new LinkedHashSet<>( possiblePaths.size() );
for ( String path : possiblePaths ) {
if ( !path.startsWith( name ) ) {
return new DomainPathContinuation(
navigablePath.append( name ),
this,
// unfortunately at this stage the foreign key descriptor could not be set
// on the attribute mapping yet, so we need to defer the sub part extraction later
referencedModelPart
);
}
furtherPaths.add( path.substring( name.length() + 1 ) );
}
if ( furtherPaths.isEmpty() ) {
throw new PathResolutionException( "Domain path of type `" + referencedModelPart.getPartMappingType() + "` -> `" + name + "`" );
}
return new FkDomainPathContinuation(
navigablePath.append( name ),
this,
( (ModelPartContainer) referencedModelPart ).findSubPart( name, null ),
furtherPaths
);
}
}

View File

@ -56,21 +56,25 @@ public DomainPath resolvePathPart(
if ( subPart instanceof CollectionPart ) {
return new CollectionPartPath( this, (CollectionPart) subPart );
}
else if ( !( subPart instanceof EmbeddableValuedModelPart || subPart instanceof ToOneAttributeMapping ) ) {
final CollectionPartPath elementPath = new CollectionPartPath(
this,
pluralAttributeMapping.getElementDescriptor()
);
return new DomainPathContinuation(
elementPath.getNavigablePath().append( name ),
this,
pluralAttributeMapping.getElementDescriptor()
);
}
else {
if ( subPart instanceof EmbeddableValuedModelPart ) {
return new DomainPathContinuation( navigablePath.append( name ), this, subPart );
}
if ( subPart instanceof ToOneAttributeMapping ) {
return new FkDomainPathContinuation( navigablePath.append( name ), this,
(ToOneAttributeMapping) subPart );
}
// leaf case:
final CollectionPartPath elementPath = new CollectionPartPath(
this,
pluralAttributeMapping.getElementDescriptor()
);
return new DomainPathContinuation(
elementPath.getNavigablePath().append( name ),
this,
pluralAttributeMapping.getElementDescriptor()
);
}
// the above checks for explicit element or index descriptor references