Grid data source, BeanModel and nested properties

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Grid data source, BeanModel and nested properties

Ilya Obshadko-2
I'm trying to implement a Grid data source optimized for database
retrievals (with paging support). Basically it's derived from
HibernateGridDataSource from Tapestry distribution, and provides support
for complex Criteria queries:
https://gist.github.com/xfyre/ecb36a9173aed6a37f14

However, there is a problem with sorting.

Provided BeanModel implementation doesn't support nested properties; that
is, I cannot use properties of child Hibernate entities: <t:grid
include="property1, child1.property1, child2.property2" .../> results in
error. Initially I had a workaround of having helper getter methods in
parent entity class, so it looked like  <t:grid include="property1,
child1Property1, child2Property2" .../>. It worked, but when I'm trying to
use database-backed Grid data source, there's an error with sorting
(because sorting is performed on database level and obviously root entity
of the query doesn't contain database properties specified in Grid.

Is there any reasonable solution for that, besides manually providing all
required mappings between Grid property names and database property names?

--
Ilya Obshadko
Reply | Threaded
Open this post in threaded view
|

Re: Grid data source, BeanModel and nested properties

Chris Poulsen
The automatic creation of bean models can only do so much - I always find
that the automatic model creation is great for getting started, but at some
point it is always necessary to provide explicit bean models.

The pattern we end up with is something like this:

model = beanModelSource.createDisplayModel
model.include( <properties we want> )
model.add* (to get the properties that the introspector cannot
find/properties that need extra arguments)

... the "include" part is important to avoid extra columns showing up when
the data model is changed.

So I guess that you do need to specify most of it manually - alternatively
you could probably teach tapestry about the complex property types, but I
prefer the manual way.

--
Chris


On Fri, Jan 2, 2015 at 9:45 AM, Ilya Obshadko <[hidden email]>
wrote:

> I'm trying to implement a Grid data source optimized for database
> retrievals (with paging support). Basically it's derived from
> HibernateGridDataSource from Tapestry distribution, and provides support
> for complex Criteria queries:
> https://gist.github.com/xfyre/ecb36a9173aed6a37f14
>
> However, there is a problem with sorting.
>
> Provided BeanModel implementation doesn't support nested properties; that
> is, I cannot use properties of child Hibernate entities: <t:grid
> include="property1, child1.property1, child2.property2" .../> results in
> error. Initially I had a workaround of having helper getter methods in
> parent entity class, so it looked like  <t:grid include="property1,
> child1Property1, child2Property2" .../>. It worked, but when I'm trying to
> use database-backed Grid data source, there's an error with sorting
> (because sorting is performed on database level and obviously root entity
> of the query doesn't contain database properties specified in Grid.
>
> Is there any reasonable solution for that, besides manually providing all
> required mappings between Grid property names and database property names?
>
> --
> Ilya Obshadko
>
Reply | Threaded
Open this post in threaded view
|

Re: Grid data source, BeanModel and nested properties

jonabarker
In reply to this post by Ilya Obshadko-2
Ilya,

Our strategy is to use a class specifically to hold the query results,
so the sort criteria are simple properties.  The Criteria query and
Projection are supplied separately to our GridDataSource.   The
Projection maps any child properties onto aliases (useful for the
sorting), and an optional ResultTransformer as well.  If none is
provided, the Transformers.aliasToBean is used.  The count is achieved
by using the Projections.rowCount().

On Fri, Jan 2, 2015 at 3:45 AM, Ilya Obshadko <[hidden email]> wrote:

> I'm trying to implement a Grid data source optimized for database
> retrievals (with paging support). Basically it's derived from
> HibernateGridDataSource from Tapestry distribution, and provides support
> for complex Criteria queries:
> https://gist.github.com/xfyre/ecb36a9173aed6a37f14
>
> However, there is a problem with sorting.
>
> Provided BeanModel implementation doesn't support nested properties; that
> is, I cannot use properties of child Hibernate entities: <t:grid
> include="property1, child1.property1, child2.property2" .../> results in
> error. Initially I had a workaround of having helper getter methods in
> parent entity class, so it looked like  <t:grid include="property1,
> child1Property1, child2Property2" .../>. It worked, but when I'm trying to
> use database-backed Grid data source, there's an error with sorting
> (because sorting is performed on database level and obviously root entity
> of the query doesn't contain database properties specified in Grid.
>
> Is there any reasonable solution for that, besides manually providing all
> required mappings between Grid property names and database property names?
>
> --
> Ilya Obshadko



--
Jonathan Barker
ITStrategic

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Grid data source, BeanModel and nested properties

Ilya Obshadko-2
Johnathan,

How do you handle situations when several of the properties you need to
display are aggregates?
For example: select ..., sum(amount_invoiced), sum(amount_paid) from orders
group by order_id.

This won't work nice with Projections.rowCount() (unless you use
sub-select, which might be sub-optimal, and I'm not sure if even possible
using Criteria API).


On Sat, Jan 3, 2015 at 5:57 AM, Jonathan Barker <[hidden email]
> wrote:

> Ilya,
>
> Our strategy is to use a class specifically to hold the query results,
> so the sort criteria are simple properties.  The Criteria query and
> Projection are supplied separately to our GridDataSource.   The
> Projection maps any child properties onto aliases (useful for the
> sorting), and an optional ResultTransformer as well.  If none is
> provided, the Transformers.aliasToBean is used.  The count is achieved
> by using the Projections.rowCount().
>
> On Fri, Jan 2, 2015 at 3:45 AM, Ilya Obshadko <[hidden email]>
> wrote:
> > I'm trying to implement a Grid data source optimized for database
> > retrievals (with paging support). Basically it's derived from
> > HibernateGridDataSource from Tapestry distribution, and provides support
> > for complex Criteria queries:
> > https://gist.github.com/xfyre/ecb36a9173aed6a37f14
> >
> > However, there is a problem with sorting.
> >
> > Provided BeanModel implementation doesn't support nested properties; that
> > is, I cannot use properties of child Hibernate entities: <t:grid
> > include="property1, child1.property1, child2.property2" .../> results in
> > error. Initially I had a workaround of having helper getter methods in
> > parent entity class, so it looked like  <t:grid include="property1,
> > child1Property1, child2Property2" .../>. It worked, but when I'm trying
> to
> > use database-backed Grid data source, there's an error with sorting
> > (because sorting is performed on database level and obviously root entity
> > of the query doesn't contain database properties specified in Grid.
> >
> > Is there any reasonable solution for that, besides manually providing all
> > required mappings between Grid property names and database property
> names?
> >
> > --
> > Ilya Obshadko
>
>
>
> --
> Jonathan Barker
> ITStrategic
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>


--
Ilya Obshadko
Reply | Threaded
Open this post in threaded view
|

Re: Grid data source, BeanModel and nested properties

Thiago H de Paula Figueiredo
In reply to this post by Ilya Obshadko-2
On Fri, 02 Jan 2015 06:45:30 -0200, Ilya Obshadko  
<[hidden email]> wrote:

> I'm trying to implement a Grid data source optimized for database
> retrievals (with paging support). Basically it's derived from
> HibernateGridDataSource from Tapestry distribution, and provides support
> for complex Criteria queries:
> https://gist.github.com/xfyre/ecb36a9173aed6a37f14
>
> However, there is a problem with sorting.
>
> Provided BeanModel implementation doesn't support nested properties; that
> is, I cannot use properties of child Hibernate entities: <t:grid
> include="property1, child1.property1, child2.property2" .../>results in  
> error.

Remember you're passing a Class instance for BeanModelSource, so the  
properties which are actually recognized as the ones provided by the class  
you passed, not subclass ones. That's how Java and strongly-typed  
languages work: if you have a class C and a subclass S, if you ask Java  
reflection classes or BeanModelSource to provide a list of properties of  
C, only properties from C will appear.

> Initially I had a workaround of having helper getter methods in
> parent entity class, so it looked like  <t:grid include="property1,
> child1Property1, child2Property2" .../>. It worked, but when I'm trying  
> to use database-backed Grid data source, there's an error with sorting
> (because sorting is performed on database level and obviously root entity
> of the query doesn't contain database properties specified in Grid.

You receive the name of these properties, so it's up to your code to  
handle this kind of situation (synthetic BeanModel properties).

I agree with Chris, whose opinion matches what Howard has been saying for  
a long time in the Tapestry mailing list: the BeanModel classes and  
components are meant to be used as a starting point, as scaffolding, as  
tools to have something working quickly, but they're not supposed to  
handle all scenarios by themselves.

--
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Grid data source, BeanModel and nested properties

Ilya Obshadko-2
I have ended up with custom DTO classes and Hibernate projections. Although
the resulting code looks far from elegant, it's extremely fast, compared to
'normal' retrieval using lists, without paging (especially for lists with
hundreds of records of course).

On Mon, Jan 5, 2015 at 1:39 PM, Thiago H de Paula Figueiredo <
[hidden email]> wrote:

> On Fri, 02 Jan 2015 06:45:30 -0200, Ilya Obshadko <[hidden email]>
> wrote:
>
>  I'm trying to implement a Grid data source optimized for database
>> retrievals (with paging support). Basically it's derived from
>> HibernateGridDataSource from Tapestry distribution, and provides support
>> for complex Criteria queries:
>> https://gist.github.com/xfyre/ecb36a9173aed6a37f14
>>
>> However, there is a problem with sorting.
>>
>> Provided BeanModel implementation doesn't support nested properties; that
>> is, I cannot use properties of child Hibernate entities: <t:grid
>> include="property1, child1.property1, child2.property2" .../>results in
>> error.
>>
>
> Remember you're passing a Class instance for BeanModelSource, so the
> properties which are actually recognized as the ones provided by the class
> you passed, not subclass ones. That's how Java and strongly-typed languages
> work: if you have a class C and a subclass S, if you ask Java reflection
> classes or BeanModelSource to provide a list of properties of C, only
> properties from C will appear.
>
>  Initially I had a workaround of having helper getter methods in
>> parent entity class, so it looked like  <t:grid include="property1,
>> child1Property1, child2Property2" .../>. It worked, but when I'm trying
>> to use database-backed Grid data source, there's an error with sorting
>> (because sorting is performed on database level and obviously root entity
>> of the query doesn't contain database properties specified in Grid.
>>
>
> You receive the name of these properties, so it's up to your code to
> handle this kind of situation (synthetic BeanModel properties).
>
> I agree with Chris, whose opinion matches what Howard has been saying for
> a long time in the Tapestry mailing list: the BeanModel classes and
> components are meant to be used as a starting point, as scaffolding, as
> tools to have something working quickly, but they're not supposed to handle
> all scenarios by themselves.
>
> --
> Thiago H. de Paula Figueiredo
> Tapestry, Java and Hibernate consultant and developer
> http://machina.com.br
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>


--
Ilya Obshadko
Reply | Threaded
Open this post in threaded view
|

Re: Grid data source, BeanModel and nested properties

jonabarker
In reply to this post by Ilya Obshadko-2
Ilya,

I haven't faced that situation… yet.  I guess the complication is in
specifying the grouping conditions.

My stats listings are restricted in size, so I don't worry about a
paged grid source for those, and I get the results from stored
procedures.  Some of the *counts* in that list are large.  I need
someone to be able to click on 86000 and go to a listing that doesn't
bring down the application.

Let me know if you find an adequate solution.  I see your other post
about code that looks far from elegant - if that is it, I would be
curious to know how you handled the projections.

Regards,
Jonathan



On Sat, Jan 3, 2015 at 3:21 AM, Ilya Obshadko <[hidden email]> wrote:

> Johnathan,
>
> How do you handle situations when several of the properties you need to
> display are aggregates?
> For example: select ..., sum(amount_invoiced), sum(amount_paid) from orders
> group by order_id.
>
> This won't work nice with Projections.rowCount() (unless you use
> sub-select, which might be sub-optimal, and I'm not sure if even possible
> using Criteria API).
>
>
> On Sat, Jan 3, 2015 at 5:57 AM, Jonathan Barker <[hidden email]
>> wrote:
>
>> Ilya,
>>
>> Our strategy is to use a class specifically to hold the query results,
>> so the sort criteria are simple properties.  The Criteria query and
>> Projection are supplied separately to our GridDataSource.   The
>> Projection maps any child properties onto aliases (useful for the
>> sorting), and an optional ResultTransformer as well.  If none is
>> provided, the Transformers.aliasToBean is used.  The count is achieved
>> by using the Projections.rowCount().
>>
>> On Fri, Jan 2, 2015 at 3:45 AM, Ilya Obshadko <[hidden email]>
>> wrote:
>> > I'm trying to implement a Grid data source optimized for database
>> > retrievals (with paging support). Basically it's derived from
>> > HibernateGridDataSource from Tapestry distribution, and provides support
>> > for complex Criteria queries:
>> > https://gist.github.com/xfyre/ecb36a9173aed6a37f14
>> >
>> > However, there is a problem with sorting.
>> >
>> > Provided BeanModel implementation doesn't support nested properties; that
>> > is, I cannot use properties of child Hibernate entities: <t:grid
>> > include="property1, child1.property1, child2.property2" .../> results in
>> > error. Initially I had a workaround of having helper getter methods in
>> > parent entity class, so it looked like  <t:grid include="property1,
>> > child1Property1, child2Property2" .../>. It worked, but when I'm trying
>> to
>> > use database-backed Grid data source, there's an error with sorting
>> > (because sorting is performed on database level and obviously root entity
>> > of the query doesn't contain database properties specified in Grid.
>> >
>> > Is there any reasonable solution for that, besides manually providing all
>> > required mappings between Grid property names and database property
>> names?
>> >
>> > --
>> > Ilya Obshadko
>>
>>
>>
>> --
>> Jonathan Barker
>> ITStrategic
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [hidden email]
>> For additional commands, e-mail: [hidden email]
>>
>>
>
>
> --
> Ilya Obshadko



--
Jonathan Barker
ITStrategic

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Grid data source, BeanModel and nested properties

Ilya Obshadko-2
Actually the solution was @Formula Hibernate fields.

For example:

    @XmlTransient

    @Formula("(select sum(invoices.amountdue) from invoices where
invoices.event_id = event_id and invoices.participant_id = participant_id)")

    private Double amountInvoiced;

PostgreSQL is able to optimize it pretty well, when you have necessary
indexes (the whole query with sub-selects takes about 10-14 ms).

When I'm saying about the solution that is 'far from elegant', I mean the
size of Criteria creation code (about 30 lines) and its lack of reusability
(because every component have slightly different conditions of using it).
But overall performance is very, very fast as soon as you eliminate "N+1"
Hibernate problem.


On Tue, Jan 6, 2015 at 5:30 PM, Jonathan Barker <[hidden email]
> wrote:

> Ilya,
>
> I haven't faced that situation… yet.  I guess the complication is in
> specifying the grouping conditions.
>
> My stats listings are restricted in size, so I don't worry about a
> paged grid source for those, and I get the results from stored
> procedures.  Some of the *counts* in that list are large.  I need
> someone to be able to click on 86000 and go to a listing that doesn't
> bring down the application.
>
> Let me know if you find an adequate solution.  I see your other post
> about code that looks far from elegant - if that is it, I would be
> curious to know how you handled the projections.
>
> Regards,
> Jonathan
>
>
>
> On Sat, Jan 3, 2015 at 3:21 AM, Ilya Obshadko <[hidden email]>
> wrote:
> > Johnathan,
> >
> > How do you handle situations when several of the properties you need to
> > display are aggregates?
> > For example: select ..., sum(amount_invoiced), sum(amount_paid) from
> orders
> > group by order_id.
> >
> > This won't work nice with Projections.rowCount() (unless you use
> > sub-select, which might be sub-optimal, and I'm not sure if even possible
> > using Criteria API).
> >
> >
> > On Sat, Jan 3, 2015 at 5:57 AM, Jonathan Barker <
> [hidden email]
> >> wrote:
> >
> >> Ilya,
> >>
> >> Our strategy is to use a class specifically to hold the query results,
> >> so the sort criteria are simple properties.  The Criteria query and
> >> Projection are supplied separately to our GridDataSource.   The
> >> Projection maps any child properties onto aliases (useful for the
> >> sorting), and an optional ResultTransformer as well.  If none is
> >> provided, the Transformers.aliasToBean is used.  The count is achieved
> >> by using the Projections.rowCount().
> >>
> >> On Fri, Jan 2, 2015 at 3:45 AM, Ilya Obshadko <[hidden email]>
> >> wrote:
> >> > I'm trying to implement a Grid data source optimized for database
> >> > retrievals (with paging support). Basically it's derived from
> >> > HibernateGridDataSource from Tapestry distribution, and provides
> support
> >> > for complex Criteria queries:
> >> > https://gist.github.com/xfyre/ecb36a9173aed6a37f14
> >> >
> >> > However, there is a problem with sorting.
> >> >
> >> > Provided BeanModel implementation doesn't support nested properties;
> that
> >> > is, I cannot use properties of child Hibernate entities: <t:grid
> >> > include="property1, child1.property1, child2.property2" .../> results
> in
> >> > error. Initially I had a workaround of having helper getter methods in
> >> > parent entity class, so it looked like  <t:grid include="property1,
> >> > child1Property1, child2Property2" .../>. It worked, but when I'm
> trying
> >> to
> >> > use database-backed Grid data source, there's an error with sorting
> >> > (because sorting is performed on database level and obviously root
> entity
> >> > of the query doesn't contain database properties specified in Grid.
> >> >
> >> > Is there any reasonable solution for that, besides manually providing
> all
> >> > required mappings between Grid property names and database property
> >> names?
> >> >
> >> > --
> >> > Ilya Obshadko
> >>
> >>
> >>
> >> --
> >> Jonathan Barker
> >> ITStrategic
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: [hidden email]
> >> For additional commands, e-mail: [hidden email]
> >>
> >>
> >
> >
> > --
> > Ilya Obshadko
>
>
>
> --
> Jonathan Barker
> ITStrategic
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>


--
Ilya Obshadko