You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Michael Vorburger <mv...@odyssey-group.com> on 2008/11/14 18:29:43 UTC
Get @Id field value (FK) without loading entity (JOIN) when using FetchGroups or Lazy Loading
Hello,
Imagine a dom. model like class A { @Id long id; String name; @Lazy B b;
}; class B { @Id String code; /* ... other attributes ... */ }.
When doing a Query on A with a FetchGroup that excludes the A's b field,
or simply through a @Lazy annotation, OpenJPA stills always loads the FK
(c.f.
http://openjpa.apache.org/builds/1.2.0/apache-openjpa-1.2.0/docs/manual/
ref_guide_fetch.html#ref_guide_fetch_impl
<http://openjpa.apache.org/builds/1.2.0/apache-openjpa-1.2.0/docs/manual
/ref_guide_fetch.html#ref_guide_fetch_impl> , "Even when a direct
relation is not eagerly fetched, OpenJPA selects the foreign key columns
and caches the values."), so the 'code' of B that is in the A table.
That's good.
Question: How do you now actually access/get the value of that b's code,
the String? OpenJPA has it, in memory, but when you hold an instance a
of A, the instant you do a.getB().getCode(), of course it will lazy load
the full B - because it has no way of knowing that after the getB()
you'll do only a getCode() ... ;-) I trust this has been considered and
thought of, and there is a solution... how???
I feel like I'm looking for "the opposite the
EntityManager.getReference() method", if that makes any sense? Is the
OpenJPAEntityManager's Object getObjectId(Object o) the rescue here...
but how exactly? A String bCode = oem.getObjectId(a.getB()) will most
likely still lead to a lazy DB load, right? Is there any chance
something like this: class A { ... @Lazy B b; B getB() { return this.b;
} String getBCodeId() { return HOWTOGETTHEEM.getObjectId(b); } } - will
work? Or will simply passing the b field to getObjectId also lead to a
lazy load? If that's feasible, how to get an EM inside the getter?
Much appreciate any ideas!
Regards,
Michael
____________________________________________________________
� This email and any files transmitted with it are CONFIDENTIAL and intended
solely for the use of the individual or entity to which they are addressed.
� Any unauthorized copying, disclosure, or distribution of the material within
this email is strictly forbidden.
� Any views or opinions presented within this e-mail are solely those of the
author and do not necessarily represent those of Odyssey Financial
Technologies SA unless otherwise specifically stated.
� An electronic message is not binding on its sender. Any message referring to
a binding engagement must be confirmed in writing and duly signed.
� If you have received this email in error, please notify the sender immediately
and delete the original.
Re: Get @Id field value (FK) without loading entity (JOIN) when
using FetchGroups or Lazy Loading
Posted by Pinaki Poddar <pp...@apache.org>.
Hi Michael,
Did you try with appropriately tuned fetch group to get the effect you
want? For example, consider a fetch group f that includes {A.id, A.name,
B.code} ?
--
View this message in context: http://n2.nabble.com/Get-%40Id-field-value-%28FK%29-without-loading-entity-%28JOIN%29-when-using-FetchGroups-or-Lazy-Loading-tp1499463p1504083.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.
Re: Get @Id field value (FK) without loading entity (JOIN) when
using FetchGroups or Lazy Loading
Posted by Yann Andenmatten <YA...@odyssey-group.com>.
Hi Pinaki,
Thanks for your answer, it is a way to solve our issue. I've still a
question: will the OpenJPAStateManager access still work properly on
detached object in every case?
Pinaki Poddar wrote:
>
> The short answer is you need to get hold of OpenJPAStateManager for A --
> the proxy object that intercepts and manages the persistent state of
> original A. That StateManager has the primary key of B which saves OpenJPA
> another join in case the user later calls A.getB().
>
However, your proposal has the inconvenient of using OpenJPA internals
(which are more subject to change than standard JPA api). In the
meanwhile I was wandering if a solution like mapping the column twice
could work:
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@Column(name = "dsit_one_bref_id")
private dsimpltest.BRealClassEntity oneBRef;
@Column(name = "dsit_one_bref_id", insertable=false, updatable=false)
private String oneBRefKeyAtt;
Obviously, this will work in reading data. Maintaining the second
attribute in synch with the first attribute will need
@PostUpdate/@PostPersist interceptors and some logic in the setter of
oneBRef.
Anyway, can you tell me if it is a bad idea?
Hi Craig,
In our case we instruct the fetch plan not to get the FB objects as we
only need to know its primary key. Doing this save us from a JOIN during
the query. Unfortunately, when accessing the data, the objects are
detached and getting FB leads us to a FB null. So from here it is not
possible to get the id (but we can get it using the Pinaki's solution)
Yann
--
View this message in context: http://n2.nabble.com/Get-%40Id-field-value-%28FK%29-without-loading-entity-%28JOIN%29-when-using-FetchGroups-or-Lazy-Loading-tp1499463p1581096.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.
Re: Get @Id field value (FK) without loading entity (JOIN) when using
FetchGroups or Lazy Loading
Posted by Craig L Russell <Cr...@Sun.COM>.
Ideally, simply navigating to a related field and getting the id of
that field should not trigger loading behavior, should it?
After all, you don't know exactly what fields to load until the user
actually wants a field that isn't loaded. The field that triggers the
database operation should influence what kind of fetch is done by the
database. It sounds like this behavior should work: for non-relation
fields, the current fetch plan is applied to the field’s owning
instance, and the fields in the field’s load-fetch-group, plus the
field itself are added to the list of fields.
Craig
On Nov 24, 2008, at 3:53 PM, Pinaki Poddar wrote:
>
> Hi,
> Sorry for delayed response.
>
> Let me restate the problem to see if I understand it correctly
> 1. Entity A has a one-to-one, lazily fetched relation to Entity B.
> public class A {
> @OneToOne(fetch=LAZY)
> private B b;
>
> 2. You want to get an instance of A in memory, but not the related
> instance of B. Nor you want a join between Table for A and Table for
> B.
>
> 3. But you should be able to access the primary field of B because
> OpenJPA
> has fetched the value but hidden it somewhere.
>
> I have attached a sketch of how this can be done in three attached
> file,
> hopefully they are self-explanatory :)
>
> http://n2.nabble.com/file/n1574366/TestFetch2.java TestFetch2.java
> http://n2.nabble.com/file/n1574366/FA.java FA.java
> http://n2.nabble.com/file/n1574366/FB.java FB.java
>
> The short answer is you need to get hold of OpenJPAStateManager for
> A --
> the proxy object that intercepts and manages the persistent state of
> original A. That StateManager has the primary key of B which saves
> OpenJPA
> another join in case the user later calls A.getB().
>
>
>
>
>
>
>
> --
> View this message in context: http://n2.nabble.com/Get-%40Id-field-value-%28FK%29-without-loading-entity-%28JOIN%29-when-using-FetchGroups-or-Lazy-Loading-tp1499463p1574366.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>
Craig L Russell
Architect, Sun Java Enterprise System http://db.apache.org/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!
RE: Get @Id field value (FK) without loading entity (JOIN) when
using FetchGroups or Lazy Loading
Posted by Pinaki Poddar <pp...@apache.org>.
Hi,
Sorry for delayed response.
Let me restate the problem to see if I understand it correctly
1. Entity A has a one-to-one, lazily fetched relation to Entity B.
public class A {
@OneToOne(fetch=LAZY)
private B b;
2. You want to get an instance of A in memory, but not the related
instance of B. Nor you want a join between Table for A and Table for B.
3. But you should be able to access the primary field of B because OpenJPA
has fetched the value but hidden it somewhere.
I have attached a sketch of how this can be done in three attached file,
hopefully they are self-explanatory :)
http://n2.nabble.com/file/n1574366/TestFetch2.java TestFetch2.java
http://n2.nabble.com/file/n1574366/FA.java FA.java
http://n2.nabble.com/file/n1574366/FB.java FB.java
The short answer is you need to get hold of OpenJPAStateManager for A --
the proxy object that intercepts and manages the persistent state of
original A. That StateManager has the primary key of B which saves OpenJPA
another join in case the user later calls A.getB().
--
View this message in context: http://n2.nabble.com/Get-%40Id-field-value-%28FK%29-without-loading-entity-%28JOIN%29-when-using-FetchGroups-or-Lazy-Loading-tp1499463p1574366.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.