コードは次のとおりです。
@Repository
public interface AccountRepository extends JpaRepository<Account, Long> {}
Spring Data JPA プロジェクトのJpaRepository 。
テストコードは次のとおりです。
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
これは CrudReporitory.save() javadoc からのものです。
特定のエンティティを保存します。保存操作によってエンティティ インスタンスが完全に変更された可能性があるため、返されたインスタンスを以降の操作に使用します。
Spring Data JPA の SimpleJpaRepository の実際のコードは次のとおりです。
@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 プロジェクトのアーキテクチャ制限ですか?