Be careful, when you are using CrudReporsitory.save() in JPA
in some JPA project, CrudReporsitory.save() is used this way:
1 |
repository.save(oldtEntity) |
sometime the oldEntity will be set with new properties, but sometimes you will find that the new assigned ID has not been set to the oldEntity.
Why?
Here is the actual code for SimpleJpaRepository from Spring Data JPA:
1 2 3 4 5 6 7 8 9 |
@Transactional public T save(T entity) { if (entityInformation.isNew(entity)) { em.persist(entity); return entity; } else { return em.merge(entity); } } |
The save(…)
method of the CrudRepository
interface is supposed to abstract simply storing an entity no matter what state it is in. Thus it must not expose the actual store specific implementation, even if (as in the JPA) case the store differentiates between new entities to be stored and existing ones to be updated.
We return a result from that method to actually allow the store implementation to return a completely different instance as JPA potentially does when merge(…)
gets invoked.
If the entity isn’t new, merge
is called. merge
copies the state of its argument into the attached entity with the same ID, and returns the attached entity. If the entity isn’t new, and you don’t use the returned entity, you’ll make modifications to a detached entity.
So the right way is:
1 |
oldtEntity = repository.save(oldtEntity); |
Reference:
https://stackoverflow.com/questions/16351156/spring-data-jpa-save-can-not-get-id
https://stackoverflow.com/questions/8625150/why-use-returned-instance-after-save-on-spring-data-jpa-repository