Skip to main content

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

Hi all,

ok, em.refresh() is doing the job. Now the test runs.

Ok, I was not aware of if the em is closed, the entities will not be read from DB by the next find call. Thank you for the tip.

Actually, I have a GenericDAO pattern and DO NOT close the em every time a find, create, update, etc. method was called.
So, I don't know actually why to close the em between the statements, just close it at application shutdown to free memory. (I do comit the transactions between calls). 
A lot of examples in books are the Internet are closing the em after every call, but this gave me detached entity errors... I don't know actually what is the best practice to handle this issue.

What are you thinking about this?

Thanks again!



Am 03.12.2009 um 14:25 schrieb christopher delahunt:

> 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="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
> 



Back to the top