복붙노트

[SPRING] Spring Data JPA Repository에서 save () 후에 반환 된 인스턴스를 사용해야하는 이유는 무엇입니까?

SPRING

Spring Data JPA Repository에서 save () 후에 반환 된 인스턴스를 사용해야하는 이유는 무엇입니까?

다음은 코드입니다.

@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

CrudReporsitory.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 프로젝트의 아키텍처 제한 사항입니까?

해결법

  1. ==============================

    1.CrudRepository 인터페이스의 save (...) 메소드는 그것이 어떤 상태인지에 상관없이 단순히 엔티티를 저장하는 것으로 가정된다. 따라서 (JPA와 같이) 스토어가 차별화된다하더라도 실제 상점 특정 구현을 노출해서는 안된다. 새로운 엔티티는 저장되고 기존 엔티티는 업데이트됩니다. 이것이 메소드가 실제로 save (...)가 아닌 (...) 또는 update (...)가 아닌 이유입니다. 이 메소드의 결과를 반환하면 병합 (...) 호출시 JPA가 잠재적으로 수행하는 것과 완전히 다른 인스턴스를 저장소 구현에서 실제로 반환 할 수 있습니다.

    CrudRepository 인터페이스의 save (...) 메소드는 그것이 어떤 상태인지에 상관없이 단순히 엔티티를 저장하는 것으로 가정된다. 따라서 (JPA와 같이) 스토어가 차별화된다하더라도 실제 상점 특정 구현을 노출해서는 안된다. 새로운 엔티티는 저장되고 기존 엔티티는 업데이트됩니다. 이것이 메소드가 실제로 save (...)가 아닌 (...) 또는 update (...)가 아닌 이유입니다. 이 메소드의 결과를 반환하면 병합 (...) 호출시 JPA가 잠재적으로 수행하는 것과 완전히 다른 인스턴스를 저장소 구현에서 실제로 반환 할 수 있습니다.

    따라서 실제 구현과 관련하여 관대 한 방법으로 JPA에 대한 방법을 구현하는 것은 API 결정에 더 가깝습니다. 전달 된 엔티티에 대해 수행 된 추가 프록시 마샬 러는 없습니다.

  2. ==============================

    2.두 번째 부분을 놓쳤습니다. 엔티티가 새 것이 아니라면 병합이 호출됩니다. merge는 인수의 상태를 동일한 ID로 연결된 엔터티에 복사하고 첨부 된 엔터티를 반환합니다. 엔티티가 새롭지 않고 반환 된 엔티티를 사용하지 않으면 분리 된 엔티티를 수정하게됩니다.

    두 번째 부분을 놓쳤습니다. 엔티티가 새 것이 아니라면 병합이 호출됩니다. merge는 인수의 상태를 동일한 ID로 연결된 엔터티에 복사하고 첨부 된 엔터티를 반환합니다. 엔티티가 새롭지 않고 반환 된 엔티티를 사용하지 않으면 분리 된 엔티티를 수정하게됩니다.

  3. from https://stackoverflow.com/questions/8625150/why-use-returned-instance-after-save-on-spring-data-jpa-repository by cc-by-sa and MIT license