【问题标题】:Spring Data JPA repository methods overloadingSpring Data JPA 存储库方法重载
【发布时间】:2017-08-20 04:50:38
【问题描述】:

例如,我有一本书 JpaRepository。 Book 有一个名为Name 的字段,book 存储库有一个方法findOneByName(作为 jpa 存储库方法命名约定)。但是我需要两个不同版本的findOneByName 才能在不同的用例中使用。一个版本是lock annotated,另一个是lock-free。像这样:

public interface BookRepository extends JpaRepository<BookDAO, Long> {

   @Lock(LockModeType.READ)
   BookDAO findOneByName( String name );

   BookDAO findOneByName( String name );
}

是否有可能在 Spring 中实现这一点?如果是,调用时如何区分这两种方法。如果没有,是否还有其他方法可以在仍然使用 Spring JPA 存储库接口(如 findOneBy***)的同时做到这一点。

【问题讨论】:

  • 我不会对其中之一使用查询方法。我将为@Lock 创建一个新方法,并将其命名为findOneByNameWithLock(name)。然后使用@Query 注解并为其指定查询。
  • 不,不是这样(与 Spring 无关,而是 Java 的工作原理)。
  • @M.Deinum 谢谢。你对这个用例有什么建设性的建议吗?如何以另一种方式做到这一点?
  • 查看@LucasP 的评论。

标签: spring hibernate orm spring-data-jpa


【解决方案1】:

根据reference,我们可以使用以下前缀命名查询方法:find…Byread…Byquery…Bycount…Byget…By

所以BookDAO findByName(String name)BookDAO getByName(String name) 方法会做同样的事情。

【讨论】:

    【解决方案2】:

    我不知道是否可以按照您的方式完成。但我会创建不同的方法

     public interface BookRepository extends JpaRepository<BookDAO, Long> {
    
       @Lock(LockModeType.READ)
       @Query("select b from Book b where b.name = :name")
       BookDAO findOneByNameForRead( String name );
    
       BookDAO findOneByName( String name );
    
    }
    

    或者您可以在服务层中创建方法,而不是使用 spring jparepository 来处理锁定。并在需要更新的地方使用它,所有读取方法都标记为@Transactional(readOnly = true)

    @PersistenceContext
    private EntityManager em;
    ...
    
    public  Book findOneBookForUpdate(String id) {
    
        Book book = em.find(Book.class, id);
        if (book != null) {
            em.lock(book, LockModeType.PESSIMISTIC_WRITE);
        }
    
        return book;
    }
    

    【讨论】:

    • 这行不通。第二种方法调用第一种方法,相当于直接调用第一种方法。
    • 在 em.find() 和 em.lock() 之间有可能另一个事务获得对实体的锁定。如果发生这种情况,em.lock 可能会失败,这取决于事务隔离级别。
    猜你喜欢
    • 1970-01-01
    • 2013-11-02
    • 2017-01-06
    • 1970-01-01
    • 2018-09-25
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 2016-12-26
    相关资源
    最近更新 更多