I'm having problems when saving entities in my DB.
I have something like (very simplified) :
@Entity
public class Building {
@OneToMany(mappedBy = "building", fetch = FetchType.EAGER)
private List<Employee> employees;
}
@Entity
public class Employee {
@NotNull
@ManyToOne
@JoinFetch(INNER)
@JoinColumn
private Building building;
@PostLoad
private void onLoad(){
if (this.plannedOrder == null) {
//For old entities in this DB, update plannedOrder if null
if (this.order < FIRST.getCode()) {
this.plannedOrder = FIRST;
} else if (this.order >= FIRST.getCode() && this.order < SECOND.getCode()) {
this.plannedOrder = SECOND;
} else if (this.order >= DEFAULT.getCode() && this.order < SEC_LAST.getCode()) {
this.plannedOrder = DEFAULT;
} else if (this.order >= SEC_LAST.getCode() && this.order < LAST.getCode()) {
this.plannedOrder = SEC_LAST;
} else if (this.order >= LAST.getCode()) {
this.plannedOrder = LAST;
} else {
this.plannedOrder = DEFAULT;
}
}
}
The problem is when I save a Employee entity. In the Building entity you will have all employees modified because the @PostLoad annotation, so JPA will try to update these entities. However, I only want to update the Employee entity.
Is some way to do this without changing the relations in my model? Could be a solution to remove the onLoad function?
Thanks!
EDITED:
Added the PostLoad code of PostLoad. This is a fix executed for old entities in DB without this field to be updated when saved.
EDITED 2
And this is how I'm saving my entity Employee with my EntityManager (if is a new Object, persist, else update it)
if (entity.getId() == null) {
entityManager.persist(entity);
return entity;
}
return entityManager.merge(entity);
Just extending what Tobb answered a little: This is occurring because you are loading in an Employee with the merge call. This entity has a 1:1 relationship to building which defaults to be Eagerly fetched, forcing building to also be loaded.
Building then also has a 1:M to Employees, and you have marked this with fetch = FetchType.EAGER, forcing all employees to also be loaded.
If you do not want all employees loaded, thereby forcing JPA to call their postLoad methods, you need to prevent one or more of these relationships from being loaded. Options:
If you choose to use Lazy fetching, this can still be overridden on a query by query basis as required through fetch joins, query hints and or fetch/load groups.