如何覆盖Spring Data JPA仓库基本方法?

3
我有一些需要在保存时添加额外逻辑的实体类型(准确地说,我想在保存时保存位置)。我不想使用任何特定于数据库的功能(例如触发器),因为我不确定将来会使用什么数据存储。
因此,我想覆盖save()方法。
在Spring Data JPA文档中,我可以看到两种提供自己实现的存储库类的方式:
1. 扩展基本存储库类并告诉Spring Data使用它。 2. 定义一个接口(在我的情况下,我假设是PositionedRepository)和一个实现类(PositionedRepositoryImpl)。
第一种方法的问题是 - 我不想为所有存储库实现它,只有两种实体类型是定位的。
第二种方式的问题是 - 我无法访问基本存储库方法,因此除了位置计算之外,我还需要以某种方式构建所有查询,通常由基本存储库提供。
是否有一种方法可以仅针对特定存储库类型扩展基本存储库类?
3个回答

5
不要在存储库本身处理该逻辑。把存储库看作是 Java 和数据库之间的一个愚笨层。它只是将数据从一端传递到另一端。
相反,你应该在另一个层面处理该情况。一个更加智能的业务逻辑层。
看这个例子:
@Service
public class MyEntityService{

     private final MyEntityRepository myEntityRepository;
     private final OtherEntityRepository otherEntityRepository;

     @Autowired
     public MyEntityService(MyEntityRepository myEntityRepository, 
                          OtherEntityRepository otherEntityRepository){
         this.myEntityRepository = myEntityRepository;
         this.otherEntityRepository = otherEntityRepository;
     }

     public void save(MyEntity myEntity){
          // do stuff with otherEntityRepository
          myEntitiyRepository.save(myEntity);
     }
}

1
非常好的回答!但是 EntityManager 不是最合适的名称,因为它在JPA中代表了一件非常具体的事情!为了保持通用性,使用 PositionedService 会更清晰 :) - undefined
我将我的存储库暴露为Spring Data REST端点,希望保持在默认的Spring流程中。 - undefined
我将我的存储库暴露为Spring Data REST端点。这可能有效,但是强烈不建议这样做。我建议在数据库和客户端之间始终至少有3个层次:数据访问层->存储库,业务逻辑层->服务,通信层->控制器。这样你可以清楚地分离责任。通信处理请求并调用业务逻辑,然后再调用数据访问。如果您按照这种方式构建应用程序,您会感激不尽。 - undefined

3

您可以:

public class CustomJpaRepository<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> {
  private final JpaEntityInformation<T, ?> entityInformationWrap;
  private final EntityManager emWrap;
  public CustomJpaRepository(JpaEntityInformation entityInformation, EntityManager entityManager) {
    super(entityInformation, entityManager);
    entityInformationWrap=entityInformation;
    emWrap=entityManager;
  }

  @Override
  public <S extends T> S save(S entity) {
    //doing
  }

}

然后在主类中添加: @EnableJpaRepositories(repositoryBaseClass = CustomJpaRepository.class)


2
作为第三种选择,您可以扩展实现JpaRepositoryJpaSpecificationExecutorSimpleJpaRepository。 这样,您可以从JpaRepository的默认实现中受益,同时具备覆盖这些方法的能力。
例如:
@Repository
public class PositionedRepository extends SimpleJpaRepository<Positioned, Long>  {

    @Override
    public Positioned save(Positioned positioned) {
           ...
    }

}

作为第四种选项,您还可以定义自己的savePositioned()方法,该方法在底层使用JpaRepository.save()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接