Hi Steven,
To include selective fields of an embedded relation via @FetchGroup
annotation is bit complicated because when field names are parsed, the types
may not have been resolved.
For concreteness, assume the following domain entitiy definitions,
@Entity
public class Person {
@Id
private long id;
private String name;
@Embedded
private Address address;
}
@Embeddable
public class Address {
private String city;
private String zip;
}
And, say, we want to fetch the following fields when we fetch a Person
instance:
Person.address
Person.address.city
and we do not want to fetch
Person.name
Person.address.zip
A straightforward annotation specification in Person.java *should* have
been
@FetchGroup(name="Person.Address.CityOnly",
attributes={
@FetchAttribute(name="address"),
@FetchAttribute(name="address.city")
})
Unfortunately "address.city" fetch attribute specification dose not work.
Because when Person.java is being parsed, we can ascertain that "address" is
one of its field. But we can not ascertain that Address has a field named
"city" -- simply because we may not have parsed Address.java at that time.
So the alternative solution is to define the FetchGroup twice, with the
same moniker.
In Person.java
@FetchGroup(name="Person.Address.CityOnly",
attribute...@fetchattribute(name="address")})
And again in Address.java
@FetchGroup(name="Person.Address.CityOnly",
attribute...@fetchattribute(name="city")})
Now at runtime, one can do
OpenJPAEntityManager em = ...;
FetchPlan plan = em.getFetchPlan();
plan.addFetchGroup("Person.Address.CityOnly");
plan.removeFetchGroup(FetchPlan.GROUP_DEFAULT); // otherwise Person.name
will be fetched as part
//of the default group
Of course, it is not necessary to define the fetch groups with same
moniker. But then, at runtime, one has to add two fetch groups.
If the fetch plan is *dynamically* defined as in my previous post then that
problem does not arise.
StevenK wrote:
>
>>Sorry it's taken me so long to respond. I was out of the office for the
holidays. First, thanks for responding to my post. When I added the fields
to the group, I added the annotation on a class like this:
> @FetchGroup(name="myFetchGroup",
> attribute...@fetchattribute(name="fieldOne"),
> @FetchAttribute(name="embeddableFieldTwo"}). I didn't qualify the fields
> by naming them MyClass.fieldOne or MyEmbeddableClass.embeddableFieldTwo.
> Do you think that adding the class name to the field name this way would
> have been enough to make it work?
>
>
>
>
> Pinaki Poddar wrote:
>>
>>> We created a fetch plan that includes a couple of embedded fields and a
>>> couple of non-embedded fields.
>>
>> Can you post the exact definition of the plan? Th eplan needs to include
>> the individual fields of the embeddded type. For example, if Person has
>> reference to Address (which is Embeddable) then
>>
>> plan.addField(Person.class, "name");
>> plan.addField(Person.class, "address");
>> plan.addField(Address.class, "city");
>>
>> will fetch a Person whose address is poulated *only* with city.
>>
>> A SQL similar to following should be generated:
>> select t0.name, t0.city from Person t0
>>
>>
>> StevenK wrote:
>>>
>>> We created an entity that contained some embedded fields and some
>>> non-embedded fields (string, ints, etc). All fields are lazy loaded
>>> (the default). We created a fetch plan that includes a couple of
>>> embedded fields and a couple of non-embedded fields. We then created a
>>> query that uses the fetch plan.
>>>
>>> We created a test that added a number of these entities to the
>>> database. We then looped through all the entities that were returned by
>>> the query and accessed each field. We turned sql tracing on so we could
>>> see what sql was generated and executed. What we found was that when
>>> we accessed the non-embedded fields, no sql was executed (we expected
>>> this because these fields were included in the fetch plan). When we
>>> accessed the embedded fields sql was executed (selects for those fields)
>>> indicating that the fields were still being lazy loaded and the fetch
>>> plan was not eagerly loading the data. We did not expect this as these
>>> fields were also part of the fetch plan.
>>>
>>> Have you worked with fetch plans that combined embedded and non-embedded
>>> fields? Any idea what might be causing this?
>>>
>>> Thanks for your help.
>>>
>>> Pinaki Poddar wrote:
>>>>
>>>>> Are their any restrictions, constraints, or other complications that
>>>>> anyone is aware of?
>>>> Nothing specific comes to mind. Are you seeing any anomaly w.r.t.
>>>> embedded fields in a fetch plan?
>>>>
>>>>
>>>> StevenK wrote:
>>>>>
>>>>> I am trying to optomize a query by using fetch groups. One of the
>>>>> fields I'd like to include in the group is an embedded entity. When I
>>>>> turn sql tracing on, run my query, and then display the value of the
>>>>> fields that were returned, I can see that the non-embedded fields in
>>>>> my entry display without additional selects from the database - which
>>>>> is exactly what I expect. The embedded fields however generate a
>>>>> select to the database to get their contents - which I am trying to
>>>>> avoid by including those fields in the fetch group. Has anyone else
>>>>> worked with fetch groups and embedded fields? Are their any
>>>>> restrictions, constraints, or other complications that anyone is aware
>>>>> of?
>>>>>
>>>>> Thanks!
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>
-----
Pinaki
--
View this message in context:
http://n2.nabble.com/FetchGroups-and-Embeddable-Fields-tp4200062p4252184.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.