users@glassfish.java.net

TopLink: Order of entities in collection?

From: <glassfish_at_javadesktop.org>
Date: Tue, 10 Apr 2007 18:12:25 PDT

I need some help in understanding the behavior of insert/persist when a collection containing multiple new entities is persisted to database.

Please refer to following code:

@Entity
public class TestPerson implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    String name;
    @OneToMany(cascade=CascadeType.ALL, mappedBy="testPerson")
    @OrderBy
    List<TestAddress> addresses;

    <<<< getters & setters >>>
}

@Entity
public class TestAddress implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    String zipCode;
    TestPerson testPerson;

    <<< getters & setters >>>
}

Consider the following code:

    em.getTransaction().begin();
        try {
            for (int k=0; k<10; k++) {
                TestPerson p = new TestPerson();
                p.setName("Name"+k);
                p.setTestAddresses(new ArrayList<TestAddress>());

                for (int i=0; i<10; i++) {
                    TestAddress a1 = new TestAddress();
                    a1.setZipCode(p.getName()+":Add"+i);
                    a1.setTestPerson(p);
                    p.getTestAddresses().add(a1);
                }
                em.persist(p);
            }
            em.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            em.getTransaction().rollback();
        }

When I use the above code to create new entities, addresses are saved in random order in the database, i.e., the generated primary key is not relevant to the order of address in the original list. The effect is that they dont appear in the same order when I retrieve TestPerson later. The OrderBy annotation is useless.

One workaround is to move the em.persist(p) call immediately after creation of TestPerson and the do a em.flush() every time after adding new TestAddress to the collection. Athough this works, it does not seem practical as it is very easy to not do it real code.

Also, I noticed that if I move the perisist() call before the for loop and not do a flush(), there is a chance that addresses wont event get created. I am not sure why this is happenning.

Question:
- Does Persistence spec define the order in which the entities are saved?
- Is TopLink configurable so that it follows the order in the list?
- Any other mechanim/design pattern/best practice to save and restore orderred entity collection in database?

Thanks in advance,

Pramod.
[Message sent by forum member 'pramod_patel' (pramod_patel)]

http://forums.java.net/jive/thread.jspa?messageID=211791