Oto kod:Dlaczego warto używać zwróconej instancji po save() w repozytorium JPA Spring Data?
@Repository
public interface AccountRepository extends JpaRepository<Account, Long> {}
JpaRepository od projektu Wiosna danych WZP.
Oto kod badania:
public class JpaAccountRepositoryTest extends JpaRepositoryTest {
@Inject
private AccountRepository accountRepository;
@Inject
private Account account;
@Test
@Transactional
public void createAccount() {
Account returnedAccount = accountRepository.save(account);
System.out.printf("account ID is %d and for returned account ID is %d\n", account.getId(), returnedAccount.getId());
}
}
Oto wynik:
account ID is 0 and for returned account ID is 1
Oto z CrudReporsitory.save() javadoc:
Zapisuje danego podmiotu. Użyj zwróconej instancji do dalszych operacji, ponieważ operacja składowania mogła całkowicie zmienić instancję jednostki.
Oto kod rzeczywisty dla SimpleJpaRepository od wiosny Danych JPA:
@Transactional
public T save(T entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
Więc pytanie jest dlaczego musimy użyć wracającą instancji zamiast pierwotnego? (tak, musimy to zrobić, w przeciwnym razie kontynuujemy pracę z odłączoną instancją, ale dlaczego)
Oryginalna metoda EntityManager.persist() zwraca pustkę, więc nasza instancja jest dołączona do kontekstu utrwalania. Czy podczas przechodzenia przez konto do zapisania w repozytorium pojawia się jakaś magia proxy? Czy jest to ograniczenie architektury projektu Spring Data JPA?
Czy mogę założyć, że nie można użyć wyników zwrotu dla nowych podmiotów? – danidacar
Gdzie jest dokumentacja dotycząca stanu zwróconego obiektu? Oznacza to, że czasami zwraca zaktualizowane pola (znaczniki czasu), czasami pola nie są aktualizowane z bazy danych. – mmcrae