Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[eclipselink-users] Re: @OrderBy does not work on java.util.Date

Hi Martin,
take a look at the following example:
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Collectionordering

It might help for what you want to do.

Reinhard



eclipselink-users-request@xxxxxxxxxxx wrote:
Send eclipselink-users mailing list submissions to
	eclipselink-users@xxxxxxxxxxx

To subscribe or unsubscribe via the World Wide Web, visit
	https://dev.eclipse.org/mailman/listinfo/eclipselink-users
or, via email, send a message with subject or body 'help' to
	eclipselink-users-request@xxxxxxxxxxx

You can reach the person managing the list at
	eclipselink-users-owner@xxxxxxxxxxx

When replying, please edit your Subject line so it is more specific
than "Re: Contents of eclipselink-users digest..."


Today's Topics:

   1. Re: @OrderBy does not work on java.util.Date (Martin Dames)
   2. Re: @OrderBy does not work on java.util.Date
      (christopher delahunt)


----------------------------------------------------------------------

Message: 1
Date: Thu, 3 Dec 2009 14:17:39 +0100
From: Martin Dames <m.dames@xxxxxx>
Subject: Re: [eclipselink-users] @OrderBy does not work on
	java.util.Date
To: EclipseLink User Discussions <eclipselink-users@xxxxxxxxxxx>
Message-ID: <E2178684-14B2-4AFB-89F7-01ED4503BFD6@xxxxxx>
Content-Type: text/plain; charset="us-ascii"

Hi Christopher,

thanks for reply.

Hmm... if I specify @OrderBy should EclipseLink not guarantee the sorting order, doesn't matter if it is in cache, read from DB or whatever. From the Business Logic point of view, I need a reliable sorting if Im getting the childrens.

Martin.



Am 03.12.2009 um 14:09 schrieb Christopher Delahunt:

  
Hello,
 
The em.find is getting the entity from the cache which has the collection in the order from the last modification.  To get the list brought in from the database, try using em.refresh on the retrieved entity.
 
Also note that Eclipselink has a second level cache, and that just closing an EntityManager may not be enough to cause a database hit - this depends on the caching settings being used though.
 
Best Regards,
Chris
 

----- Original Message -----
From: m.dames@xxxxxx
To: eclipselink-users@xxxxxxxxxxx
Sent: Thursday, December 3, 2009 6:30:55 AM GMT -05:00 US/Canada Eastern
Subject: [eclipselink-users] @OrderBy does not work on java.util.Date

Hi guys,

as a solution to my previous post (see below) I switched from TreeSet to List for my childrens. At the Java side, I can retrieve the newest one (specified by the date) without problems (using Collection.sort()).

But, if an Entity has alot childrens, each with another date, I would prefer to have all childrens in an ascending order in my list when the list is created. JPA should do the magic since it can retrieve the List in correct order.

I added therefore the @OrderBy(value="date ASC") annotation to my Entity objects List of childrens

@OneToMany (mappedBy = "entity", fetch=FetchType.LAZY, cascade = {CascadeType.ALL})
@OrderBy(value="date ASC")
private List<Child> childrens = new ArrayList<Child>();

my Child Entity looks like:

class Child {

@Temporal(TemporalType.TIMESTAMP)
@Column(nullable = false)
private java.util.Date date;
..
getter
setter
}

my TestCase should check the appropriate order if an entity object is retrieved from database:

public void testOrderAfterRetrieval {

Entity e = new Entity();
Child child1 = new Child();
child1.setDate(new Date());
Child child2 = new Child();
child2.setDate(new Date() + one day); // plus one day is done with Calender API

e.getChildrens.add(child2); // tomorrow will be inserted first to get a wrong sorting
e.getChildrens.add(child1); 
// so the list should now contain {child2, child1}
...
em.persist(e);
..

em.close(); // Here I want that the em will be forced to load every entity from database to ensure the sorting

Entity foundEntity = em.find(e.getId); // find the persisted entity and all children

assertEquals(child1, foundEntity.getChildrens.get(0)); // test if the list is in ASC order, child1 should be the first in the list since the Date is before child2
assertEquals(child2, foundEntity.getChildrens.get(1));

...

The test fails. The first inserted child (child2) will be the first in the new retrieved List. So, what is wrong?

If Im changing the insertion order before persist, the test will be passed. But I want that a find method will retrieve this in my wished order without regards to the order it was persisted before.

Im using EclipseLink 1.2 with MySQL. The MySQL table has "datetime" as column type and was generated by EclipseLink.


Thank you for help!

Martin.



Am 02.12.2009 um 23:23 schrieb Michael Bar-sinai:

Hi Martin,
I would use a list, and add the @OrderBy annotation. That would do the sorting on the SQL side. You could also use a custom query and a controller class (e.g. controllerClass.getLastKidsFor( entity ) ), depends on your application architecture.

Michael

On Thu, Dec 3, 2009 at 12:18 AM, Martin Dames <m.dames@xxxxxx> wrote:
Hi Michael,

thanks for reply.

Yes, that was what I am afraid of. The bigger picture is, that I would like get the newest children without any performance issues. The children are holding a date in my real case. I implemented this as usual with a TreeSet, which will sort the children's by adding a new one automatigally with a comparator.

I might fetch the childrens sorted by the database and not in my java app, so I can use lazy load or batch fetch.

Unfortunately it is not an option to sort the HashSet at the Java-side each time I retrieve the result, that would be too slow.

Actually an ORM should'nt affect the OO side. But in this case I have to design my object architecture with regard to JPA. This isn't sufficient in my eyes. If I want to use a TreeSet, I should get a TreeSet and all other Collection types.

Thanks,

Martin.




Am 02.12.2009 um 22:25 schrieb Michael Bar-sinai:

Hi Martin,
Eclipselink creates an IndirectSet to do the lazy loading - TreeSets stores everything in the memory. You can't really get around this unless you do EAGER loading, and even then you'll probably get something that not a TreeSet.
What's the bigger picture? What are you trying to achieve? You could always instantiate a TreeSet and call addAll(), but that would be manually eager loading.

Michael Bar-Sinai

P.S.
The @OrderBy annotation applies to lists: http://www.eclipse.org/eclipselink/api/1.1/javax/persistence/OrderBy.html

On Wed, Dec 2, 2009 at 11:15 PM, Martin Dames <m.dames@xxxxxx> wrote:
Ok, I tried a bit and didn't get a solution:


I changed the fetch type to EAGER instead of LAZY.

Now I get another ClassCastException :
java.lang.ClassCastException: java.util.HashSet cannot be cast to java.util.TreeSet

The setter method from the last post (see below) will convert the passed Set into a TreeSet, so there should just be an instance of TreeSet in my children set, but EclipseLink is creating a HashSet !?!.

I tried to use OrderBy Annotation:

@OrderBy(value="firstname")
@OneToMany (mappedBy = "entity", fetch=FetchType.EAGER, cascade = {CascadeType.ALL})
private Set<Child> childrens = new TreeSet<Child>();

in hope that it will return an instance of TreeSet (which is sorted at first place in ascending order), but this does not work either.

Thank you for your support!

Martin.



Anfang der weitergeleiteten E-Mail:

Von: Martin Dames <m.dames@xxxxxx>
Datum: 2. Dezember 2009 20:08:55 MEZ
An: eclipselink-users@xxxxxxxxxxx
Betreff: IndirectSet cannot be cast to java.util.TreeSet

Hi all,

I've got an error when I look up my lazy loaded children of one of my pojos:

java.lang.ClassCastException: org.eclipse.persistence.indirection.IndirectSet cannot be cast to java.util.TreeSet

Ok, the thing has something to do with the lazy loading technology in EclipseLink/TopLink... if i have an entity like this:

@Entity
class Entity {

@OneToMany (mappedBy = "entity", fetch=FetchType.LAZY, cascade = {CascadeType.ALL})
private Set<Child> childrens = new TreeSet<Child>();

public void setChildrens(Set<Child> childrens) { this.childrens = childrens }

public Set<Child> getChildrens() { return this.childrens }

public Child getNextChild() {
return this. childrens.size() > 0 ? ((TreeSet<Child>) this. childrens).last() : null;
}
... 
}

If I now find all entities of Entity and call getNextChild(), I will get the error. It seems that EclipseLink will pass a IndirectSet object into my childrens set and then I can not cast it anymore. The indirect set handles somehow the lazy load technique.... so what to do?

I tried this:
public void setChildrens(Set<Child> childrens) { this.childrens = new TreeSet<Child>(childrens); }

but this does not work either. It seems, that EclipseLink is using reflection to pass the IndiretSet into my set property.

I my assumptions are correct, what is to do if want to use lazy loading, a TreeSet (for sorting purposes--see .last() above) and the Set property of my Entity class interface should be remain java.uti.Set?

Thank you for help!

Martin.



_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
< A href="" class="moz-txt-link-rfc2396E" href="https://dev.eclipse.org/mailman/listinfo/eclipselink-users">"https://dev.eclipse.org/mailman/listinfo/eclipselink-users" target=_blank>https://dev.eclipse.org/mailman/listinfo/eclipselink-users


_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users


_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users


_______________________________________________
eclipseli! nk-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users

_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users
    
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://dev.eclipse.org/mailman/private/eclipselink-users/attachments/20091203/63ea8c62/attachment.html

------------------------------

Message: 2
Date: Thu, 03 Dec 2009 08:25:46 -0500
From: christopher delahunt <christopher.delahunt@xxxxxxxxxx>
Subject: Re: [eclipselink-users] @OrderBy does not work on
	java.util.Date
To: EclipseLink User Discussions <eclipselink-users@xxxxxxxxxxx>
Message-ID: <4B17BC5A.70305@xxxxxxxxxx>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

Hello Martin,

OrderBy only guarantees that what is returned from the database is 
ordered.  It is the applications job to maintain this ordering.  JPA 
entities are trying to be plain java objects as much as possible, and 
performance would take a hit depending on when the provider decides it 
needs to reorder your collection. 

Best Regards,
Chris

Martin Dames wrote:
  
Hi Christopher,

thanks for reply.

Hmm... if I specify @OrderBy should EclipseLink not guarantee the 
sorting order, doesn't matter if it is in cache, read from DB or 
whatever. From the Business Logic point of view, I need a reliable 
sorting if Im getting the childrens.

Martin.



Am 03.12.2009 um 14:09 schrieb Christopher Delahunt:

    
Hello,

 

The em.find is getting the entity from the cache which has the 
collection in the order from the last modification.  To get the list 
brought in from the database, try using em.refresh on the retrieved 
entity.

 

Also note that Eclipselink has a second level cache, and that just 
closing an EntityManager may not be enough to cause a database hit - 
this depends on the caching settings being used though.

 

Best Regards,
Chris

 


----- Original Message -----
From: m.dames@xxxxxx <mailto:m.dames@xxxxxx>
To: eclipselink-users@xxxxxxxxxxx <mailto:eclipselink-users@xxxxxxxxxxx>
Sent: Thursday, December 3, 2009 6:30:55 AM GMT -05:00 US/Canada Eastern
Subject: [eclipselink-users] @OrderBy does not work on java.util.Date

Hi guys,

as a solution to my previous post (see below) I switched from TreeSet 
to List for my childrens. At the Java side, I can retrieve the newest 
one (specified by the date) without problems (using Collection.sort()).

But, if an Entity has alot childrens, each with another date, I would 
prefer to have all childrens in an ascending order in my list when 
the list is created. JPA should do the magic since it can retrieve 
the List in correct order.

I added therefore the @OrderBy(value="date ASC") annotation to my 
Entity objects List of childrens

@OneToMany (mappedBy = "entity", fetch=FetchType.LAZY, cascade = 
{CascadeType.ALL})
@OrderBy(value="date ASC")
private List<Child> childrens = new ArrayList<Child>();

my Child Entity looks like:

class Child {

@Temporal(TemporalType.TIMESTAMP)
@Column(nullable = false)
private java.util.Date date;
..
getter
setter
}

my TestCase should check the appropriate order if an entity object is 
retrieved from database:

public void testOrderAfterRetrieval {

Entity e = new Entity();
Child child1 = new Child();
child1.setDate(new Date());
Child child2 = new Child();
child2.setDate(new Date() + one day); // plus one day is done with 
Calender API

e.getChildrens.add(child2); // tomorrow will be inserted first to get 
a wrong sorting
e.getChildrens.add(child1); 
// so the list should now contain {child2, child1}
...
em.persist(e);
..

em.close(); // Here I want that the em will be forced to load every 
entity from database to ensure the sorting

Entity foundEntity = em.find(e.getId); // find the persisted entity 
and all children

assertEquals(child1, foundEntity.getChildrens.get(0)); // test if the 
list is in ASC order, child1 should be the first in the list since 
the Date is before child2
assertEquals(child2, foundEntity.getChildrens.get(1));

...

The test fails. The first inserted child (child2) will be the first 
in the new retrieved List. So, what is wrong?

If Im changing the insertion order before persist, the test will be 
passed. But I want that a find method will retrieve this in my wished 
order without regards to the order it was persisted before.

Im using EclipseLink 1.2 with MySQL. The MySQL table has "datetime" 
as column type and was generated by EclipseLink.


Thank you for help!

Martin.



Am 02.12.2009 um 23:23 schrieb Michael Bar-sinai:

    Hi Martin,
    I would use a list, and add the @OrderBy annotation. That would
    do the sorting on the SQL side. You could also use a custom query
    and a controller class (e.g. controllerClass.getLastKidsFor(
    entity ) ), depends on your application architecture.

    Michael

    On Thu, Dec 3, 2009 at 12:18 AM, Martin Dames <m.dames@xxxxxx
    <mailto:m.dames@xxxxxx>> wrote:

        Hi Michael,

        thanks for reply.

        Yes, that was what I am afraid of. The bigger picture is,
        that I would like get the newest children without any
        performance issues. The children are holding a date in my
        real case. I implemented this as usual with a TreeSet, which
        will sort the children's by adding a new one automatigally
        with a comparator.

        I might fetch the childrens sorted by the database and not in
        my java app, so I can use lazy load or batch fetch.

        Unfortunately it is not an option to sort the HashSet at the
        Java-side each time I retrieve the result, that would be too
        slow.

        Actually an ORM should'nt affect the OO side. But in this
        case I have to design my object architecture with regard to
        JPA. This isn't sufficient in my eyes. If I want to use a
        TreeSet, I should get a TreeSet and all other Collection types.

        Thanks,

        Martin.




        Am 02.12.2009 um 22:25 schrieb Michael Bar-sinai:

            Hi Martin,
            Eclipselink creates an IndirectSet to do the lazy loading
            - TreeSets stores everything in the memory. You can't
            really get around this unless you do EAGER loading, and
            even then you'll probably get something that not a TreeSet.
            What's the bigger picture? What are you trying to
            achieve? You could always instantiate a TreeSet and call
            addAll(), but that would be manually eager loading.

            Michael Bar-Sinai

            P.S.
            The @OrderBy annotation applies to
            lists: http://www.eclipse.org/eclipselink/api/1.1/javax/persistence/OrderBy.html

            On Wed, Dec 2, 2009 at 11:15 PM, Martin
            Dames <m.dames@xxxxxx <mailto:m.dames@xxxxxx>> wrote:

                Ok, I tried a bit and didn't get a solution:


                I changed the fetch type to EAGER instead of LAZY.

                Now I get another ClassCastException :
                java.lang.ClassCastException: java.util.HashSet
                cannot be cast to java.util.TreeSet

                The setter method from the last post (see below) will
                convert the passed Set into a TreeSet, so there
                should just be an instance of TreeSet in my children
                set, but EclipseLink is creating a HashSet !?!.

                I tried to use OrderBy Annotation:

                @OrderBy(value="firstname")
                @OneToMany (mappedBy = "entity",
                fetch=FetchType.EAGER, cascade = {CascadeType.ALL})
                private Set<Child> childrens = new TreeSet<Child>();

                in hope that it will return an instance of TreeSet
                (which is sorted at first place in ascending order),
                but this does not work either.

                Thank you for your support!

                Martin.



                Anfang der weitergeleiteten E-Mail:

                    *Von: *Martin Dames <m.dames@xxxxxx
                    <mailto:m.dames@xxxxxx>>
                    *Datum: *2. Dezember 2009 20:08:55 MEZ
                    *An: *eclipselink-users@xxxxxxxxxxx
                    <mailto:eclipselink-users@xxxxxxxxxxx>
                    *Betreff: **IndirectSet cannot be cast to
                    java.util.TreeSet*

                    Hi all,

                    I've got an error when I look up my lazy loaded
                    children of one of my pojos:

                    java.lang.ClassCastException:
                    org.eclipse.persistence.indirection.IndirectSet
                    cannot be cast to java.util.TreeSet

                    Ok, the thing has something to do with the lazy
                    loading technology in EclipseLink/TopLink... if i
                    have an entity like this:

                    @Entity
                    class Entity {

                    @OneToMany (mappedBy = "entity",
                    fetch=FetchType.LAZY, cascade = {CascadeType.ALL})
                    private Set<Child> childrens = new TreeSet<Child>();

                    public void setChildrens(Set<Child> childrens) {
                    this.childrens = childrens }

                    public Set<Child> getChildrens() { return
                    this.childrens }

                    public Child getNextChild() {
                    return this. childrens.size() > 0 ?
                    ((TreeSet<Child>) this. childrens).last() : null;
                    }
                    ...
                    }

                    If I now find all entities of Entity and call
                    getNextChild(), I will get the error. It seems
                    that EclipseLink will pass a IndirectSet object
                    into my childrens set and then I can not cast it
                    anymore. The indirect set handles somehow the
                    lazy load technique.... so what to do?

                    I tried this:
                    public void setChildrens(Set<Child> childrens) {
                    this.childrens = new TreeSet<Child>(childrens); }

                    but this does not work either. It seems, that
                    EclipseLink is using reflection to pass the
                    IndiretSet into my set property.

                    I my assumptions are correct, what is to do if
                    want to use lazy loading, a TreeSet (for sorting
                    purposes--see .last() above) and the Set property
                    of my Entity class interface should be remain
                    java.uti.Set?

                    Thank you for help!

                    Martin.



                _______________________________________________
                eclipselink-users mailing list
                eclipselink-users@xxxxxxxxxxx
                < A
                href="" class="moz-txt-link-rfc2396E" href="https://dev.eclipse.org/mailman/listinfo/eclipselink-users">"https://dev.eclipse.org/mailman/listinfo/eclipselink-users"
                target=_blank>https://dev.eclipse.org/mailman/listinfo/eclipselink-users
                <mailto:eclipselink-u%21%20%20%20sers@xxxxxxxxxxx>


            _______________________________________________
            eclipselink-users mailing list
            eclipselink-users@xxxxxxxxxxx
            <mailto:eclipselink-users@xxxxxxxxxxx>
            https://dev.eclipse.org/mailman/listinfo/eclipselink-users



        _______________________________________________
        eclipselink-users mailing list
        eclipselink-users@xxxxxxxxxxx
        <mailto:eclipselink-users@xxxxxxxxxxx>
        https://dev.eclipse.org/mailman/listinfo/eclipselink-users


    _______________________________________________
    eclipseli! nk-users mailing list
    eclipselink-users@xxxxxxxxxxx <mailto:eclipselink-users@xxxxxxxxxxx>
    https://dev.eclipse.org/mailman/listinfo/eclipselink-users


_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx <mailto:eclipselink-users@xxxxxxxxxxx>
https://dev.eclipse.org/mailman/listinfo/eclipselink-users
      
------------------------------------------------------------------------

_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users
  
    

------------------------------

_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users


End of eclipselink-users Digest, Vol 28, Issue 9
************************************************
  

--
Oracle
Reinhard Girstenbrei | Senior Principal Technical Support Engineer
Phone: +498914302318 | Mobile: +491775941318
Oracle Oracle Customer Service

ORACLE Deutschland GmbH | Riesstr. 25 | 80992 München


ORACLE Deutschland GmbH, Hauptverwaltung: Riesstraße 25, D-80992 München
Geschäftsführer: Jürgen Kunz, Registergericht: Amtsgericht München, HRB 82775
Green Oracle Oracle is committed to developing practices and products that help protect the environment

Back to the top