Вот код:
@Repository
public interface AccountRepository extends JpaRepository<Account, Long> {}
JpaRepository из проекта JPA Spring Data.
Вот код тестирования:
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());
}
}
Вот результат:
account ID is 0 and for returned account ID is 1
Вот из javadoc CrudReporsitory.save ():
Сохраняет данную сущность. Используйте возвращенный экземпляр для дальнейших операций, поскольку операция сохранения могла полностью изменить экземпляр объекта.
Вот фактический код для SimpleJpaRepository из Spring Data JPA:
@Transactional
public T save(T entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
Итак, вопрос в том, почему нам нужно использовать возвращенный экземпляр вместо исходного? (да, мы должны это сделать, в противном случае мы продолжаем работать с отдельным экземпляром, но почему)
Исходный метод EntityManager.persist () возвращает void, поэтому наш экземпляр подключен к контексту постоянства. Происходит ли какое-нибудь волшебство прокси при передаче аккаунта для сохранения в хранилище? Это ограничение архитектуры проекта Spring Data JPA?