clean up lots of warnings in org.hibernate.graph

This commit is contained in:
Gavin King 2023-07-01 18:44:00 +02:00
parent bc901f5162
commit 1e05e8444e
17 changed files with 244 additions and 274 deletions

View File

@ -12,26 +12,27 @@ import jakarta.persistence.Subgraph;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
/**
* Hibernate extension to the JPA entity-graph AttributeNode contract.
* Extends the JPA-defined {@link AttributeNode} with additional operations.
*
* @author Strong Liu
* @author Steve Ebersole
* @author Andrea Boriero
*/
public interface AttributeNode<J> extends GraphNode<J>, jakarta.persistence.AttributeNode<J> {
PersistentAttribute<?, J> getAttributeDescriptor();
Map<Class<? extends J>, SubGraph<? extends J>> getSubGraphs();
Map<Class<? extends J>, SubGraph<? extends J>> getKeySubGraphs();
@Override
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
default Map<Class, Subgraph> getSubgraphs() {
return (Map) getSubGraphs();
}
@Override
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
default Map<Class, Subgraph> getKeySubgraphs() {
return (Map) getKeySubGraphs();
}

View File

@ -14,19 +14,26 @@ import org.hibernate.metamodel.model.domain.PersistentAttribute;
/**
* A container for {@link AttributeNode} references.
* <p>
* Acts as a "bridge" between JPA's {@link jakarta.persistence.EntityGraph}
* and {@link jakarta.persistence.Subgraph}.
*
* @apiNote Acts as an abstraction over the JPA-defined interfaces
* {@link jakarta.persistence.EntityGraph} and
* {@link jakarta.persistence.Subgraph}, which have no
* common supertype.
*
* @author Strong Liu
* @author Steve Ebersole
* @author Andrea Boriero
*
* @see RootGraph
* @see SubGraph
* @see jakarta.persistence.EntityGraph
* @see jakarta.persistence.Subgraph
*/
public interface Graph<J> extends GraphNode<J> {
/**
* Add a subgraph rooted at a plural attribute, allowing
* further nodes to be added to the subgraph.
* Add a subgraph rooted at a plural attribute, allowing further
* nodes to be added to the subgraph.
*
* @apiNote This method is missing in JPA, and nodes cannot be
* added in a typesafe way to subgraphs representing
@ -52,10 +59,12 @@ public interface Graph<J> extends GraphNode<J> {
*
* @throws CannotBecomeEntityGraphException If the named attribute is not entity-valued
*/
RootGraph<J> makeRootGraph(String name, boolean mutable) throws CannotBecomeEntityGraphException;
RootGraph<J> makeRootGraph(String name, boolean mutable)
throws CannotBecomeEntityGraphException;
/**
* Create a (mutable or immutable) {@link SubGraph} rooted at this {@link Graph}.
* Create a new (mutable or immutable) {@link SubGraph} rooted at
* this {@link Graph}.
*/
SubGraph<J> makeSubGraph(boolean mutable);
@ -67,37 +76,38 @@ public interface Graph<J> extends GraphNode<J> {
// AttributeNode handling
/**
* Ultimately only needed for implementing {@link jakarta.persistence.EntityGraph#getAttributeNodes()}
* Ultimately only needed for implementing
* {@link jakarta.persistence.EntityGraph#getAttributeNodes()}
* and {@link jakarta.persistence.Subgraph#getAttributeNodes()}
*/
List<AttributeNode<?>> getGraphAttributeNodes();
/**
* Find an already existing AttributeNode by attributeName within this
* container
* Find an already existing AttributeNode by attributeName within
* this container
*/
<AJ> AttributeNode<AJ> findAttributeNode(String attributeName);
/**
* Find an already existing AttributeNode by corresponding attribute
* reference, within this container
* reference, within this container.
*/
<AJ> AttributeNode<AJ> findAttributeNode(PersistentAttribute<? extends J, AJ> attribute);
/**
* Get a list of all existing AttributeNodes within this container
* Get a list of all existing AttributeNodes within this container.
*/
List<AttributeNode<?>> getAttributeNodeList();
/**
* Add an AttributeNode (with no associated SubGraphNodes) to this container
* by attribute name
* Add an {@link AttributeNode} (with no associated {@link SubGraph})
* to this container by attribute name.
*/
<AJ> AttributeNode<AJ> addAttributeNode(String attributeName);
/**
* Add an AttributeNode (with no associated SubGraphNode) to this container
* by Attribute reference
* Add an {@link AttributeNode} (with no associated {@link SubGraph})
* to this container by attribute reference.
*/
<AJ> AttributeNode<AJ> addAttributeNode(PersistentAttribute<? extends J,AJ> attribute);
@ -107,31 +117,39 @@ public interface Graph<J> extends GraphNode<J> {
// sub graph nodes
/**
* Create a (mutable) SubGraphNode associated with the named AttributeNode.
* The created SubGraphNode is returned
* Create and return a new (mutable) {@link SubGraph} associated with
* the named {@link AttributeNode}.
*
* @apiNote If no such AttributeNode exists yet, it is created.
*/
<AJ> SubGraph<AJ> addSubGraph(String attributeName) throws CannotContainSubGraphException;
<AJ> SubGraph<AJ> addSubGraph(String attributeName)
throws CannotContainSubGraphException;
<AJ> SubGraph<AJ> addSubGraph(String attributeName, Class<AJ> type) throws CannotContainSubGraphException;
<AJ> SubGraph<AJ> addSubGraph(String attributeName, Class<AJ> type)
throws CannotContainSubGraphException;
/**
* Create a (mutable) SubGraphNode associated with the AttributeNode for the given
* Attribute. The created SubGraphNode is returned
* Create and return a new (mutable) {@link SubGraph} associated with
* the {@link AttributeNode} for the given attribute.
*
* @apiNote If no such AttributeNode exists yet, it is created.
*/
<AJ> SubGraph<AJ> addSubGraph(PersistentAttribute<? extends J, AJ> attribute) throws CannotContainSubGraphException;
<AJ> SubGraph<AJ> addSubGraph(PersistentAttribute<? extends J, AJ> attribute)
throws CannotContainSubGraphException;
<AJ> SubGraph<? extends AJ> addSubGraph(PersistentAttribute<? extends J, AJ> attribute, Class<? extends AJ> type) throws CannotContainSubGraphException;
<AJ> SubGraph<? extends AJ> addSubGraph(PersistentAttribute<? extends J, AJ> attribute, Class<? extends AJ> type)
throws CannotContainSubGraphException;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// key sub graph nodes
<AJ> SubGraph<AJ> addKeySubGraph(String attributeName) throws CannotContainSubGraphException;
<AJ> SubGraph<AJ> addKeySubGraph(String attributeName, Class<AJ> type) throws CannotContainSubGraphException;
<AJ> SubGraph<AJ> addKeySubGraph(String attributeName)
throws CannotContainSubGraphException;
<AJ> SubGraph<AJ> addKeySubGraph(String attributeName, Class<AJ> type)
throws CannotContainSubGraphException;
<AJ> SubGraph<AJ> addKeySubGraph(PersistentAttribute<? extends J,AJ> attribute) throws CannotContainSubGraphException;
<AJ> SubGraph<? extends AJ> addKeySubGraph(PersistentAttribute<? extends J,AJ> attribute, Class<? extends AJ> type) throws CannotContainSubGraphException;
<AJ> SubGraph<AJ> addKeySubGraph(PersistentAttribute<? extends J,AJ> attribute)
throws CannotContainSubGraphException;
<AJ> SubGraph<? extends AJ> addKeySubGraph(PersistentAttribute<? extends J,AJ> attribute, Class<? extends AJ> type)
throws CannotContainSubGraphException;
}

View File

@ -7,9 +7,12 @@
package org.hibernate.graph;
/**
* Commonality between {@link AttributeNode} and {@link Graph}.
* Common operations of {@link AttributeNode} and {@link Graph}.
*
* @author Steve Ebersole
*
* @see AttributeNode
* @see Graph
*/
public interface GraphNode<J> {
boolean isMutable();

View File

@ -15,18 +15,18 @@ import jakarta.persistence.metamodel.Attribute;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
/**
* Hibernate extension to the JPA {@link EntityGraph} contract.
* Extends the JPA-defined {@link EntityGraph} with additional operations.
*
* @author Steve Ebersole
* @author Andrea Boriero
*
* @see SubGraph
*/
public interface RootGraph<J> extends Graph<J>, EntityGraph<J> {
// todo (6.0) : do we want to consolidate this functionality on AttributeNodeContainer?
boolean appliesTo(String entityName);
boolean appliesTo(Class entityType);
// boolean appliesTo(String entityName);
//
// boolean appliesTo(Class<?> entityType);
@Override
RootGraph<J> makeRootGraph(String name, boolean mutable);
@ -37,44 +37,38 @@ public interface RootGraph<J> extends Graph<J>, EntityGraph<J> {
<T1> SubGraph<? extends T1> addSubclassSubgraph(Class<? extends T1> type);
@Override
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
default List<AttributeNode<?>> getAttributeNodes() {
return (List) getAttributeNodeList();
}
@Override
default void addAttributeNodes(String... names) {
if ( names == null ) {
return;
}
for ( String name : names ) {
addAttributeNode( name );
if ( names != null ) {
for ( String name : names ) {
addAttributeNode( name );
}
}
}
@Override
@SuppressWarnings("unchecked")
default void addAttributeNodes(Attribute<J, ?>... attributes) {
if ( attributes == null ) {
return;
}
for ( Attribute<J, ?> attribute : attributes ) {
addAttributeNode( (PersistentAttribute) attribute );
if ( attributes != null ) {
for ( Attribute<J, ?> attribute : attributes ) {
addAttributeNode( (PersistentAttribute<J,?>) attribute );
}
}
}
@Override
default <X> SubGraph<X> addSubgraph(Attribute<J, X> attribute) {
//noinspection unchecked
return addSubGraph( (PersistentAttribute) attribute );
return addSubGraph( (PersistentAttribute<J,X>) attribute );
}
@Override
default <X> SubGraph<? extends X> addSubgraph(Attribute<J, X> attribute, Class<? extends X> type) {
//noinspection unchecked
return addSubGraph( (PersistentAttribute) attribute, type );
return addSubGraph( (PersistentAttribute<J,X>) attribute, type );
}
@Override
@ -89,14 +83,12 @@ public interface RootGraph<J> extends Graph<J>, EntityGraph<J> {
@Override
default <X> SubGraph<X> addKeySubgraph(Attribute<J, X> attribute) {
//noinspection unchecked
return addKeySubGraph( (PersistentAttribute) attribute );
return addKeySubGraph( (PersistentAttribute<J,X>) attribute );
}
@Override
default <X> SubGraph<? extends X> addKeySubgraph(Attribute<J, X> attribute, Class<? extends X> type) {
//noinspection unchecked
return addKeySubGraph( (PersistentAttribute) attribute, type );
return addKeySubGraph( (PersistentAttribute<J,X>) attribute, type );
}
@Override

View File

@ -7,19 +7,23 @@
package org.hibernate.graph;
import java.util.List;
import jakarta.persistence.Subgraph;
import jakarta.persistence.metamodel.Attribute;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
/**
* Hibernate extension to the JPA entity-graph Subgraph contract.
* Extends the JPA-defined {@link Subgraph} with additional operations.
*
* @author Steve Ebersole
* @author Andrea Boriero
*
* @see RootGraph
*/
public interface SubGraph<J> extends Graph<J>, jakarta.persistence.Subgraph<J> {
public interface SubGraph<J> extends Graph<J>, Subgraph<J> {
@Override
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
default List<jakarta.persistence.AttributeNode<?>> getAttributeNodes() {
return (List) getAttributeNodeList();
}

View File

@ -7,7 +7,6 @@
package org.hibernate.graph.internal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -26,6 +25,8 @@ import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
import static java.util.Collections.emptyList;
/**
* Base class for {@link RootGraph} and {@link SubGraph} implementations.
*
@ -66,10 +67,9 @@ public abstract class AbstractGraph<J> extends AbstractGraphNode<J> implements G
}
@Override
@SuppressWarnings("unchecked")
public RootGraphImplementor<J> makeRootGraph(String name, boolean mutable) {
if ( getGraphedType() instanceof EntityDomainType ) {
return new RootGraphImpl( name, mutable, this );
return new RootGraphImpl<>( name, mutable, this );
}
throw new CannotBecomeEntityGraphException(
@ -79,23 +79,21 @@ public abstract class AbstractGraph<J> extends AbstractGraphNode<J> implements G
@Override
@SuppressWarnings("unchecked")
public void merge(GraphImplementor<J>... others) {
if ( others == null ) {
public void merge(GraphImplementor<? extends J> other) {
if ( other == null ) {
return;
}
for ( GraphImplementor<J> other : others ) {
for ( AttributeNodeImplementor<?> attributeNode : other.getAttributeNodeImplementors() ) {
final AttributeNodeImplementor localAttributeNode = findAttributeNode(
(PersistentAttribute) attributeNode.getAttributeDescriptor()
);
if ( localAttributeNode != null ) {
// keep the local one, but merge in the incoming one
localAttributeNode.merge( attributeNode );
}
else {
addAttributeNode( attributeNode.makeCopy( true ) );
}
for ( AttributeNodeImplementor<?> attributeNode : other.getAttributeNodeImplementors() ) {
final AttributeNodeImplementor<?> localAttributeNode = findAttributeNode(
(PersistentAttribute<? extends J,?>) attributeNode.getAttributeDescriptor()
);
if ( localAttributeNode != null ) {
// keep the local one, but merge in the incoming one
localAttributeNode.merge( attributeNode );
}
else {
addAttributeNode( attributeNode.makeCopy( true ) );
}
}
@ -121,14 +119,11 @@ public abstract class AbstractGraph<J> extends AbstractGraphNode<J> implements G
attrNodeMap.put( incomingAttributeNode.getAttributeDescriptor(), attributeNode );
}
else {
// because... Java
@SuppressWarnings("rawtypes")
final AttributeNodeImplementor attributeNodeFinal = attributeNode;
incomingAttributeNode.visitSubGraphs(
(subType, subGraph) -> attributeNodeFinal.addSubGraph(
subType,
// we assume the subGraph has been properly copied if needed
subGraph
)
// we assume the subGraph has been properly copied if needed
(subType, subGraph) -> attributeNodeFinal.addSubGraph( subGraph )
);
}
@ -139,33 +134,24 @@ public abstract class AbstractGraph<J> extends AbstractGraphNode<J> implements G
@SuppressWarnings("unchecked")
public <AJ> AttributeNodeImplementor<AJ> findAttributeNode(String attributeName) {
final PersistentAttribute<? super J, ?> attribute = managedType.findAttributeInSuperTypes( attributeName );
if ( attribute == null ) {
return null;
}
return findAttributeNode( (PersistentAttribute) attribute );
return attribute == null ? null : findAttributeNode( (PersistentAttribute<? extends J, AJ>) attribute );
}
@Override
@SuppressWarnings("unchecked")
public <AJ> AttributeNodeImplementor<AJ> findAttributeNode(PersistentAttribute<? extends J, AJ> attribute) {
if ( attrNodeMap == null ) {
return null;
}
return (AttributeNodeImplementor) attrNodeMap.get( attribute );
return attrNodeMap == null ? null : (AttributeNodeImplementor<AJ>) attrNodeMap.get( attribute );
}
@Override
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
public List<AttributeNode<?>> getGraphAttributeNodes() {
return (List) getAttributeNodeImplementors();
}
@Override
public List<AttributeNodeImplementor<?>> getAttributeNodeImplementors() {
return attrNodeMap == null
? Collections.emptyList()
: new ArrayList<>( attrNodeMap.values() );
return attrNodeMap == null ? emptyList() : new ArrayList<>( attrNodeMap.values() );
}
@Override
@ -185,12 +171,12 @@ public abstract class AbstractGraph<J> extends AbstractGraphNode<J> implements G
public <AJ> AttributeNodeImplementor<AJ> findOrCreateAttributeNode(PersistentAttribute<? extends J, AJ> attribute) {
verifyMutability();
AttributeNodeImplementor attrNode = null;
AttributeNodeImplementor<AJ> attrNode = null;
if ( attrNodeMap == null ) {
attrNodeMap = new HashMap<>();
}
else {
attrNode = attrNodeMap.get( attribute );
attrNode = (AttributeNodeImplementor<AJ>) attrNodeMap.get( attribute );
}
if ( attrNode == null ) {

View File

@ -6,16 +6,17 @@
*/
package org.hibernate.graph.internal;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
import org.hibernate.graph.CannotContainSubGraphException;
import org.hibernate.graph.SubGraph;
import org.hibernate.graph.spi.AttributeNodeImplementor;
import org.hibernate.graph.spi.GraphImplementor;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
@ -23,6 +24,8 @@ import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.jboss.logging.Logger;
import static java.util.Collections.emptyMap;
/**
* Hibernate implementation of the JPA AttributeNode contract
*
@ -69,25 +72,13 @@ public class AttributeNodeImpl<J>
}
@Override
@SuppressWarnings("unchecked")
public Map<Class<? extends J>, SubGraphImplementor<? extends J>> getSubGraphMap() {
if ( subGraphMap == null ) {
return Collections.emptyMap();
}
else {
return subGraphMap;
}
return subGraphMap == null ? emptyMap() : subGraphMap;
}
@Override
@SuppressWarnings("unchecked")
public Map<Class<? extends J>, SubGraphImplementor<? extends J>> getKeySubGraphMap() {
if ( keySubGraphMap == null ) {
return Collections.emptyMap();
}
else {
return keySubGraphMap;
}
return keySubGraphMap == null ? emptyMap() : keySubGraphMap;
}
@Override
@ -107,68 +98,59 @@ public class AttributeNodeImpl<J>
private <S extends J> SubGraphImplementor<S> internalMakeSubgraph(ManagedDomainType<S> type) {
assert type != null;
log.debugf( "Making sub-graph : ( (%s) %s )", type.getTypeName(), getAttributeName() );
final SubGraphImplementor<S> subGraph = type.makeSubGraph();
internalAddSubGraph( type.getJavaType(), subGraph );
internalAddSubGraph( subGraph );
return subGraph;
}
@SuppressWarnings("unchecked")
private <T extends J> ManagedDomainType<T> valueGraphTypeAsManaged() {
final SimpleDomainType<J> valueGraphType = (SimpleDomainType) getAttributeDescriptor().getValueGraphType();
final DomainType<?> valueGraphType = getAttributeDescriptor().getValueGraphType();
if ( valueGraphType instanceof ManagedDomainType ) {
return (ManagedDomainType) valueGraphType;
return (ManagedDomainType<T>) valueGraphType;
}
else {
throw new CannotContainSubGraphException(
String.format(
Locale.ROOT,
"Attribute [%s] (%s) cannot contain value sub-graphs",
getAttributeName(),
getAttributeDescriptor().getPersistentAttributeType().name()
)
);
}
throw new CannotContainSubGraphException(
String.format(
Locale.ROOT,
"Attribute [%s] (%s) cannot contain value sub-graphs",
getAttributeName(),
getAttributeDescriptor().getPersistentAttributeType().name()
)
);
}
private static final Logger log = Logger.getLogger( AttributeNodeImpl.class );
@SuppressWarnings("unchecked")
private <S extends J> SubGraphImplementor<S> internalMakeSubgraph(Class<S> subType) {
verifyMutability();
final ManagedDomainType<S> managedType = valueGraphTypeAsManaged();
if ( subType == null ) {
subType = managedType.getJavaType();
}
return internalMakeSubgraph( managedType.findSubType( subType ) );
return internalMakeSubgraph( managedType.findSubType( subType == null ? managedType.getJavaType() : subType ) );
}
@SuppressWarnings("unchecked")
protected <S extends J> void internalAddSubGraph(Class<S> subType, SubGraphImplementor<S> subGraph) {
protected void internalAddSubGraph(SubGraphImplementor<? extends J> subGraph) {
log.tracef( "Adding sub-graph : ( (%s) %s )", subGraph.getGraphedType().getTypeName(), getAttributeName() );
if ( subGraphMap == null ) {
subGraphMap = new HashMap<>();
}
final SubGraphImplementor<? extends J> previous = subGraphMap.put( subType, (SubGraphImplementor) subGraph );
final SubGraphImplementor<? extends J> previous = subGraphMap.put( subGraph.getClassType(), subGraph );
if ( previous != null ) {
log.debugf( "Adding sub-graph [%s] over-wrote existing [%s]", subGraph, previous );
}
}
@Override
@SuppressWarnings("unchecked")
public <S extends J> void addSubGraph(Class<S> subType, SubGraph<S> subGraph) {
verifyMutability();
assert subGraph.getClassType() == subType;
internalAddSubGraph( (SubGraphImplementor<S>) subGraph );
}
internalAddSubGraph( subType, (SubGraphImplementor) subGraph );
@Override
public void addSubGraph(SubGraphImplementor<? extends J> subGraph) {
internalAddSubGraph( subGraph );
}
@Override
@ -187,44 +169,27 @@ public class AttributeNodeImpl<J>
}
private <S extends J> SubGraphImplementor<S> internalMakeKeySubgraph(ManagedDomainType<S> type) {
log.debugf( "Making key sub-graph : ( (%s) %s )", type.getTypeName(), getAttributeName() );
final SubGraphImplementor<S> subGraph = type.makeSubGraph();
internalAddKeySubGraph( type.getJavaType(), subGraph );
internalAddKeySubGraph( subGraph );
return subGraph;
}
@SuppressWarnings("unchecked")
private <S extends J> SubGraphImplementor<S> internalMakeKeySubgraph(Class<S> type) {
verifyMutability();
final ManagedDomainType<S> managedType = keyGraphTypeAsManaged();
final ManagedDomainType<S> subType;
if ( type == null ) {
subType = managedType;
}
else {
subType = managedType.findSubType( type );
}
final ManagedDomainType<S> subType = type == null ? managedType : managedType.findSubType( type );
subType.getJavaType();
return internalMakeKeySubgraph( subType );
}
@SuppressWarnings("unchecked")
protected <S extends J> void internalAddKeySubGraph(Class<S> subType, SubGraph<S> subGraph) {
log.tracef( "Adding key sub-graph : ( (%s) %s )", subType.getName(), getAttributeName() );
protected void internalAddKeySubGraph(SubGraph<? extends J> subGraph) {
log.tracef( "Adding key sub-graph : ( (%s) %s )", subGraph.getClassType().getName(), getAttributeName() );
if ( keySubGraphMap == null ) {
keySubGraphMap = new HashMap<>();
}
final SubGraphImplementor<? extends J> previous = keySubGraphMap.put( subType, (SubGraphImplementor) subGraph );
final SubGraphImplementor<? extends J> previous =
keySubGraphMap.put( subGraph.getClassType(), (SubGraphImplementor<? extends J>) subGraph );
if ( previous != null ) {
log.debugf( "Adding key sub-graph [%s] over-wrote existing [%]", subGraph, previous );
}
@ -232,62 +197,59 @@ public class AttributeNodeImpl<J>
@SuppressWarnings("unchecked")
private <T extends J> ManagedDomainType<T> keyGraphTypeAsManaged() {
final SimpleDomainType<J> keyGraphType = (SimpleDomainType) getAttributeDescriptor().getKeyGraphType();
final SimpleDomainType<?> keyGraphType = getAttributeDescriptor().getKeyGraphType();
if ( keyGraphType instanceof ManagedDomainType ) {
return (ManagedDomainType) keyGraphType;
return (ManagedDomainType<T>) keyGraphType;
}
else {
throw new CannotContainSubGraphException(
String.format(
Locale.ROOT,
"Attribute [%s#%s] (%s) cannot contain key sub-graphs - %s",
getAttributeDescriptor().getDeclaringType().getTypeName(),
getAttributeName(),
getAttributeDescriptor().getPersistentAttributeType().name(),
keyGraphType
)
);
}
throw new CannotContainSubGraphException(
String.format(
Locale.ROOT,
"Attribute [%s#%s] (%s) cannot contain key sub-graphs - %s",
getAttributeDescriptor().getDeclaringType().getTypeName(),
getAttributeName(),
getAttributeDescriptor().getPersistentAttributeType().name(),
keyGraphType
)
);
}
@Override
@SuppressWarnings("unchecked")
public <S extends J> void addKeySubGraph(Class<S> subType, SubGraph<S> subGraph) {
internalAddKeySubGraph( subType, subGraph );
assert subGraph.getClassType() == subType;
internalAddKeySubGraph( subGraph );
}
@Override
@SuppressWarnings("unchecked")
public AttributeNodeImplementor<J> makeCopy(boolean mutable) {
return new AttributeNodeImpl<>(
mutable,
this.attribute,
makeMapCopy( mutable, (Map) subGraphMap ),
makeMapCopy( mutable, (Map) keySubGraphMap ),
makeMapCopy( mutable, subGraphMap ),
makeMapCopy( mutable, keySubGraphMap ),
jpaMetamodel()
);
}
private <S extends J> Map<Class<S>, SubGraphImplementor<S>> makeMapCopy(
private Map<Class<? extends J>, SubGraphImplementor<? extends J>> makeMapCopy(
boolean mutable,
Map<Class<S>, SubGraphImplementor<S>> nodeMap) {
Map<Class<? extends J>, SubGraphImplementor<? extends J>> nodeMap) {
if ( nodeMap == null ) {
return null;
}
return CollectionHelper.makeCopy(
nodeMap,
type -> type,
subGraph -> subGraph.makeCopy( mutable )
);
else {
return nodeMap.entrySet().stream()
.map(entry -> Map.entry(entry.getKey(), entry.getValue().makeCopy( mutable )))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
}
@Override
@SuppressWarnings("unchecked")
public void merge(AttributeNodeImplementor<?> attributeNode) {
attributeNode.visitSubGraphs(
(incomingSubType, incomingGraph) -> {
SubGraphImplementor existing = null;
SubGraphImplementor<?> existing = null;
if ( subGraphMap == null ) {
subGraphMap = new HashMap<>();
}
@ -296,17 +258,17 @@ public class AttributeNodeImpl<J>
}
if ( existing != null ) {
existing.merge( incomingGraph );
existing.merge( (GraphImplementor) incomingGraph );
}
else {
internalAddSubGraph( (Class) incomingSubType, (SubGraphImplementor) incomingGraph.makeCopy( true ) );
internalAddSubGraph( (SubGraphImplementor) incomingGraph.makeCopy( true ) );
}
}
);
attributeNode.visitKeySubGraphs(
(incomingSubType, incomingGraph) -> {
SubGraphImplementor existing = null;
SubGraphImplementor<?> existing = null;
if ( keySubGraphMap == null ) {
keySubGraphMap = new HashMap<>();
}
@ -315,10 +277,10 @@ public class AttributeNodeImpl<J>
}
if ( existing != null ) {
existing.merge( incomingGraph );
existing.merge( (GraphImplementor) incomingGraph );
}
else {
internalAddKeySubGraph( (Class) incomingSubType, (SubGraphImplementor) incomingGraph.makeCopy( true ) );
internalAddKeySubGraph( (SubGraphImplementor) incomingGraph.makeCopy( true ) );
}
}
);

View File

@ -35,12 +35,7 @@ public class RootGraphImpl<J> extends AbstractGraph<J> implements EntityGraph<J>
}
public RootGraphImpl(String name, EntityDomainType<J> entityType, JpaMetamodel jpaMetamodel) {
this(
name,
entityType,
true,
jpaMetamodel
);
this( name, entityType, true, jpaMetamodel );
}
public RootGraphImpl(String name, boolean mutable, GraphImplementor<J> original) {
@ -65,11 +60,7 @@ public class RootGraphImpl<J> extends AbstractGraph<J> implements EntityGraph<J>
@Override
public RootGraphImplementor<J> makeRootGraph(String name, boolean mutable) {
if ( ! mutable && ! isMutable() ) {
return this;
}
return super.makeRootGraph( name, mutable );
return !mutable && !isMutable() ? this : super.makeRootGraph( name, mutable );
}
@Override
@ -78,13 +69,13 @@ public class RootGraphImpl<J> extends AbstractGraph<J> implements EntityGraph<J>
}
@Override
public boolean appliesTo(EntityDomainType<? super J> entityType) {
public boolean appliesTo(EntityDomainType<?> entityType) {
final ManagedDomainType<J> managedTypeDescriptor = getGraphedType();
if ( managedTypeDescriptor.equals( entityType ) ) {
return true;
}
IdentifiableDomainType<? super J> superType = entityType.getSupertype();
IdentifiableDomainType<?> superType = entityType.getSupertype();
while ( superType != null ) {
if ( managedTypeDescriptor.equals( superType ) ) {
return true;
@ -101,7 +92,7 @@ public class RootGraphImpl<J> extends AbstractGraph<J> implements EntityGraph<J>
}
@Override
public boolean appliesTo(Class type) {
public boolean appliesTo(Class<?> type) {
return appliesTo( jpaMetamodel().entity( type ) );
}
}

View File

@ -45,12 +45,12 @@ public class SubGraphImpl<J> extends AbstractGraph<J> implements SubGraphImpleme
}
@Override
public boolean appliesTo(ManagedDomainType<? super J> managedType) {
if ( this.getGraphedType().equals( managedType ) ) {
public boolean appliesTo(ManagedDomainType<?> managedType) {
if ( getGraphedType().equals( managedType ) ) {
return true;
}
ManagedDomainType superType = managedType.getSuperType();
ManagedDomainType<?> superType = managedType.getSuperType();
while ( superType != null ) {
if ( superType.equals( managedType ) ) {
return true;
@ -62,7 +62,7 @@ public class SubGraphImpl<J> extends AbstractGraph<J> implements SubGraphImpleme
}
@Override
public boolean appliesTo(Class<? super J> javaType) {
public boolean appliesTo(Class<?> javaType) {
return appliesTo( jpaMetamodel().managedType( javaType ) );
}
}

View File

@ -15,7 +15,7 @@ import org.hibernate.graph.SubGraph;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
/**
* Integration version of the AttributeNode contract
* Integration version of the {@link AttributeNode} contract
*
* @author Strong Liu
* @author Steve Ebersole
@ -24,11 +24,11 @@ public interface AttributeNodeImplementor<J> extends AttributeNode<J>, GraphNode
Map<Class<? extends J>, SubGraphImplementor<? extends J>> getSubGraphMap();
Map<Class<? extends J>, SubGraphImplementor<? extends J>> getKeySubGraphMap();
default void visitSubGraphs(BiConsumer<Class<?>, SubGraphImplementor<?>> consumer) {
default void visitSubGraphs(BiConsumer<Class<? extends J>, SubGraphImplementor<? extends J>> consumer) {
getSubGraphMap().forEach( consumer );
}
default void visitKeySubGraphs(BiConsumer<Class<?>, SubGraphImplementor<?>> consumer) {
default void visitKeySubGraphs(BiConsumer<Class<? extends J>, SubGraphImplementor<? extends J>> consumer) {
getKeySubGraphMap().forEach( consumer );
}
@ -45,7 +45,7 @@ public interface AttributeNodeImplementor<J> extends AttributeNode<J>, GraphNode
}
@Override
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
default Map<Class, Subgraph> getSubgraphs() {
return (Map) getSubGraphMap();
}
@ -76,4 +76,6 @@ public interface AttributeNodeImplementor<J> extends AttributeNode<J>, GraphNode
<S extends J> SubGraphImplementor<S> makeKeySubGraph(ManagedDomainType<S> subtype);
void merge(AttributeNodeImplementor<?> attributeNode);
void addSubGraph(SubGraphImplementor<? extends J> subGraph);
}

View File

@ -18,19 +18,19 @@ import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
/**
* Integration version of the Graph contract
* Integration version of the {@link Graph} contract
*
* @author Strong Liu
* @author Steve Ebersole
* @author Andrea Boriero
*/
public interface GraphImplementor<J> extends Graph<J>, GraphNodeImplementor<J> {
boolean appliesTo(ManagedDomainType<? super J> managedType);
boolean appliesTo(Class<? super J> javaType);
boolean appliesTo(ManagedDomainType<?> managedType);
@SuppressWarnings("unchecked")
void merge(GraphImplementor<J>... others);
boolean appliesTo(Class<?> javaType);
void merge(GraphImplementor<? extends J> other);
JpaMetamodel jpaMetamodel();
@ -39,7 +39,8 @@ public interface GraphImplementor<J> extends Graph<J>, GraphNodeImplementor<J> {
// Co-variant returns
@Override
RootGraphImplementor<J> makeRootGraph(String name, boolean mutable) throws CannotBecomeEntityGraphException;
RootGraphImplementor<J> makeRootGraph(String name, boolean mutable)
throws CannotBecomeEntityGraphException;
@Override
SubGraphImplementor<J> makeSubGraph(boolean mutable);
@ -60,7 +61,7 @@ public interface GraphImplementor<J> extends Graph<J>, GraphNodeImplementor<J> {
List<AttributeNodeImplementor<?>> getAttributeNodeImplementors();
@Override
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
default List<AttributeNode<?>> getAttributeNodeList() {
return (List) getAttributeNodeImplementors();
}
@ -72,7 +73,8 @@ public interface GraphImplementor<J> extends Graph<J>, GraphNodeImplementor<J> {
<AJ> AttributeNodeImplementor<AJ> findAttributeNode(PersistentAttribute<? extends J, AJ> attribute);
@Override
<AJ> AttributeNodeImplementor<AJ> addAttributeNode(String attributeName) throws CannotContainSubGraphException;
<AJ> AttributeNodeImplementor<AJ> addAttributeNode(String attributeName)
throws CannotContainSubGraphException;
@Override
<AJ> AttributeNodeImplementor<AJ> addAttributeNode(PersistentAttribute<? extends J, AJ> attribute)
@ -80,7 +82,7 @@ public interface GraphImplementor<J> extends Graph<J>, GraphNodeImplementor<J> {
@SuppressWarnings("unchecked")
default <AJ> AttributeNodeImplementor<AJ> findOrCreateAttributeNode(String name) {
return findOrCreateAttributeNode( (PersistentAttribute) getGraphedType().getAttribute( name ) );
return findOrCreateAttributeNode( (PersistentAttribute<? extends J,AJ>) getGraphedType().getAttribute( name ) );
}
<AJ> AttributeNodeImplementor<AJ> findOrCreateAttributeNode(PersistentAttribute<? extends J, AJ> attribute);
@ -91,8 +93,9 @@ public interface GraphImplementor<J> extends Graph<J>, GraphNodeImplementor<J> {
@Override
@SuppressWarnings("unchecked")
default <AJ> SubGraphImplementor<AJ> addSubGraph(String attributeName) throws CannotContainSubGraphException {
return (SubGraphImplementor) findOrCreateAttributeNode( attributeName ).makeSubGraph();
default <AJ> SubGraphImplementor<AJ> addSubGraph(String attributeName)
throws CannotContainSubGraphException {
return (SubGraphImplementor<AJ>) findOrCreateAttributeNode( attributeName ).makeSubGraph();
}
@Override
@ -121,7 +124,7 @@ public interface GraphImplementor<J> extends Graph<J>, GraphNodeImplementor<J> {
@Override
@SuppressWarnings("unchecked")
default <AJ> SubGraphImplementor<AJ> addKeySubGraph(String attributeName) {
return (SubGraphImplementor) findOrCreateAttributeNode( attributeName ).makeKeySubGraph();
return (SubGraphImplementor<AJ>) findOrCreateAttributeNode( attributeName ).makeKeySubGraph();
}
@Override
@ -137,7 +140,8 @@ public interface GraphImplementor<J> extends Graph<J>, GraphNodeImplementor<J> {
@Override
default <AJ> SubGraphImplementor<? extends AJ> addKeySubGraph(
PersistentAttribute<? extends J, AJ> attribute,
Class<? extends AJ> subType) throws CannotContainSubGraphException {
Class<? extends AJ> subType)
throws CannotContainSubGraphException {
return findOrCreateAttributeNode( attribute ).makeKeySubGraph( subType );
}
}

View File

@ -9,7 +9,7 @@ package org.hibernate.graph.spi;
import org.hibernate.graph.GraphNode;
/**
* Integration version of the GraphNode contract
* Integration version of the {@link GraphNode} contract
*
* @author Steve Ebersole
* @author Strong Liu

View File

@ -11,18 +11,20 @@ import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
/**
* Integration version of the RootGraph contract
* Integration version of the {@link RootGraph} contract
*
* @author Steve Ebersole
*/
public interface RootGraphImplementor<J> extends RootGraph<J>, GraphImplementor<J> {
boolean appliesTo(EntityDomainType<? super J> entityType);
boolean appliesTo(String entityName);
boolean appliesTo(EntityDomainType<?> entityType);
@Override
@SuppressWarnings("unchecked")
default boolean appliesTo(ManagedDomainType<? super J> managedType) {
default boolean appliesTo(ManagedDomainType<?> managedType) {
assert managedType instanceof EntityDomainType;
return appliesTo( (EntityDomainType) managedType );
return appliesTo( (EntityDomainType<?>) managedType );
}
@Override

View File

@ -12,7 +12,7 @@ import org.hibernate.graph.SubGraph;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
/**
* Integration version of the SubGraph contract
* Integration version of the {@link SubGraph} contract
*
* @author Steve Ebersole
*/
@ -22,15 +22,12 @@ public interface SubGraphImplementor<J> extends SubGraph<J>, GraphImplementor<J>
@Override
default SubGraphImplementor<J> makeSubGraph(boolean mutable) {
if ( ! mutable && ! isMutable() ) {
return this;
}
return makeCopy( mutable );
return !mutable && !isMutable() ? this : makeCopy( mutable );
}
@Override
RootGraphImplementor<J> makeRootGraph(String name, boolean mutable) throws CannotBecomeEntityGraphException;
RootGraphImplementor<J> makeRootGraph(String name, boolean mutable)
throws CannotBecomeEntityGraphException;
@Override
<AJ> SubGraphImplementor<AJ> addKeySubGraph(String attributeName);

View File

@ -0,0 +1,15 @@
/*
* 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
*/
/**
* This package defines an internal SPI abstracting over implementations
* of the APIs defined in {@link org.hibernate.graph}.
*/
@Incubating
package org.hibernate.graph.spi;
import org.hibernate.Incubating;

View File

@ -9,7 +9,6 @@ package org.hibernate.sql.results.internal;
import java.util.Map;
import java.util.Objects;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.graph.GraphSemantic;
import org.hibernate.graph.spi.AttributeNodeImplementor;
@ -30,10 +29,10 @@ import org.hibernate.sql.results.graph.Fetchable;
public class StandardEntityGraphTraversalStateImpl implements EntityGraphTraversalState {
private final GraphSemantic graphSemantic;
private GraphImplementor currentGraphContext;
private GraphImplementor<?> currentGraphContext;
public StandardEntityGraphTraversalStateImpl(GraphSemantic graphSemantic, RootGraphImplementor rootGraphImplementor) {
Objects.requireNonNull(graphSemantic, "graphSemantic cannot be null");
public StandardEntityGraphTraversalStateImpl(GraphSemantic graphSemantic, RootGraphImplementor<?> rootGraphImplementor) {
Objects.requireNonNull( graphSemantic, "graphSemantic cannot be null" );
Objects.requireNonNull( rootGraphImplementor, "rootGraphImplementor cannot be null" );
this.graphSemantic = graphSemantic;
this.currentGraphContext = rootGraphImplementor;
@ -51,25 +50,19 @@ public class StandardEntityGraphTraversalStateImpl implements EntityGraphTravers
return new TraversalResult( currentGraphContext, new FetchStrategy( FetchTiming.IMMEDIATE, true ) );
}
final GraphImplementor previousContextRoot = currentGraphContext;
AttributeNodeImplementor attributeNode = null;
if ( appliesTo( fetchParent ) ) {
attributeNode = currentGraphContext.findAttributeNode( fetchable.getFetchableName() );
}
final GraphImplementor<?> previousContextRoot = currentGraphContext;
final AttributeNodeImplementor<?> attributeNode = appliesTo( fetchParent )
? currentGraphContext.findAttributeNode( fetchable.getFetchableName() )
: null;
currentGraphContext = null;
FetchStrategy fetchStrategy = null;
final FetchStrategy fetchStrategy;
if ( attributeNode != null ) {
fetchStrategy = new FetchStrategy( FetchTiming.IMMEDIATE, true );
final Map<Class<?>, SubGraphImplementor> subgraphMap;
final Map<? extends Class<?>, ? extends SubGraphImplementor<?>> subgraphMap;
final Class<?> subgraphMapKey;
if ( fetchable instanceof PluralAttributeMapping ) {
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) fetchable;
if ( exploreKeySubgraph ) {
subgraphMap = attributeNode.getKeySubGraphMap();
subgraphMapKey = getEntityCollectionPartJavaClass( pluralAttributeMapping.getIndexDescriptor() );
@ -88,9 +81,12 @@ public class StandardEntityGraphTraversalStateImpl implements EntityGraphTravers
currentGraphContext = subgraphMap.get( subgraphMapKey );
}
}
if ( fetchStrategy == null && graphSemantic == GraphSemantic.FETCH ) {
else if ( graphSemantic == GraphSemantic.FETCH ) {
fetchStrategy = new FetchStrategy( FetchTiming.DELAYED, false );
}
else {
fetchStrategy = null;
}
return new TraversalResult( previousContextRoot, fetchStrategy );
}
@ -105,10 +101,7 @@ public class StandardEntityGraphTraversalStateImpl implements EntityGraphTravers
}
private boolean appliesTo(FetchParent fetchParent) {
if ( currentGraphContext == null ) {
return false;
}
return fetchParent.appliesTo( currentGraphContext );
return currentGraphContext != null && fetchParent.appliesTo( currentGraphContext );
}
}

View File

@ -19,7 +19,7 @@ import org.junit.Test;
public class EntityGraphsTest extends AbstractEntityGraphTest {
private final <T> void checkMerge(Class<T> rootType, EntityGraph<T> expected, @SuppressWarnings("unchecked") EntityGraph<T>... graphs) {
private <T> void checkMerge(Class<T> rootType, EntityGraph<T> expected, EntityGraph<T>... graphs) {
EntityManager entityManager = getOrCreateEntityManager();
EntityGraph<T> actual = EntityGraphs.merge( entityManager, rootType, graphs );
Assert.assertTrue( EntityGraphs.areEqual( expected, actual ) );