codememo

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

tipmemo 2023. 9. 10. 12:19
반응형

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

다음은 CrudReportsitory.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);
            }
    }

그렇다면 문제는 왜 원래 인스턴스 대신 반환된 인스턴스를 사용해야 하느냐는 것입니다.(네, 반드시 실행해야 합니다. 그렇지 않으면 분리된 인스턴스를 계속 사용할 수 있습니다. 하지만 그 이유는 무엇입니까?)

원래 엔티티 관리자입니다.persistance 메서드는 void를 반환하므로 인스턴스가 persistence 컨텍스트에 연결됩니다.저장소에 저장하기 위해 계정을 전달하는 동안 프록시 마법이 발생합니까?Spring Data JPA 프로젝트의 아키텍처 제한인가요?

save(…)의 방법CrudRepository인터페이스는 어떤 상태에 있든지 간에 단순히 엔티티를 저장하는 것을 추상화하도록 되어있습니다.따라서 (JPA의 경우와 같이) 스토어가 저장될 새 엔티티와 업데이트될 기존 엔티티 사이를 구분하더라도 실제 스토어별 구현을 노출해서는 안 됩니다.그래서 그 방법이 실제로 불리는 것입니다.save(…)것은 아니다.create(…)아니면update(…). 우리는 JPA가 잠재적으로 다음과 같이 스토어 구현이 완전히 다른 인스턴스를 반환할 수 있도록 실제로 허용하기 위해 이 방법의 결과를 반환합니다.merge(…)호출됩니다.

또한 실제 구현에서 식별자 등을 입력해야 하는 경우 (즉, JPA가 아닌) 불변 객체를 실제로 처리할 수 있는 지속성 구현은 새로운 인스턴스를 반환해야 할 수도 있습니다.즉, 구현이 단지 엔티티 상태를 소비할 것이라고 가정하는 것은 일반적으로 잘못된 것입니다.

따라서 일반적으로 실제 구현에 대해 관대한(허용, 관용) 것이 API 결정에 가깝습니다. 따라서 JPA에 대한 방법을 우리가 하는 것처럼 구현하는 것입니다.전달된 개체에 대한 추가 프록시 마사지가 없습니다.

두 번째 파트를 놓쳤군요. 만약 새로운 개체가 아니라면,merge라고 합니다.merge는 인수의 상태를 동일한 ID의 첨부 엔티티로 복사하고, 첨부 엔티티를 반환합니다.새로운 개체가 아니고 반환된 개체를 사용하지 않는 경우 분리된 개체를 수정합니다.

언급URL : https://stackoverflow.com/questions/8625150/why-use-returned-instance-after-save-on-spring-data-jpa-repository

반응형