You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Jim Talbut <jt...@spudsoft.co.uk> on 2013/12/06 20:10:40 UTC
A FIQL question
Hi,
I have a JPA entity model that has the following chain of relationships:
Order_JpaImpl {
@OneToMany(mappedBy = "order", fetch = FetchType.EAGER, cascade =
{CascadeType.ALL})
List< OrderLine_JpaImpl> orderLines = new LinkedList<>();
}
OrderLine_JpaImpl {
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "prdId", nullable = false)
@ForeignKey
@Index
private Product_JpaImpl orderLineItem;
}
Product_JpaImpl {
@ManyToOne( cascade = {}, targetEntity = Show_JpaImpl.class, fetch
= FetchType.EAGER )
@JoinColumn( name="shwId", nullable = false )
@ForeignKey
@Index
private Show_JpaImpl show;
}
Show_JpaImpl {
@Column( length = 32, unique = true, nullable = false )
private String shortName;
}
I want to use FIQL to get all the orders that include orderlines that
have products from a given show.
So I have a simple search expression: show==AMND
And a mapping:
private static Map<String,String> createBeanNameMap() {
Map<String,String> map = new HashMap<>();
map.put("customerdisplay","customerDisplay");
map.put("ordertime","orderTime");
map.put("fulfilmentstatus","fulfilmentStatus");
map.put("show","orderLines.orderLineItem.show.shortName");
return map;
}
That is used by:
SearchCondition<ImplType> searchCondition =
searchContext.getCondition(targetClass, getBeanNameMap());
And that always returns null :(
I think what I'm trying to achieve is equivalent to the "all the books
with good reviews written by Ted" example at
http://cxf.apache.org/docs/jax-rs-search.html, but I'm getting an error
inside the parser when it finds that orderLines is a List.
So my question is, should this work?
Is it supposed to be possible to go via a one-to-many join and return
parents with a child that matches?
I'm using CXF 2.7.7.
Thanks.
Jim
Re: A FIQL question
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi,
On 11/12/13 15:54, Jim Talbut wrote:
> Hi Sergey,
>
> I've been using OpenJPA, but I don't mind it not working with interfaces
> as long as it is documented.
> Anyone using interfaces can do what I did, which is to have:
> public interface OrderLine
> {
> Product getOrderLineItem();
> void setOrderLineItem( Product orderLineItem );
> }
>
> @Entity
> public class OrderLine_JpaImpl implements OrderLine, Serializable {
>
> @ManyToOne(fetch = FetchType.EAGER)
> @JoinColumn(name = "prdId", nullable = false)
> @ForeignKey
> @Index
> private Product_JpaImpl orderLineItem;
>
> @Override
> public Product_JpaImpl getOrderLineItem() {
> return orderLineItem;
> }
>
> @Override
> public void setOrderLineItem(Product orderLineItem) {
> setOrderLineItem((Product_JpaImpl)orderLineItem);
> }
>
> public void setOrderLineItem(Product_JpaImpl orderLineItem) {
> this.orderLineItem = orderLineItem;
> }
>
> }
>
> I didn't know that Java permitted a sub class to return a sub class from
> an override (i.e. the way getOrderLineItem is considered an override
> despite returning a more specific type).
> This way the getter always returns the Entity type, and we have a hidden
> setter that accepts the correct type.
>
> I reckon that having your generic code be unable to know that it can use
> setOrderLineItem(Product orderLineItem) is a reasonable limitation.
>
> I think the problem I'm left with is caused by trying to specify
> properties of a child of a list, rather than being related to the
> interfaces.
>
Thanks for the info above, I haven't setup a JPA2 test, but I did a
trivial fix to get interface properties supported as it may be needed
even without JPA2. Please test it after we get CXF-5449 done
Cheers, Sergey
> Jim
>
>
>
> On 11/12/2013 13:14, Sergey Beryozkin wrote:
>> Hi Jim
>> Thanks; by the way I can't setup a test where an entity returns an
>> interface. Apparently not all JPA2 implementations support it.
>> We can do a basic interface proxy to get a template working with
>> interfaces, but I will need some help with configuring persistence.xml
>> and adding a test dependency to pom.xml,
>>
>> so, can you do it please, update persistence.xml in
>> rt/rs/extensions/search and pom.xml and send the diff to me or open a
>> JIRA (Support for testing another JPA2 implementation) ?
>>
>> Thanks, Sergey
>>
>> On 09/12/13 20:40, Jim Talbut wrote:
>>> On 09/12/2013 13:28, Sergey Beryozkin wrote:
>>>> org.apache.cxf.jaxrs.ext.search.jpa.JPATypedVisitorTest has few tests
>>>> where collections of primitive and complex types are used.
>>>>
>>>> Can you please open a JIRA and prototype the way the beans are
>>>> linked to
>>>> each other (please narrow it down to the faulty path only), somehow the
>>>> parser has got confused, needs to be fixed
>>>>
>>>> Thanks, Sergey
>>>
>>> Thanks Sergey.
>>> Created https://issues.apache.org/jira/browse/CXF-5449, mainly as a copy
>>> of this email.
>>> I /think/ the failure occurs when you have:
>>> 1. A parent entity containing a list of children.
>>> 2. The children entities contain a single grandchild.
>>> 3. The search is for a property of the grandchild.
>>> And it fails when it tries to set the grandchild in the child.
>>>
>>> I've actually got another layer in the hierarchy (great-grandchild), but
>>> given where the exception comes from I suspect that isn't needed to
>>> cause the failure.
>>>
>>> Jim
>>>
>>>
>>
>>
>
Re: A FIQL question
Posted by Jim Talbut <jt...@spudsoft.co.uk>.
Hi Sergey,
I've been using OpenJPA, but I don't mind it not working with interfaces
as long as it is documented.
Anyone using interfaces can do what I did, which is to have:
public interface OrderLine
{
Product getOrderLineItem();
void setOrderLineItem( Product orderLineItem );
}
@Entity
public class OrderLine_JpaImpl implements OrderLine, Serializable {
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "prdId", nullable = false)
@ForeignKey
@Index
private Product_JpaImpl orderLineItem;
@Override
public Product_JpaImpl getOrderLineItem() {
return orderLineItem;
}
@Override
public void setOrderLineItem(Product orderLineItem) {
setOrderLineItem((Product_JpaImpl)orderLineItem);
}
public void setOrderLineItem(Product_JpaImpl orderLineItem) {
this.orderLineItem = orderLineItem;
}
}
I didn't know that Java permitted a sub class to return a sub class from
an override (i.e. the way getOrderLineItem is considered an override
despite returning a more specific type).
This way the getter always returns the Entity type, and we have a hidden
setter that accepts the correct type.
I reckon that having your generic code be unable to know that it can use
setOrderLineItem(Product orderLineItem) is a reasonable limitation.
I think the problem I'm left with is caused by trying to specify
properties of a child of a list, rather than being related to the
interfaces.
Jim
On 11/12/2013 13:14, Sergey Beryozkin wrote:
> Hi Jim
> Thanks; by the way I can't setup a test where an entity returns an
> interface. Apparently not all JPA2 implementations support it.
> We can do a basic interface proxy to get a template working with
> interfaces, but I will need some help with configuring persistence.xml
> and adding a test dependency to pom.xml,
>
> so, can you do it please, update persistence.xml in
> rt/rs/extensions/search and pom.xml and send the diff to me or open a
> JIRA (Support for testing another JPA2 implementation) ?
>
> Thanks, Sergey
>
> On 09/12/13 20:40, Jim Talbut wrote:
>> On 09/12/2013 13:28, Sergey Beryozkin wrote:
>>> org.apache.cxf.jaxrs.ext.search.jpa.JPATypedVisitorTest has few tests
>>> where collections of primitive and complex types are used.
>>>
>>> Can you please open a JIRA and prototype the way the beans are linked to
>>> each other (please narrow it down to the faulty path only), somehow the
>>> parser has got confused, needs to be fixed
>>>
>>> Thanks, Sergey
>>
>> Thanks Sergey.
>> Created https://issues.apache.org/jira/browse/CXF-5449, mainly as a copy
>> of this email.
>> I /think/ the failure occurs when you have:
>> 1. A parent entity containing a list of children.
>> 2. The children entities contain a single grandchild.
>> 3. The search is for a property of the grandchild.
>> And it fails when it tries to set the grandchild in the child.
>>
>> I've actually got another layer in the hierarchy (great-grandchild), but
>> given where the exception comes from I suspect that isn't needed to
>> cause the failure.
>>
>> Jim
>>
>>
>
>
Re: A FIQL question
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Jim
Thanks; by the way I can't setup a test where an entity returns an
interface. Apparently not all JPA2 implementations support it.
We can do a basic interface proxy to get a template working with
interfaces, but I will need some help with configuring persistence.xml
and adding a test dependency to pom.xml,
so, can you do it please, update persistence.xml in
rt/rs/extensions/search and pom.xml and send the diff to me or open a
JIRA (Support for testing another JPA2 implementation) ?
Thanks, Sergey
On 09/12/13 20:40, Jim Talbut wrote:
> On 09/12/2013 13:28, Sergey Beryozkin wrote:
>> org.apache.cxf.jaxrs.ext.search.jpa.JPATypedVisitorTest has few tests
>> where collections of primitive and complex types are used.
>>
>> Can you please open a JIRA and prototype the way the beans are linked to
>> each other (please narrow it down to the faulty path only), somehow the
>> parser has got confused, needs to be fixed
>>
>> Thanks, Sergey
>
> Thanks Sergey.
> Created https://issues.apache.org/jira/browse/CXF-5449, mainly as a copy
> of this email.
> I /think/ the failure occurs when you have:
> 1. A parent entity containing a list of children.
> 2. The children entities contain a single grandchild.
> 3. The search is for a property of the grandchild.
> And it fails when it tries to set the grandchild in the child.
>
> I've actually got another layer in the hierarchy (great-grandchild), but
> given where the exception comes from I suspect that isn't needed to
> cause the failure.
>
> Jim
>
>
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com
Re: A FIQL question
Posted by Jim Talbut <jt...@spudsoft.co.uk>.
On 09/12/2013 13:28, Sergey Beryozkin wrote:
> org.apache.cxf.jaxrs.ext.search.jpa.JPATypedVisitorTest has few tests
> where collections of primitive and complex types are used.
>
> Can you please open a JIRA and prototype the way the beans are linked to
> each other (please narrow it down to the faulty path only), somehow the
> parser has got confused, needs to be fixed
>
> Thanks, Sergey
Thanks Sergey.
Created https://issues.apache.org/jira/browse/CXF-5449, mainly as a copy
of this email.
I /think/ the failure occurs when you have:
1. A parent entity containing a list of children.
2. The children entities contain a single grandchild.
3. The search is for a property of the grandchild.
And it fails when it tries to set the grandchild in the child.
I've actually got another layer in the hierarchy (great-grandchild), but
given where the exception comes from I suspect that isn't needed to
cause the failure.
Jim
Re: A FIQL question
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi
On 07/12/13 12:19, Jim Talbut wrote:
> I think I've taken this as far as it will go.
> By changing all the getters to return implementation classes rather than
> interfaces, and then adding non-interface setters that take
> implementation classes I am able to get a lot further, but then I hit this:
>
> Caused by: java.lang.IllegalArgumentException: argument type mismatch;
> setter parameter type: java.util.List, set value type:
> uk.co.spudsoft.spiderweborders.model.jpaimpl.OrderLine_JpaImpl
> at
> org.apache.cxf.jaxrs.ext.search.Beanspector.setValue(Beanspector.java:152)
> ~[cxf-rt-rs-extension-search-2.7.8.jar:2.7.8]
> at
> org.apache.cxf.jaxrs.ext.search.Beanspector.setValue(Beanspector.java:131)
> ~[cxf-rt-rs-extension-search-2.7.8.jar:2.7.8]
> at
> org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser$Comparison.createTemplate(FiqlParser.java:600)
> ~[cxf-rt-rs-extension-search-2.7.8.jar:2.7.8]
>
>
> OrderLines is a list of OrderLine objects, but the template is being
> created with just one and the setter doesn't know how to handle lists.
> I tried adding a setter that takes a single OrderLine, but something got
> upset when it saw that the getter and setter were of different types.
>
> Unless there is special handling for lists of strings (or primitives) I
> can't see how the example can work either.
>
org.apache.cxf.jaxrs.ext.search.jpa.JPATypedVisitorTest has few tests
where collections of primitive and complex types are used.
Can you please open a JIRA and prototype the way the beans are linked to
each other (please narrow it down to the faulty path only), somehow the
parser has got confused, needs to be fixed
Thanks, Sergey
> Jim
>
> On 07/12/2013 07:59, Jim Talbut wrote:
>> Hmm, I think I've made some progress.
>> The problem seems to be caused by this:
>>
>> Order_JpaImpl {
>> @Override
>> public List<? extends OrderLine> getOrderLines() {
>> return orderLines;
>> }
>> }
>>
>> Everything public is an interface, and the reflection in the FiqlParser
>> is just using the method signatures.
>> Which ends up with it trying to instantiate an interface.
>>
>> Not sure if there is a way around this.
>> One possibility is adding a method that returns the actual datatype, but
>> that isn't visible on the interface.
>> Given that the map from external name ('show') is hidden the method that
>> it uses doesn't actually have to be visible.
>>
>> Jim
>>
>> On 06/12/2013 19:10, Jim Talbut wrote:
>>> Hi,
>>>
>>> I have a JPA entity model that has the following chain of relationships:
>>>
>>> Order_JpaImpl {
>>> @OneToMany(mappedBy = "order", fetch = FetchType.EAGER, cascade =
>>> {CascadeType.ALL})
>>> List< OrderLine_JpaImpl> orderLines = new LinkedList<>();
>>> }
>>>
>>> OrderLine_JpaImpl {
>>> @ManyToOne(fetch = FetchType.EAGER)
>>> @JoinColumn(name = "prdId", nullable = false)
>>> @ForeignKey
>>> @Index
>>> private Product_JpaImpl orderLineItem;
>>> }
>>>
>>> Product_JpaImpl {
>>> @ManyToOne( cascade = {}, targetEntity = Show_JpaImpl.class, fetch
>>> = FetchType.EAGER )
>>> @JoinColumn( name="shwId", nullable = false )
>>> @ForeignKey
>>> @Index
>>> private Show_JpaImpl show;
>>> }
>>>
>>> Show_JpaImpl {
>>> @Column( length = 32, unique = true, nullable = false )
>>> private String shortName;
>>> }
>>>
>>> I want to use FIQL to get all the orders that include orderlines that
>>> have products from a given show.
>>> So I have a simple search expression: show==AMND
>>> And a mapping:
>>> private static Map<String,String> createBeanNameMap() {
>>> Map<String,String> map = new HashMap<>();
>>> map.put("customerdisplay","customerDisplay");
>>> map.put("ordertime","orderTime");
>>> map.put("fulfilmentstatus","fulfilmentStatus");
>>> map.put("show","orderLines.orderLineItem.show.shortName");
>>> return map;
>>> }
>>> That is used by:
>>> SearchCondition<ImplType> searchCondition =
>>> searchContext.getCondition(targetClass, getBeanNameMap());
>>>
>>> And that always returns null :(
>>>
>>> I think what I'm trying to achieve is equivalent to the "all the books
>>> with good reviews written by Ted" example at
>>> http://cxf.apache.org/docs/jax-rs-search.html, but I'm getting an error
>>> inside the parser when it finds that orderLines is a List.
>>>
>>> So my question is, should this work?
>>> Is it supposed to be possible to go via a one-to-many join and return
>>> parents with a child that matches?
>>>
>>> I'm using CXF 2.7.7.
>>>
>>> Thanks.
>>>
>>> Jim
>>
>
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com
Re: A FIQL question
Posted by Jim Talbut <jt...@spudsoft.co.uk>.
I think I've taken this as far as it will go.
By changing all the getters to return implementation classes rather than
interfaces, and then adding non-interface setters that take
implementation classes I am able to get a lot further, but then I hit this:
Caused by: java.lang.IllegalArgumentException: argument type mismatch;
setter parameter type: java.util.List, set value type:
uk.co.spudsoft.spiderweborders.model.jpaimpl.OrderLine_JpaImpl
at
org.apache.cxf.jaxrs.ext.search.Beanspector.setValue(Beanspector.java:152)
~[cxf-rt-rs-extension-search-2.7.8.jar:2.7.8]
at
org.apache.cxf.jaxrs.ext.search.Beanspector.setValue(Beanspector.java:131)
~[cxf-rt-rs-extension-search-2.7.8.jar:2.7.8]
at
org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser$Comparison.createTemplate(FiqlParser.java:600)
~[cxf-rt-rs-extension-search-2.7.8.jar:2.7.8]
OrderLines is a list of OrderLine objects, but the template is being
created with just one and the setter doesn't know how to handle lists.
I tried adding a setter that takes a single OrderLine, but something got
upset when it saw that the getter and setter were of different types.
Unless there is special handling for lists of strings (or primitives) I
can't see how the example can work either.
Jim
On 07/12/2013 07:59, Jim Talbut wrote:
> Hmm, I think I've made some progress.
> The problem seems to be caused by this:
>
> Order_JpaImpl {
> @Override
> public List<? extends OrderLine> getOrderLines() {
> return orderLines;
> }
> }
>
> Everything public is an interface, and the reflection in the FiqlParser
> is just using the method signatures.
> Which ends up with it trying to instantiate an interface.
>
> Not sure if there is a way around this.
> One possibility is adding a method that returns the actual datatype, but
> that isn't visible on the interface.
> Given that the map from external name ('show') is hidden the method that
> it uses doesn't actually have to be visible.
>
> Jim
>
> On 06/12/2013 19:10, Jim Talbut wrote:
>> Hi,
>>
>> I have a JPA entity model that has the following chain of relationships:
>>
>> Order_JpaImpl {
>> @OneToMany(mappedBy = "order", fetch = FetchType.EAGER, cascade =
>> {CascadeType.ALL})
>> List< OrderLine_JpaImpl> orderLines = new LinkedList<>();
>> }
>>
>> OrderLine_JpaImpl {
>> @ManyToOne(fetch = FetchType.EAGER)
>> @JoinColumn(name = "prdId", nullable = false)
>> @ForeignKey
>> @Index
>> private Product_JpaImpl orderLineItem;
>> }
>>
>> Product_JpaImpl {
>> @ManyToOne( cascade = {}, targetEntity = Show_JpaImpl.class, fetch
>> = FetchType.EAGER )
>> @JoinColumn( name="shwId", nullable = false )
>> @ForeignKey
>> @Index
>> private Show_JpaImpl show;
>> }
>>
>> Show_JpaImpl {
>> @Column( length = 32, unique = true, nullable = false )
>> private String shortName;
>> }
>>
>> I want to use FIQL to get all the orders that include orderlines that
>> have products from a given show.
>> So I have a simple search expression: show==AMND
>> And a mapping:
>> private static Map<String,String> createBeanNameMap() {
>> Map<String,String> map = new HashMap<>();
>> map.put("customerdisplay","customerDisplay");
>> map.put("ordertime","orderTime");
>> map.put("fulfilmentstatus","fulfilmentStatus");
>> map.put("show","orderLines.orderLineItem.show.shortName");
>> return map;
>> }
>> That is used by:
>> SearchCondition<ImplType> searchCondition =
>> searchContext.getCondition(targetClass, getBeanNameMap());
>>
>> And that always returns null :(
>>
>> I think what I'm trying to achieve is equivalent to the "all the books
>> with good reviews written by Ted" example at
>> http://cxf.apache.org/docs/jax-rs-search.html, but I'm getting an error
>> inside the parser when it finds that orderLines is a List.
>>
>> So my question is, should this work?
>> Is it supposed to be possible to go via a one-to-many join and return
>> parents with a child that matches?
>>
>> I'm using CXF 2.7.7.
>>
>> Thanks.
>>
>> Jim
>
Re: A FIQL question
Posted by Jim Talbut <jt...@spudsoft.co.uk>.
Hmm, I think I've made some progress.
The problem seems to be caused by this:
Order_JpaImpl {
@Override
public List<? extends OrderLine> getOrderLines() {
return orderLines;
}
}
Everything public is an interface, and the reflection in the FiqlParser
is just using the method signatures.
Which ends up with it trying to instantiate an interface.
Not sure if there is a way around this.
One possibility is adding a method that returns the actual datatype, but
that isn't visible on the interface.
Given that the map from external name ('show') is hidden the method that
it uses doesn't actually have to be visible.
Jim
On 06/12/2013 19:10, Jim Talbut wrote:
> Hi,
>
> I have a JPA entity model that has the following chain of relationships:
>
> Order_JpaImpl {
> @OneToMany(mappedBy = "order", fetch = FetchType.EAGER, cascade =
> {CascadeType.ALL})
> List< OrderLine_JpaImpl> orderLines = new LinkedList<>();
> }
>
> OrderLine_JpaImpl {
> @ManyToOne(fetch = FetchType.EAGER)
> @JoinColumn(name = "prdId", nullable = false)
> @ForeignKey
> @Index
> private Product_JpaImpl orderLineItem;
> }
>
> Product_JpaImpl {
> @ManyToOne( cascade = {}, targetEntity = Show_JpaImpl.class, fetch
> = FetchType.EAGER )
> @JoinColumn( name="shwId", nullable = false )
> @ForeignKey
> @Index
> private Show_JpaImpl show;
> }
>
> Show_JpaImpl {
> @Column( length = 32, unique = true, nullable = false )
> private String shortName;
> }
>
> I want to use FIQL to get all the orders that include orderlines that
> have products from a given show.
> So I have a simple search expression: show==AMND
> And a mapping:
> private static Map<String,String> createBeanNameMap() {
> Map<String,String> map = new HashMap<>();
> map.put("customerdisplay","customerDisplay");
> map.put("ordertime","orderTime");
> map.put("fulfilmentstatus","fulfilmentStatus");
> map.put("show","orderLines.orderLineItem.show.shortName");
> return map;
> }
> That is used by:
> SearchCondition<ImplType> searchCondition =
> searchContext.getCondition(targetClass, getBeanNameMap());
>
> And that always returns null :(
>
> I think what I'm trying to achieve is equivalent to the "all the books
> with good reviews written by Ted" example at
> http://cxf.apache.org/docs/jax-rs-search.html, but I'm getting an error
> inside the parser when it finds that orderLines is a List.
>
> So my question is, should this work?
> Is it supposed to be possible to go via a one-to-many join and return
> parents with a child that matches?
>
> I'm using CXF 2.7.7.
>
> Thanks.
>
> Jim