Reputation: 740
In this code I am saving the main object and a foreign key of that object. I print out "entity" and "thing" which should be the exact same object. But they aren't. Why?
thingList.forEach(entity -> {
System.out.println(entity);
// Save if the foreign key exists and isn't already saved in the database
if(entity.ForeignKey() != null && ForeignKeyRepository.findOne(entity.ForeignKey().getId()) == null)
{
ForeignKeyRepository.save(entity.getForeignKey());
}
Thing thing = thingRepository.save(entity);
System.out.println(thing);
});
Upvotes: 4
Views: 9515
Reputation: 81990
If the entity is not new and there is already a different instance representing the database row in the session of the EntityManager
you get that instance, modified to match the one passed as an argument, as the return value.
You can confirm this by inspecting the implementation and the relevant JPA documentation.
The save
method is implemented in SimpleJpaRepository
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
em
is the EntityManager
. From it's merge
methods documentation:
Returns: the managed instance that the state was merged to
The JPA specification section 3.2.7.1 is a little more explicit:
• If X is a detached entity, the state of X is copied onto a pre-existing managed entity instance X' of the same identity or a new managed copy X' of X is created.
• If X is a new entity instance, a new managed entity instance X' is created and the state of X is copied into the new managed entity instance X'.
• If X is a removed entity instance, an IllegalArgumentException will be thrown by the merge operation (or the transaction commit will fail).
• If X is a managed entity, it is ignored by the merge operation, however, the merge operation is cascaded to entities referenced by relationships from X if these relationships have been annotated with the cascade element value cascade=MERGE or cascade=ALL annotation.
Upvotes: 6
Reputation: 479
That is what excepted as they mention in the doc of the save method
S save(S entity) : Saves a given entity. Use the returned instance for further operations as the save operation might have changed the entity instance completely.
Upvotes: 0