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/10/21 08:21:13 UTC
Correct way to use a JPA*QueryVisitor with a filter class that is
not a JPA entity
Hi,
I have a JPA data model that I'm trying to use with CXF's SearchContext.
In order to constrain the searching that can be done I'm trying to use a
search class that is not a JPA entity (and that just contains a subset
of the JPA fields).
Q1. Is this the right way to solve this problem?
Q2. How should I get it to work?
Details:
I have a "User" interface that the "User_JpaImpl" entity class derives from.
I also have a "UserFilter" class that just has two properties (username
& enabled) - the User interface also has getters and setters for these
properties, but there is no relationship between UserFilter and User (or
User_JpaImpl).
My best attempt so far looks like this:
SearchCondition<UserFilter> sc =
searchContext.getCondition(UserFilter.class);
JPACriteriaQueryVisitor<UserFilter, User_JpaImpl> visitor =
new JPACriteriaQueryVisitor<>(entityManager,
UserFilter.class, User_JpaImpl.class);
searchCondition.accept(visitor);
TypedQuery<User_JpaImpl> query = visitor.getTypedQuery();
List<? extends User> result = query.getResultList();
This throws an exception in accept because of this:
if (builder == null) {
builder = em.getCriteriaBuilder();
cq = builder.createQuery(queryClass);
root = cq.from(tClass);
predStack.push(new ArrayList<Predicate>());
}
tClass is UserFilter.class, which is not known to JPA and thus cannot be
used as root (cq.from(tClass) throws IllegalArgumentException).
All I want to do is limit the set of fields that can be queried, if this
is the wrong approach I'm happy to swap it for another.
Thanks.
Jim
Re: Correct way to use a JPA*QueryVisitor with a filter class that
is not a JPA entity
Posted by Sergey Beryozkin <sb...@gmail.com>.
The exception is now propagated by default, in CXF 2.7.8 it will be
possible to get it propagated by setting a
"search.block.search.extension" to false
Sergey
On 21/10/13 21:07, Jim Talbut wrote:
> On 21/10/2013 10:18, Sergey Beryozkin wrote:
>> I believe the JPA2 way is to use either JPA2 Tuple or capturing
>> beans/arrays which will filter the 'username' & 'enabled' properties
>> at JPA/DB level, the JPA2 section has a couple of examples and
>> JPATypedQueryVisitorTest has few more (to do with different styles of
>> shaping the output), I'd probably go for using Tuple.
>>
>> If you prefer to use a custom UserFilter then I guess you'd need to use
>> JPATypedQueryVisitor<User_JpaImpl> and then filter the result list
>> with the filter afterwards
>
> Thanks, I think I'm going to go with using another visitor just to do my
> validation, and then use the simple TypedQuery - any other approach
> seems to create more complexity (for my scenario) than it's worth.
>
> Is there a reason why any errors in the parsing are silently swallowed
> in SearchContextImpl.getCondition():
> if (theExpression != null) {
> try {
> return parser.parse(theExpression);
> } catch (SearchParseException ex) {
> return null;
> }
> } else {
> return null;
> }
>
> Thanks again.
>
> Jim
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com
Re: Correct way to use a JPA*QueryVisitor with a filter class that
is not a JPA entity
Posted by Sergey Beryozkin <sb...@gmail.com>.
On 21/10/13 21:07, Jim Talbut wrote:
> On 21/10/2013 10:18, Sergey Beryozkin wrote:
>> I believe the JPA2 way is to use either JPA2 Tuple or capturing
>> beans/arrays which will filter the 'username' & 'enabled' properties
>> at JPA/DB level, the JPA2 section has a couple of examples and
>> JPATypedQueryVisitorTest has few more (to do with different styles of
>> shaping the output), I'd probably go for using Tuple.
>>
>> If you prefer to use a custom UserFilter then I guess you'd need to use
>> JPATypedQueryVisitor<User_JpaImpl> and then filter the result list
>> with the filter afterwards
>
> Thanks, I think I'm going to go with using another visitor just to do my
> validation, and then use the simple TypedQuery - any other approach
> seems to create more complexity (for my scenario) than it's worth.
The metadata can be generated with the JPA impl plugin, the plus - the
faster retrieval times I guess
>
> Is there a reason why any errors in the parsing are silently swallowed
> in SearchContextImpl.getCondition():
> if (theExpression != null) {
> try {
> return parser.parse(theExpression);
> } catch (SearchParseException ex) {
> return null;
> }
> } else {
> return null;
> }
>
Right, originally I thought that typically, if one goes and query some
web site and mistypes a query name then one would still get some default
OK response, as opposed to some 400.
So if you get 'null' then assume that the default representation is to
be returned, given that the query parameters are usually optional anyway.
However, I agree this approach may have its limitations, I think that
for 3.0 only, we need to push the responsibility a bit higher to the
application code, the good practice would still most likely be to
proceed with returning a default rep, but may be the application code
will decide to do something else
Cheers, Sergey
> Thanks again.
>
> Jim
Re: Correct way to use a JPA*QueryVisitor with a filter class that
is not a JPA entity
Posted by Jim Talbut <jt...@spudsoft.co.uk>.
On 21/10/2013 10:18, Sergey Beryozkin wrote:
> I believe the JPA2 way is to use either JPA2 Tuple or capturing
> beans/arrays which will filter the 'username' & 'enabled' properties
> at JPA/DB level, the JPA2 section has a couple of examples and
> JPATypedQueryVisitorTest has few more (to do with different styles of
> shaping the output), I'd probably go for using Tuple.
>
> If you prefer to use a custom UserFilter then I guess you'd need to use
> JPATypedQueryVisitor<User_JpaImpl> and then filter the result list
> with the filter afterwards
Thanks, I think I'm going to go with using another visitor just to do my
validation, and then use the simple TypedQuery - any other approach
seems to create more complexity (for my scenario) than it's worth.
Is there a reason why any errors in the parsing are silently swallowed
in SearchContextImpl.getCondition():
if (theExpression != null) {
try {
return parser.parse(theExpression);
} catch (SearchParseException ex) {
return null;
}
} else {
return null;
}
Thanks again.
Jim
Re: Correct way to use a JPA*QueryVisitor with a filter class that
is not a JPA entity
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi
On 21/10/13 07:21, Jim Talbut wrote:
> Hi,
>
> I have a JPA data model that I'm trying to use with CXF's SearchContext.
>
> In order to constrain the searching that can be done I'm trying to use a
> search class that is not a JPA entity (and that just contains a subset
> of the JPA fields).
> Q1. Is this the right way to solve this problem?
> Q2. How should I get it to work?
>
> Details:
>
> I have a "User" interface that the "User_JpaImpl" entity class derives
> from.
> I also have a "UserFilter" class that just has two properties (username
> & enabled) - the User interface also has getters and setters for these
> properties, but there is no relationship between UserFilter and User (or
> User_JpaImpl).
>
> My best attempt so far looks like this:
> SearchCondition<UserFilter> sc =
> searchContext.getCondition(UserFilter.class);
> JPACriteriaQueryVisitor<UserFilter, User_JpaImpl> visitor =
> new JPACriteriaQueryVisitor<>(entityManager,
> UserFilter.class, User_JpaImpl.class);
> searchCondition.accept(visitor);
>
> TypedQuery<User_JpaImpl> query = visitor.getTypedQuery();
> List<? extends User> result = query.getResultList();
>
> This throws an exception in accept because of this:
> if (builder == null) {
> builder = em.getCriteriaBuilder();
> cq = builder.createQuery(queryClass);
> root = cq.from(tClass);
> predStack.push(new ArrayList<Predicate>());
> }
>
> tClass is UserFilter.class, which is not known to JPA and thus cannot be
> used as root (cq.from(tClass) throws IllegalArgumentException).
>
>
> All I want to do is limit the set of fields that can be queried, if this
> is the wrong approach I'm happy to swap it for another.
>
I believe the JPA2 way is to use either JPA2 Tuple or capturing
beans/arrays which will filter the 'username' & 'enabled' properties at
JPA/DB level, the JPA2 section has a couple of examples and
JPATypedQueryVisitorTest has few more (to do with different styles of
shaping the output), I'd probably go for using Tuple.
If you prefer to use a custom UserFilter then I guess you'd need to use
JPATypedQueryVisitor<User_JpaImpl> and then filter the result list with
the filter afterwards
Thanks, Sergey
> Thanks.
>
> Jim