Home » Eclipse Projects » EclipseLink » Cant get NamedEntityGraph to work....(NamedEntityGraph)
Cant get NamedEntityGraph to work.... [message #1710510] |
Wed, 07 October 2015 08:46 |
Asaf Natan Messages: 3 Registered: October 2015 |
Junior Member |
|
|
Hi ,
im trying to solve the n+1 problem using the namedentitygraph , it couldnt get it to work , in my project - so i have make three test classes to check it more thoroughly , and still i cant get it to work , am i doing anything wrong?
Rest Service returning Test3 instance:
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Test3 get(@PathParam("id") String id){
EntityGraph<?> gr=em.getEntityGraph("testGraph");
CriteriaBuilder cb=em.getCriteriaBuilder();
CriteriaQuery<Test3> q = cb.createQuery(Test3.class);
Root<Test3> r=q.from(Test3.class);
q.select(r).where(cb.equal(r.get(Test3_.id), id));
TypedQuery<Test3> query=em.createQuery(q);
query.setHint("javax.persistence.loadgraph", gr);
return query.getSingleResult();
}
Test3.java:
@NamedEntityGraph(name="testGraph",attributeNodes={@NamedAttributeNode(value="tests",subgraph="test2Sub")},
subgraphs={@NamedSubgraph(attributeNodes = { @NamedAttributeNode(value = "tests") }, name = "test2Sub")})
@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class, property = "json-id")
public class Test3 implements Serializable{
@Id
@Column(name = "id", nullable = false, length = 22)
private String id;
@OneToMany(mappedBy="test3", fetch=FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name = "id")
private Set<Test2> tests= new HashSet<>();
public Test3() {
id=getBase64ID();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@OneToMany(mappedBy="test3", fetch=FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name = "id")
public Set<Test2> getTests() {
return tests;
}
public void setTests(Set<Test2> tests) {
this.tests = tests;
}
protected String getBase64ID() {
String result;
try {
result = new String(Base64.encodeBase64(Hex.decodeHex(UUID.randomUUID().toString().replaceAll("-", "")
.toCharArray())));
result = result.replace("/", "-"); // we cannot afford a slash
result =result.substring(0,22); //we don't need the trailing ==
} catch (DecoderException e) {
result = "errorinid";
}
return result;
}
}
Test3.java
@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class, property = "json-id")
public class Test2 implements Serializable{
@Id
@Column(name = "id", nullable = false, length = 22)
private String id;
@ManyToOne(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name="test3" ,referencedColumnName="id")
private Test3 test3;
@OneToMany(mappedBy="test2", fetch=FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name = "id")
private Set<Test4> tests= new HashSet<>();
public Test2() {
id=getBase64ID();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
protected String getBase64ID() {
String result;
try {
result = new String(Base64.encodeBase64(Hex.decodeHex(UUID.randomUUID().toString().replaceAll("-", "")
.toCharArray())));
result = result.replace("/", "-"); // we cannot afford a slash
result =result.substring(0,22); //we don't need the trailing ==
} catch (DecoderException e) {
result = "errorinid";
}
return result;
}
@ManyToOne(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name="test3" ,referencedColumnName="id")
public Test3 getTest3() {
return test3;
}
public void setTest3(Test3 test3) {
this.test3 = test3;
}
@OneToMany(mappedBy="test2", fetch=FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name = "id")
public Set<Test4> getTests() {
return tests;
}
public void setTests(Set<Test4> tests) {
this.tests = tests;
}
Test4.java:
@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class, property = "json-id")
public class Test4 implements Serializable{
@Id
@Column(name = "id", nullable = false, length = 22)
private String id;
@ManyToOne(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name="test2" ,referencedColumnName="id")
private Test2 test2;
public Test4() {
id=getBase64ID();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@ManyToOne(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name="test2" ,referencedColumnName="id")
public Test2 getTest() {
return test2;
}
public void setTest(Test2 test) {
this.test2 = test;
}
protected String getBase64ID() {
String result;
try {
result = new String(Base64.encodeBase64(Hex.decodeHex(UUID.randomUUID().toString().replaceAll("-", "")
.toCharArray())));
result = result.replace("/", "-"); // we cannot afford a slash
result =result.substring(0,22); //we don't need the trailing ==
} catch (DecoderException e) {
result = "errorinid";
}
return result;
}
}
eclipselinksql.log:
11:46:03,163 DEBUG [org.eclipse.persistence.sql] (default task-4) SELECT id FROM TEST3 WHERE (id = ?)
bind => [ZTGTJf1JRoGKn6qI8LyngA]
11:46:03,174 DEBUG [org.eclipse.persistence.sql] (default task-4) SELECT id, test3 FROM TEST2 WHERE (test3 = ?)
bind => [ZTGTJf1JRoGKn6qI8LyngA]
11:46:03,177 DEBUG [org.eclipse.persistence.sql] (default task-4) SELECT id, test2 FROM TEST4 WHERE (test2 = ?)
bind => [T5qrmwUdSkO24H7ZRBNhMg]
11:46:03,179 DEBUG [org.eclipse.persistence.sql] (default task-4) SELECT id, test2 FROM TEST4 WHERE (test2 = ?)
bind => [Ibitp+k4SOCnOb1SqazZlQ]
|
|
|
Re: Cant get NamedEntityGraph to work.... [message #1710818 is a reply to message #1710510] |
Fri, 09 October 2015 14:01 |
Chris Delahunt Messages: 1389 Registered: July 2009 |
Senior Member |
|
|
Your EntityGraph is empty, and because you have used it as a javax.persistence.loadgraph, it means that all attributes are defaulting to their specified or default FetchType. It is pretty much the same thing as not specifying the loadgraph.
You cannot force relationships to be lazy, but you can use EntityGraph to force loading of lazy relationships.
That said, it doesn't explain why your Test3->Test2 relationship is being triggered. I suggest modifying your method and logging something after the query has executed to make it more clear if the "SELECT id, test3 FROM TEST2 " statements are occurring on the query.getSingleResult() call or afterward. I suspect that some process after the query.getSingleResult() call is traversing the Test3 instance returned, such as parsing it into JSON, that is causing the relationship to be fetched.
Best Regards,
Chris
[Updated on: Fri, 09 October 2015 14:10] Report message to a moderator
|
|
|
Goto Forum:
Current Time: Mon Oct 07 09:11:32 GMT 2024
Powered by FUDForum. Page generated in 0.03347 seconds
|