2

Short version: Is there a way to tell JPA to ignore null properties of a detached entity instance when merging?

Long version:

I Have the following scenario:

Web Application communicates through HTTP REST with Backend. Backend uses JAX-B, JAX-RS, EJBs and JPA2.0 (EclipseLink). Application functionality is basically CRUD.

Because of this design, all entities received through JAX-RS are detached entities, causing JPA to replace all attributes and relationships (if a relationship is null when received, JPA deletes the relationship in the database)

The idea is, having a @OneToMany unidirectional aggregation relationship between A and B A<>---B (this creates a join table), I want to modify attributes owned by A, keeping it's references to B unmodified. In order to do this I'm doing the following:

  1. Fetching A through JAX-RS, with all it's attributes and references.
  2. Modifying record in web application.
  3. Sending new values through JAX-RS.
  4. Merging new deserialized entity (in a detached state).

The issue is, as the application grows, A get new relationships and data transfered will keep growing with it (and not being required for A's CRUD operations.

I'm aware that a solution would be to fetch from database the unmodified record and merge it in code, but I'm looking for a solution that avoids this extra database query.

Andrés Esguerra
  • 849
  • 5
  • 15
  • Calling find before hand will not affect the number of queries unless it is a new entity, as JPA merge will query for the entity to perform the merge anyway. If it is already in the cache, it doesn't need to query for it and will just return it. – Chris Sep 17 '15 at 12:23
  • I forgot to mention cache is disabled and enabling it is not an option in this case. – Andrés Esguerra Dec 14 '15 at 22:38
  • JPA will use a query when you call merge if it isn't already in the context's cache - its list of managed entities. Hence calling em.find beforehand will not change the number of queries if you are using the same EntityManager context - you are just loading it before JPA does so that JPA doesn't have to. You could even make it more efficient by gathering a list of primary keys and load them with a single query. Then you can custom merge, ignoring your null values. But JPA is required to merge your entity as is overtop what was there, null and all. – Chris Dec 15 '15 at 14:41

1 Answers1

0

If you queried for A with JPA for that entity in the GET request it should be in L2 cache thus using a find operation on it should hit the cache. Then it is a simple case or merging over the changed values.

If you still want to simply merge A without the merge cascading to B you can mark the entity relationship so that it doesn't cascade on merge.

@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy = "aEntity")