Skip to content

Commit c9c11a4

Browse files
committed
HHH-19023 add operations on EntityGraphs to allow for session-free graph creation
1 parent 5d4cdf2 commit c9c11a4

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

hibernate-core/src/main/java/org/hibernate/graph/EntityGraphs.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@
1818
import jakarta.persistence.Subgraph;
1919
import jakarta.persistence.TypedQuery;
2020

21+
import jakarta.persistence.metamodel.EntityType;
2122
import org.hibernate.engine.spi.SessionImplementor;
23+
import org.hibernate.graph.internal.RootGraphImpl;
2224
import org.hibernate.graph.spi.GraphImplementor;
2325
import org.hibernate.graph.spi.RootGraphImplementor;
26+
import org.hibernate.metamodel.RepresentationMode;
27+
import org.hibernate.metamodel.model.domain.EntityDomainType;
2428
import org.hibernate.query.SelectionQuery;
2529

2630
/**
@@ -33,6 +37,43 @@
3337
*/
3438
public final class EntityGraphs {
3539

40+
/**
41+
* Create a new entity graph rooted at the given entity, without
42+
* needing a reference to the session or session factory.
43+
*
44+
* @param rootType The {@link EntityType} representing the root
45+
* entity of the graph
46+
* @return a new mutable {@link EntityGraph}
47+
*
48+
* @since 7.0
49+
*/
50+
public static <T> EntityGraph<T> createGraph(EntityType<T> rootType) {
51+
return new RootGraphImpl<>( null, (EntityDomainType<T>) rootType );
52+
}
53+
54+
/**
55+
* Create a new entity graph rooted at the given
56+
* {@linkplain RepresentationMode#MAP dynamic entity}, without
57+
* needing a reference to the session or session factory.
58+
*
59+
* @param rootType The {@link EntityType} representing the root
60+
* entity of the graph, which must be a dynamic
61+
* entity
62+
* @return a new mutable {@link EntityGraph}
63+
*
64+
* @since 7.0
65+
*/
66+
public static EntityGraph<Map<String,?>> createGraphForDynamicEntity(EntityType<?> rootType) {
67+
final EntityDomainType<?> domainType = (EntityDomainType<?>) rootType;
68+
if ( domainType.getRepresentationMode() != RepresentationMode.MAP ) {
69+
throw new IllegalArgumentException( "Entity '" + domainType.getHibernateEntityName()
70+
+ "' is not a dynamic entity" );
71+
}
72+
@SuppressWarnings("unchecked") //Safe, because we just checked
73+
final EntityDomainType<Map<String, ?>> dynamicEntity = (EntityDomainType<Map<String, ?>>) domainType;
74+
return new RootGraphImpl<>( null, dynamicEntity );
75+
}
76+
3677
/**
3778
* Merges multiple entity graphs into a single graph that specifies the
3879
* fetching/loading of all attributes the input graphs specify.

hibernate-core/src/main/java/org/hibernate/graph/Graph.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.util.List;
88

99
import jakarta.persistence.metamodel.Attribute;
10+
import jakarta.persistence.metamodel.EntityType;
1011
import jakarta.persistence.metamodel.ManagedType;
1112
import jakarta.persistence.metamodel.MapAttribute;
1213
import jakarta.persistence.metamodel.PluralAttribute;
@@ -33,12 +34,17 @@
3334
* <p>
3435
* Extends the JPA-defined {@link jakarta.persistence.Graph} with additional operations.
3536
* <p>
36-
* There are a range of ways to create {@code Graph}s:
37+
* There are a range of ways to define {@code Graph}s:
3738
* <ul>
3839
* <li>programmatically, beginning with {@link org.hibernate.Session#createEntityGraph(Class)},
3940
* <li>using the {@link jakarta.persistence.NamedEntityGraph @NamedEntityGraph} annotation, or
4041
* <li>using the mini-language understood by {@link GraphParser}.
4142
* </ul>
43+
* <p>
44+
* When a graph is defined programmatically, the new graph is usually instantiated by calling
45+
* {@link jakarta.persistence.EntityManager#createEntityGraph(Class)}. However, this requires
46+
* a reference to and {@code EntityManager}, which might not always be convenient. An
47+
* alternative is provided by {@link EntityGraphs#createGraph(EntityType)}.
4248
*
4349
* @apiNote Historically, both {@link jakarta.persistence.EntityGraph} and this interface
4450
* declared operations with incorrect generic types, leading to unsound code. This was

hibernate-core/src/main/java/org/hibernate/graph/RootGraph.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package org.hibernate.graph;
66

77
import jakarta.persistence.EntityGraph;
8+
import jakarta.persistence.metamodel.EntityType;
89

910
/**
1011
* Extends the JPA-defined {@link EntityGraph} with additional operations.
@@ -13,6 +14,13 @@
1314
* @author Andrea Boriero
1415
*
1516
* @see SubGraph
17+
* @see org.hibernate.Session#createEntityGraph(Class)
18+
* @see org.hibernate.Session#createEntityGraph(String)
19+
* @see org.hibernate.Session#createEntityGraph(Class, String)
20+
* @see org.hibernate.SessionFactory#findEntityGraphByName(String)
21+
* @see org.hibernate.SessionFactory#createGraphForDynamicEntity(String)
22+
* @see EntityGraphs#createGraph(EntityType)
23+
* @see EntityGraphs#createGraphForDynamicEntity(EntityType)
1624
*/
1725
public interface RootGraph<J> extends Graph<J>, EntityGraph<J> {
1826

0 commit comments

Comments
 (0)