【问题标题】:What is the relation between Spring Entity Manager and Spring Data Repository?Spring Entity Manager 和 Spring Data Repository 之间有什么关系?
【发布时间】:2018-12-02 18:23:36
【问题描述】:

最近我看到一篇关于如何使用 spring 存储库对数据库执行批处理操作的有趣文章 - http://knes1.github.io/blog/2015/2015-10-19-streaming-mysql-results-using-java8-streams-and-spring-data.html,并且我已经实现了 Solution Using Paging

一切正常,但我不明白清除 entitymanager 会如何影响批处理期间数据库上可能发生的其他操作。

  • Spring Entity Manager 和 Spring Data Repository 有什么关系?如果我对 Spring Data Repository 执行操作,为什么清除 Spring Entity Manager 会影响已用内存?
  • 清除 Spring Entity Manager 会如何影响批处理过程中可能发生的其他读/写操作?
  • 如何创建 Spring Entity Manager 和 Spring Data Repository 的专用实例?现在我正在使用基本的自动装配
@PersistenceContext
private EntityManager entityManager;
@Autowired
private MyRepository myRepository;
  • 为批处理创建单独的 Spring Entity Manager 和 Spring Data Repository 实例是否有意义?

感谢您的帮助

【问题讨论】:

    标签: spring-data-jpa


    【解决方案1】:

    Spring Entity Manager 和 Spring Data Repository 有什么关系?如果我对 Spring Data Repository 执行操作,为什么清除 Spring Entity Manager 会影响已用内存?

    Spring Data JpaRepository 引用了 EntityManager 并使用它来实现其方法。 对于构成JpaRepository 的固定方法,您可以在SimpleRepository 中找到实现

    清除EntityManager [如何] 影响批处理期间可能发生的其他读/写操作?

    EntityManager 是一个 JPA 构造。所有托管引用都连接到一个EntityManager。这是为了让 JPA 实现了解实体何时被修改,因此需要在下一次刷新事件时保存。为了做到这一点,EntityManager 必须跟踪它遇到的所有实体。对于典型的 Web 应用程序,这意味着:

    • 您加载了一些实体。
    • 修改它们。
    • 可能会添加或删除一些实体
    • 刷新批次并在请求结束时关闭EntityManager

    由于只涉及几个实体,因此持有对所有实体的引用并不是什么大问题。

    在批处理设置中,事情通常会完全不同。 没有特别的想法,很自然的事情是:

    1. 您加载了一些实体。
    2. 修改它们。
    3. 可能会添加或删除一些实体。
    4. 重复数千或数百万次。
    5. 在批次结束时刷新批次并关闭EntityManager

    因此,您保留了对实体的数千甚至数百万个引用,这些引用在许多情况下将不再被触及。 当EntityManager 访问其实体引用列表时,这会给内存带来压力并影响性能。 这样的操作是:

    • 检查每个已加载和持久化的实体是否已在 EntityManager 中引用
    • 在刷新事件期间检查哪些实体需要保存,并使所有语句以正确的顺序执行。

    EntityManager 及其一级缓存(它保存的实体映射)也有好处:实体只加载一次。 如果您的批次一遍又一遍地引用一些已经存在的实体(典型的“主数据”),它不会一遍又一遍地加载,而是每个EntityManager 加载一次。 因此,您可能也不想在处理完每个行后刷新您的 EntityManager

    如何创建 Spring Entity Manager 和 Spring Data Repository 的专用实例?现在我正在使用基本的自动接线。

    你没有。 有多种方法可以创建专用实例。 毕竟,它只是 Java 代码。 但你真的不想那样做。 相反,只需使用按类型生成的 sing 存储库实例。 它为EntityManager 注入了一个代理。 实际的EntityManager 将用于事务。 并在上述代理内的事务开始时进行交换。 这是 Spring Scope Magic 的一部分。

    您需要做的是用@Transactional 注释您的方法,以使事务保持在合理的大小范围内。

    为批处理创建单独的 Spring Entity Manager 和 Spring Data Repository 实例是否有意义?

    不,我不这么认为。 它只会让事情变得复杂。

    【讨论】:

      猜你喜欢
      • 2013-01-15
      • 2018-10-07
      • 2021-12-22
      • 1970-01-01
      • 1970-01-01
      • 2011-02-28
      • 2020-03-06
      • 2018-10-19
      • 2014-08-17
      相关资源
      最近更新 更多