I'm trying to figure out how EclipseLink determines what elements of a collection need to be inserted as part of a merge.
For example, this Entity:
@Entity(name = "subject")
@Table(name = "subject")
public final class Subject {
...
@ElementCollection(fetch = FetchType.EAGER)
private List<String> permissions = new ArrayList<String>();
and this update method for the Subject
public Subject update(Subject entity) {
EntityManager entityManager = provider.get();
entityManager.getTransaction().begin();
entityManager.merge(entity);
entityManager.getTransaction().commit();
return entity;
}
...I can see this behavior from postgresqls logs when I try and update it:
-- first, selecting the object I want
2013-12-10 03:48:19 GMT LOG: execute <unnamed>: SELECT id FROM subject WHERE (id = $1)
2013-12-10 03:48:19 GMT DETAIL: parameters: $1 = '567'
2013-12-10 03:48:19 GMT LOG: execute <unnamed>: SELECT t0.PERMISSIONS FROM subject_PERMISSIONS t0 WHERE (t0.subject_id = $1)
2013-12-10 03:48:19 GMT DETAIL: parameters: $1 = '567'
-- after calling merge, adding the new permission
2013-12-10 03:50:01 GMT LOG: execute S_1: BEGIN
2013-12-10 03:50:01 GMT LOG: execute <unnamed>: INSERT INTO subject_PERMISSIONS (subject_id, PERMISSIONS) VALUES ($1, $2)
2013-12-10 03:50:01 GMT DETAIL: parameters: $1 = '567', $2 = 'new:perm'
2013-12-10 03:50:01 GMT LOG: execute S_2: COMMIT
The select for subject
and permissions
occur when I first pull the object using the EntityManager
and I get a Subject
object back. This is fine but what I don't understand is when I then add"new:perm"
to that collection and use the merge
method, EclipseLink has somehow figured out that only the new perm needs to be inserted with no other information.
The Subject
object doesn't appear to be a proxy with any extra information in it and EclipseLink has not done any extra database query work to find out what permissions already exist in the database, so how has EclipseLink determined that only the permission I have just added needs to be inserted?