JPQL with a join fetch on a entity with a lazy fetch attribute. [message #1595923] |
Sun, 01 February 2015 09:06 |
dimi Mising name Messages: 1 Registered: February 2015 |
Junior Member |
|
|
There are two entity EntityA and EntityB
entity EntityA has a relation "parent" ManyToOne(fetch=LAZY) with EntityB, and EntityB has a Lob attribute "content" with fetch=LAZY.
If I execute a JPQL query like:
select a from EntityA a join fetch a.parent where ....
The query not olny fetch EntityB but also EntityB.content is fetched.
How can I do to "join fetch EntityB" but not his attribute content?
I'm using EclipseLink 2.5.2 with static weaving configured
Tanks
Dmitrij
Dimi
[Updated on: Fri, 06 February 2015 07:29] Report message to a moderator
|
|
|
Re: JPQL with a join fetch on a entity with a lazy fetch attribute. [message #1652632 is a reply to message #1595923] |
Thu, 05 March 2015 23:59 |
Will Dazey Messages: 10 Registered: February 2015 |
Junior Member |
|
|
Hello, thx for the post.
I tried a simple example of what I believe you are describing and it looks like it may be a bug in EclipseLink. EntityB and the @Lob appear to be loading with the querying of EntityA. If you remove the join-fetch hint, EntityA does load without EntityB as expected and a further accessing of EntityA.getParent() loads EntityB but does NOT load the @Lob, also as I would expect and is consistent with an em.find(). I hope ppl were able to follow that .
The following example generates this output:
[EL Finest]: query: --UnitOfWork(1523955742)--Thread(Thread[main,5,main])--Execute query ReadObjectQuery(referenceClass=EntityA sql="SELECT t1.EntA_ID, t1.PARENT_ID, t0.EntB_ID, t0.CONTENT FROM ENTITYB t0, ENTITYA t1 WHERE ((t1.EntA_ID = ?) AND (t0.EntB_ID = t1.PARENT_ID))")
[EL Finest]: connection: --ServerSession(1748233233)--Connection(875238181)--Thread(Thread[main,5,main])--Connection acquired from connection pool [default].
[EL Fine]: sql: --ServerSession(1748233233)--Connection(875238181)--Thread(Thread[main,5,main])--SELECT t1.EntA_ID, t1.PARENT_ID, t0.EntB_ID, t0.CONTENT FROM ENTITYB t0, ENTITYA t1 WHERE ((t1.EntA_ID = ?) AND (t0.EntB_ID = t1.PARENT_ID))
bind => [2]
[EL Finest]: connection: --ServerSession(1748233233)--Connection(875238181)--Thread(Thread[main,5,main])--Connection released to connection pool [default].
[EL Finer]: cache: --UnitOfWork(1523955742)--Thread(Thread[main,5,main])--initialize identitymaps
[EL Finer]: cache: --ClientSession(-69654959)--Thread(Thread[main,5,main])--initialize identitymaps
[EL Finer]: transaction: --UnitOfWork(1523955742)--Thread(Thread[main,5,main])--release unit of work
[EL Finer]: connection: --ClientSession(-69654959)--Thread(Thread[main,5,main])--client released
EntityB isloaded: true
EntityB.content isloaded: true
Entities:
@Entity
public class EntityA implements Serializable{
private static final long serialVersionUID = 1L;
@Id @GeneratedValue @Column(name="EntA_ID")
private int id;
@ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)
@JoinColumn(name="PARENT_ID", referencedColumnName = "EntB_ID")
private EntityB parent;
}
@Entity
public class EntityB implements Serializable{
private static final long serialVersionUID = 1L;
@Id @GeneratedValue @Column(name="EntB_ID")
private int id;
@Lob @Basic(fetch=FetchType.LAZY)
private String content;
}
Test:
@Test
public void testGenericTest() throws Exception {
EntityManager em = emf.createEntityManager();
EntityB parent = new EntityB();
parent.setContent("CONTENT HERE!");
EntityA entA = new EntityA();
entA.setParent(parent);
em.getTransaction().begin();
em.persist(entA);
em.getTransaction().commit();
em.clear();
Query query = em.createQuery("select a from EntityA a join fetch a.parent where a.id = ?1");
query.setParameter(1, entA.getId());
EntityA ent = (EntityA) query.getSingleResult();
em.clear();
PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
System.out.println("EntityB isloaded: " + util.isLoaded(ent, "parent"));
EntityB entb = ent.getParent();
System.out.println("EntityB.content isloaded: " + util.isLoaded(entb, "content"));
em.close();
}
However, if the @Lob was wrapped in another Entity with a @OnetoOne relation to EntityB, then you may be able to work around the problem, as the @Lob will not load until you access EntityB.content. Of course this is a possible work around and I suggest opening a bug for this if you would like some attention.
@Entity
public class EntityB implements Serializable{
private static final long serialVersionUID = 1L;
@Id @GeneratedValue @Column(name="EntB_ID")
private int id;
@OneToOne(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)
private EntityC content;
}
@Entity
public class EntityC implements Serializable{
private static final long serialVersionUID = -4230225817490725483L;
@Id @GeneratedValue
private int id;
@Lob
private String value;
}
|
|
|
|
Powered by
FUDForum. Page generated in 0.02297 seconds