HHH-17528 Throw error for embedded result with collections
This commit is contained in:
parent
a59119ee42
commit
b44ff032c3
|
@ -610,3 +610,11 @@ create table JsonHolder as (
|
|||
====
|
||||
|
||||
Again, the name and the nullability of the `aggregate` column can be refined through applying a `@Column` on the persistent attribute.
|
||||
|
||||
[[embeddable-mapping-aggregate]]
|
||||
==== Embeddable mappings containing collections
|
||||
|
||||
Mapping <<chapters/domain/collections.adoc#collections,collections>> inside an `@Embeddable` value is supported in most cases. There are a couple exceptions:
|
||||
|
||||
* If the values of an <<chapters/domain/collections.adoc#collections-elemental,@ElementCollection>> is of embeddable type, that embeddable cannot contain nested collections;
|
||||
* Explicitly selecting an embeddable that contains collections in a query is currently not supported (we wouldn't be able to correctly initialize the collection since its owning entity instance would be missing from the Persistence Context).
|
|
@ -6,8 +6,10 @@
|
|||
*/
|
||||
package org.hibernate.sql.results.graph.embeddable.internal;
|
||||
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.query.SemanticException;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.ast.SqlAstJoinType;
|
||||
import org.hibernate.sql.ast.spi.FromClauseAccess;
|
||||
|
@ -41,8 +43,14 @@ public class EmbeddableResultImpl<T> extends AbstractFetchParent implements Embe
|
|||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
super( navigablePath );
|
||||
|
||||
this.fetchContainer = modelPart.getEmbeddableTypeDescriptor();
|
||||
this.resultVariable = resultVariable;
|
||||
|
||||
// We currently don't support explicitly selecting embeddables that contain collections
|
||||
// as we wouldn't be able to correctly initialize their owning entity instances
|
||||
checkContainsCollections( modelPart, navigablePath );
|
||||
|
||||
/*
|
||||
An `{embeddable_result}` sub-path is created for the corresponding initializer to differentiate it from a fetch-initializer if this embedded is also fetched.
|
||||
The Jakarta Persistence spec says that any embedded value selected in the result should not be part of the state of any managed entity.
|
||||
|
@ -88,6 +96,25 @@ public class EmbeddableResultImpl<T> extends AbstractFetchParent implements Embe
|
|||
return false;
|
||||
}
|
||||
|
||||
private static void checkContainsCollections(
|
||||
EmbeddableValuedModelPart embeddableModelPart,
|
||||
NavigablePath navigablePath) {
|
||||
embeddableModelPart.forEachSubPart( (index, modelPart) -> {
|
||||
final AttributeMapping attribute = modelPart.asAttributeMapping();
|
||||
if ( attribute != null ) {
|
||||
if ( attribute.isPluralAttributeMapping() ) {
|
||||
throw new SemanticException( String.format(
|
||||
"Explicit selection of an embeddable containing collections is not supported: %s",
|
||||
navigablePath
|
||||
) );
|
||||
}
|
||||
else if ( attribute.isEmbeddedAttributeMapping() ) {
|
||||
checkContainsCollections( attribute.asEmbeddedAttributeMapping(), navigablePath );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResultVariable() {
|
||||
return resultVariable;
|
||||
|
|
Loading…
Reference in New Issue