1

just noticed something interesting here. If I run the following piece of code, by calling the flush only at the end of the list, JPA appears to be inserting the objects in random order into the database. The reason I can tell is because I have the database to create the identity column. And the object sequence id doesn't correspond to the order of the identity column.

public void persistList(List<Object> objectList) {
for (Object object : objectList) {
    em.persist(object);
}        
    em.flush()
}

However, if I run the following code it works. All I did is added the em.flush() at immediately after each em.persist(). Has anyone run into this issue before?

public void persistList(List<Object> objectList) {
for (Object object : objectList) {
    em.persist(object);
    em.flush();


  }        

}

for example, objectList has object1,objec2,object3. So theoretically, the sequence inserted to database should be object1,then object2, then object3. However, sometimes it doesn't.

keisd
  • 59
  • 6

1 Answers1

3

When you call em.persist() you're telling JPA to make sure the entity will be persisted when the time is right. The time is right if you call flush(), the transaction is committed or other possible reasons the JPA implementation might have.

The spec doesn't give any guarantees about the order, so the implementation is free to do what it wants as long as the entity is persisted in the end.

This allows JPA to optimized the communication with the database, and perform a lot of other things too before the data goes to the database level (and even then you have a transaction open that can be rolled back).

I don't understand what you mean by "the object sequence id doesn't correspond to the order of the identity column", but it sounds like you should refactor your code so it doesn't rely on JPA insertion order.

If you're using Hibernate you could try enabling the order_inserts property and see if it'll fix your issue. I would consider this a design issue though, since if you want explicit values you should explicitly code that way. Now you're generating ids in different places and complaining about getting "wrong" ones.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • so how can i ensure the sequence is correct? excepting put em.flush() inside the for loop because i will cause some performance issue – keisd May 14 '18 at 06:49
  • i am not using hibernate – keisd May 14 '18 at 07:00
  • Well, then you can either see if the implentation you're using (which should really be tagged, as the single `java` tag doesn't tell much) has a similar property for ordering inserts, or it's time to start thinking about how you'll be refactoring your id generation to make it efficient and correct. – Kayaman May 14 '18 at 07:02