JPG SubGraph to determine the fetch type of an inline property

I have a Ride entity that injects a nested Route entity. A route has cities with list properties with a ManyToMany relation, so it has a LAZY fetchtype (and I don't want to use EAGER). Therefore, I want to define a NamedEntityGraph for the Ride entity in order to load the load on the Ride object with the Route with an updated list of cities. But when I deploy my war, I get this exception:

java.lang.IllegalArgumentException: [route] attribute is not a managed type

the trip

@Entity @NamedQueries({ @NamedQuery(name = "Ride.findAll", query = "SELECT m FROM Ride m")}) @NamedEntityGraphs({ @NamedEntityGraph( name = "rideWithInstanciatedRoute", attributeNodes = { @NamedAttributeNode(value = "route", subgraph = "routeWithTowns") }, subgraphs = { @NamedSubgraph( name = "routeWithTowns", attributeNodes = { @NamedAttributeNode("towns") } ) } ) }) public class Ride implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Embedded private Route route; // some getter and setter } 

Route

 @Embeddable public class Route implements Serializable { private static final long serialVersionUID = 1L; @ManyToMany private List<Town> towns; // some getter and setter } 
+5
source share
1 answer

Looking at the implementation of Hibernate org.hibernate.jpa.graph.internal.AttributeNodeImpl , we conclude that @NamedAttributeNode cannot be:

  • simple types (Java primitives and their wrappers, strings, enumerations, temporary files, ...)
  • embeddables (annotated using @Embedded )
  • item collections (annotated using @ElementCollection )
 if (attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.BASIC || attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.EMBEDDED ) { throw new IllegalArgumentException( String.format("Attribute [%s] is not of managed type", getAttributeName()) ); } 

I did not find a similar limitation in the JPA 2.1 specification, so it may be a flaw in Hibernate.


In your specific case, the problem is that @NamedEntityGraph belongs to the Route class, which is nested, so its use in the entity graph is apparently forbidden by Hibernate (unfortunately).

To make it work, you need to slightly modify the entity model. A few examples that come to my mind:

  • define Route as an object
  • delete Route and move its towns field to the Ride object (simplifies the entity model)
  • move the Route field from the Ride to the Town object, add a routedTowns map to the Ride object:

     @Entity public class Ride implements Serializable { ... @ManyToMany(mappedBy = "rides") private Map<Route, Town> routedTowns; ... } @Entity public class Town implements Serializable { ... @ManyToMany private List<Ride> rides; @Embeddable private Route route; ... } 

Of course, an object graph may require changes accordingly.

+5
source

Source: https://habr.com/ru/post/1209473/


All Articles