'Using EntityGraph with SuperClasses and Embedded Attributes
I would like to use the EntityGraph Feature because of the known n+1 Problem. I have the following Entities structure:
@Entity
@Table(name = "customer")
public class Customer extends Person {
@Column(name = "foo")
public String foo;
@Column(name = "bar")
public String bar;
}
@Entity
@Table(name = "person")
public class Person {
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "car.id")
public Car car;
@Embedded
public Key key;
}
@Entity
@Table(name = "car")
public class Car {
@Column(name = "a")
public String a;
@Column(name = "b")
public String b;
}
@Embeddable
public class Key
{
@Column(name = "key_id")
public Long keyId;
@Column(name = "key_color")
public String keyColor;
}
Now I want to use a NamedEntityGraph. As far as I understand with "@NamedEntityGraph(name = "getCustomer", includeAllAttributes=true)" it should work but it doesnt.
The NamedEntityGraph call with
em.createQuery(criteriaQuery).setHint("javax.persistence.fetchgraph", em.getEntityGraph("getCustomer")).getResultList()
returns the amount of Customers in the database but all Attributes including car and the Embedded Attribute key is always null.
Do I have to use subgraphs? I tried to declare the NamedEntityGraph on Customer class also on Person class. It makes no difference.
EDIT: After struggling a long time with this problem, i tried to break down it to the lowest level with these two entities
@Entity
@Table(name = "publication")
@NamedEntityGraph(name = "graph.Publication.articles",
attributeNodes = @NamedAttributeNode("articles"))
public class Publication {
@Id
private String publicationId;
private String name;
private String category;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "publicationId")
private List<Article> articles;
@Entity
@Table(name = "article")
public class Article {
@Id
private String articleId;
private String title;
private String publicationId;
}
If i create a query i can see further more than one query in the postgres log.
EntityGraph<?> entityGraph = em.getEntityGraph("graph.Publication.articles");
List resultList = em.createQuery("SELECT x FROM Publication x").setHint("javax.persistence.fetchgraph", entityGraph).getResultList();
Different queries for all publications
SELECT ARTICLEID, publicationId, TITLE FROM article WHERE (publicationId = $1) parameters: $1 = 'publication_1'
SELECT ARTICLEID, publicationId, TITLE FROM article WHERE (publicationId = $1) parameters: $1 = 'publication_2'
But I would only have expected one query with a join here.
Solution 1:[1]
Finally I found a solution for my problem. I refer to the edited part of my question.
I found this page which describes very well how to use batch query hints to improve performance. http://java-persistence-performance.blogspot.com/2010/08/batch-fetching-optimizing-object-graph.html?m=1
For my example I don't need the entitygraph anymore. The query should created like this
List resultList = em.createQuery("SELECT x FROM Publication x").setHint("eclipselink.batch", "x.articles").getResultList();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | sylo |