如果使用 Spring Data Repositories (Spring 4),如何从持久性上下文中分离实体

Posted

技术标签:

【中文标题】如果使用 Spring Data Repositories (Spring 4),如何从持久性上下文中分离实体【英文标题】:How to detach entity from persistence context, if using Spring Data Repositories (Spring 4) 【发布时间】:2016-10-13 16:33:37 【问题描述】:

我需要在 spring-boot 应用程序中从持久性上下文中分离一个实体。

我有以下基础存储库:

interface EntityRepository extends CrudRepository<Entity, Long> 

显然这不提供任何detach(..)-操作。 我找到了一个答案,这实际上对我不起作用: SO Post.

我尝试了同样的方法,但似乎我的实体没有分离(好像我更改了任何字段,它仍然保持不变)

自定义回购:

interface MyCustomEntityRepository 
  void detach(Entity ent)

接口实现:

class MyCustomEntityRepositoryImpl implements MyCustomEntityRepository
     @PersistenceContext
     private EntityManager em;

     public void detach(Entity ent) 
         em.detach(ent);
     

但我不能用MyCustomEntityReposity 扩展EntityRepository,因为这会导致:

No property detach found for type Entity! 通过不扩展 EntityRepository,我设法让它编译没有错误。还将CrudRepository 更改为JpaRepository 但是我的实体仍然没有脱离,但在链接的帖子中,QA 说它正在为他/她工作。 分离对象的实际原因是能够在 @EntityListener 中执行一些验证,方法是检查 db 中当前存储的实体以及当前更改的实体实例,该实例应该被分离。

有没有人看到一些错误或给我一个线索,我做错了什么?

使用:Spring-boot(1.4.0-release)、Spring 4、JPA

【问题讨论】:

这是一次性要求还是您希望应用程序中的所有实体都使用此功能? 我只需要一个实体,但也对一般方法感兴趣 如果它仅用于单个实体,只需将 EntityManager 自动连接为 @PersistenceContext EntityManager entityManager;,您可以在其中自动连接存储库,然后您可以将实体实例分离为 entityManager.detach(entity)。这不需要任何自定义编码,因此很容易。如果您对所有实体都需要此功能,请参阅 the official documentation 了解 JPA 存储库的自定义行为。您可以扩展 CrudRepository 以在存储库中包含 detach 方法。 我实际上做了你在最后一句话中提到的事情,但是 spring 声称:Error creating bean with name 'entityRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property detach found for type Entity 您没有为所有存储库引入自定义行为,而只是为一个存储库(来自您的代码)引入了自定义行为。向所有存储库添加行为需要一个从CrudRepositoryPagingAndSortingRepositoryJpaRepository 扩展的接口、一个扩展SimpleJpaRepository 并实现自定义接口的存储库类和一个可以创建自定义存储库类实例的工厂bean。请参阅我链接到的文档中的确切部分。 【参考方案1】:

有没有人看到一些错误或给我一个线索,我做错了什么?

虽然很难说,什么可能是您实际问题的一部分,什么只是草率的问题编辑。

    你的界面没有编译

    interface MyCustomEntityRepository 
       detach(Entity ent)
    
    

    应该是

    interface MyCustomEntityRepository 
       void detach(Entity ent)
    
    

    您的自定义接口的实现应该实现该接口:

    class MyCustomEntityRepositoryImpl 
    

    应该是

    class MyCustomEntityRepositoryImpl implements MyCustomEntityRepository 
    

如果问题仍然存在,请显示您正在使用的实际代码以及实际异常,包括堆栈跟踪。

【讨论】:

抱歉回复晚了。是的,代码中的错误是由于草率的问题编辑而发生的。我可以通过完全不使用分离来解决它,而是解析另一个实体实例上的修改,并能够对两个单独的实体实例进行验证。几天后我将再次尝试,以通过实体侦听器和分离实现相同的效果,因为我对自己感兴趣。然后我会在这里回复。抱歉耽搁了

以上是关于如果使用 Spring Data Repositories (Spring 4),如何从持久性上下文中分离实体的主要内容,如果未能解决你的问题,请参考以下文章

Spring之泛型依赖注入

Spring注解相关

如果使用 Spring Data Repositories (Spring 4),如何从持久性上下文中分离实体

Spring源码解读——源码下载及编译

Spring Data 错误:“HHH000389 不成功:如果存在则删除表”

Spring Data Jpa