Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Cant get NamedEntityGraph to work....(NamedEntityGraph)
Cant get NamedEntityGraph to work.... [message #1710510] Wed, 07 October 2015 08:46 Go to next message
Asaf Natan is currently offline Asaf NatanFriend
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 Go to previous message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1380
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

Previous Topic:Validation Exception on compound key
Next Topic:EclipseLink not working with Latest MongoDB
Goto Forum:
  


Current Time: Sat Mar 06 15:11:11 GMT 2021

Powered by FUDForum. Page generated in 0.02286 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top