当前位置: 首页 > 面试题库 >

为什么在Spring Data JPA Repository上的save()之后使用返回的实例?

连成益
2023-03-14
问题内容

这是代码:

@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项目的架构限制吗?


问题答案:

该接口的save(…)方法CrudRepository应该抽象为简单地存储一个实体,而不管它处于什么状态。因此,即使该存储区(如在JPA中一样)区分要存储的新实体,也不能公开实际的特定于存储区的实现。和现有的要更新。这就是为什么该方法实际上称为save(…)not create(…)update(…)。我们从该方法返回一个结果,以实际上允许商店实现返回一个完全不同的实例,就像JPA在merge(…)被调用时可能返回的那样。

因此,一般来说,对于实际实施要宽容(允许,宽容)更多是API决定,因此像我们所做的那样实施JPA方法。对传递的实体没有其他的代理消息传递。



 类似资料:
  • 问题内容: 考虑一下这个功能: 有人可以解释一下为什么L1和L2显然无法到达时没有给出警告,而L3却给出了警告。 问题答案: 因为就编译器而言,这只是另一个方法调用。 它所做的是结束过程这一事实只能从实现中找到(这是本机代码,而没有任何区别)。 如果你必须把你的代码(通常也最好避免它,除非你想返回0以外的代码),它应该是一个方法,返回,例如。这样更好。 关于可达性,解释是相同的:是Java语言的关

  • 问题内容: 在装有NVidia GeForce 820M的Windows 10 PC上,我成功安装了CUDA 9.2和cudnn 7.1,然后按照pytorch.org上的说明安装了PyTorch。 具体来说我使用了命令 因为我使用点子而不是Anaconda。 然而我得到以下 为什么会这样呢? 问题答案: 您的图形卡不支持CUDA 9.0。 由于我已经看到很多涉及此类问题的问题,因此我就如何检查您

  • 在我的Web应用中,在服务布局中,我对“餐厅”实体使用代理(在“餐厅”字段上使用fetchtype.lazy)。 “get()”进入存储库:

  • 一旦服务器启动,我就会收到这个错误,错误显示log4j2。找不到xml, 下面是log4j2。已配置的xml。 因此,我将log4j2中的级别更改为trace。并在控制台中获取以下日志。 我们的是一个具有多个EJB和WAR文件的EJB应用程序。log4j2。xml驻留在自定义配置路径中,通过在代码中设置以下属性来读取它 System.set属性("log4j.configuration文件","/

  • 通过下面的代码片段,我试图运行一个查询,该查询更新数据或将新数据插入名为的表中。该表包含一个名为和的列。如果中已经有一个节点,则更新中以毫秒为单位的时间。否则,将插入新的信息。 问题是,下面的代码片段无法将数据插入到数据库的表中。原因是声明: 那么应该如何编辑代码,以便更新重复值并插入新值呢?

  • 如果我们假设有如下所示的XML,那么match=“/”究竟返回什么?据我所知,它返回了一个虚构的顶级节点,它具有<代码> 测验xml