Prim
Prim

Reputation: 1364

Hibernate Batch Update

I am trying to update a collection of a Java entity, but the order in which Hibernate executes the batch update leads to a constraint violation exception. I will use the following example to explain the situation.

Entity Student Int id String Name String deskID

Rule: 2 students cannot have the same desk

1st transaction: Insert 2 students as follows Student 1 Id:1 Name:ABC DeskId:D1

Student 2 Id:2 Name:DEF DeskId: D2

Now after this I decide to update both the student entities to swap their desks and I send a collection of updated student entities to hibernate update Student 1 Id:1 Name:ABC DeskId:D2

Student 2 Id:2 Name:DEF DeskId: D1

But this leads to constraint violation exception because i think the update is taking place one record at a time.

I am using JTA entity managers to manage the transactions. My code to update looks something like this

updateMultiple(Collection<Student> updatedStudents)
        for (final Student student: updatedStudents)
        {
            final Student st= this.entityManager.getReference(Student.class, Student.getId());
            student.merge(st);
        }
        this.entityManager.flush();
        return breakClauseDtos;

Upvotes: 0

Views: 481

Answers (1)

Johanna
Johanna

Reputation: 5293

The source of your problem is clear: The database checks the constraints when the SQL statement is executed and not at commit time. When executing the first SQL statement the constraint is violated.

You can go around the problem when you remove the desk from student 1 first, then assign it to student 2, then give student 1 his desc. This means three SQL statements (one more than necessary), and then perhaps you have to flush the session after every update (Hibernate reorders SQL statements, which can interfere with your manual order).

But the better solution is correcting the issue in your data model.

If every desk can be owned by only one student, then there is a n:1 relation from desk to student. Desk needs the id of the student as a foreign key. No extra constraint need to be defined. Now changing the desk means changing the student id in the desk record. This can be done with only two update statements.

Upvotes: 1

Related Questions