2

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?

markdsievers
  • 7,151
  • 11
  • 51
  • 83

1 Answers1

2

Caching.

Didn't realise EclipseLink had caching behavior beyond transactions by default.

Running a test without having that object pass through JPA shows the expected selects being run to determine what needs to be updated / inserted.

markdsievers
  • 7,151
  • 11
  • 51
  • 83