为什么在Spring Data JPA Repository上的save()之后使用返回的实例? [英] Why use returned instance after save() on Spring Data JPA Repository?

查看:5683
本文介绍了为什么在Spring Data JPA Repository上的save()之后使用返回的实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是代码:

@Repository
public interface AccountRepository extends JpaRepository<Account, Long> {}

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:

Here is from CrudReporsitory.save() javadoc:


保存给定实体。使用返回的实例进行进一步操作,因为save操作可能已完全更改了实体实例。

Saves a given entity. Use the returned instance for further operations as the save operation might have changed the entity instance completely.

以下是来自Spring Data JPA的SimpleJpaRepository的实际代码:

Here is the actual code for SimpleJpaRepository from Spring Data JPA:

 @Transactional
    public T save(T entity) { 
            if (entityInformation.isNew(entity)) {
                    em.persist(entity);
                    return entity;
            } else {
                    return em.merge(entity);
            }
    }

所以,问题是为什么我们需要使用返回的实例而不是原始实例? (是的,我们必须这样做,否则我们继续使用分离的实例,但为什么)

So, the question is why do we need to use the returned instance instead of the original one? (yes, we must do it, otherwise we continue to work with detached instance, but why)

原始的EntityManager.persist()方法返回void,所以我们的实例是附加到持久化上下文。通过帐户保存到存储库时是否会发生一些代理魔术?它是Spring Data JPA项目的体系结构限制吗?

The original EntityManager.persist() method returns void, so our instance is attached to the persistence context. Does some proxy magic happens while passing account to save to repository? Is it the architecture limitation of Spring Data JPA project?

推荐答案

save(...) CrudRepository 接口的方法应该抽象简单地存储一个实体,无论它处于什么状态。因此它不能暴露实际的商店特定实现,甚至如果(如在JPA中)情况,商店区分要存储的新实体和要更新的现有实体。这就是为什么该方法实际上被称为 save(...)而不是 create(...)更新(...)。我们从该方法返回一个结果,实际上允许商店实现返回一个完全不同的实例,因为当调用 merge(...)时,JPA可能会这样做。

The save(…) method of the CrudRepository interface is supposed to abstract simply storing an entity no matter what state it is in. Thus it must not expose the actual store specific implementation, even if (as in the JPA) case the store differentiates between new entities to be stored and existing ones to be updated. That's why the method is actually called save(…) not create(…) or update(…). We return a result from that method to actually allow the store implementation to return a completely different instance as JPA potentially does when merge(…) gets invoked.

因此,一般而言,更多的API决定是对实际实现宽松,从而像我们一样实现JPA的方法。没有对传递的实体进行额外的代理按摩。

So generally it's more of an API decision to be lenient regarding the actual implementation and thus implementing the method for JPA as we do. There's no additional proxy massaging done to the entities passed.

这篇关于为什么在Spring Data JPA Repository上的save()之后使用返回的实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆