Java 如何覆盖Spring数据JPA存储库基方法?
我有一些实体类型在保存时需要额外的逻辑(确切地说,我想在保存时保存位置)。我不想使用任何特定于DB的特性,比如触发器,因为我不确定将来会使用什么样的数据存储 所以我想重写Java 如何覆盖Spring数据JPA存储库基方法?,java,spring,hibernate,spring-data-jpa,Java,Spring,Hibernate,Spring Data Jpa,我有一些实体类型在保存时需要额外的逻辑(确切地说,我想在保存时保存位置)。我不想使用任何特定于DB的特性,比如触发器,因为我不确定将来会使用什么样的数据存储 所以我想重写save()方法 在Spring Data JPA文档中,我可以看到为存储库类提供自己实现的两种方法: 扩展基本存储库类并告诉Spring数据使用它 使用实现类(PositionedRepositoryImpl)定义接口(在我的例子中,我假设PositionedRepository) 第一种方法的问题-我不想为所有存储库实现它,
save()
方法
在Spring Data JPA文档中,我可以看到为存储库类提供自己实现的两种方法:
PositionedRepositoryImpl
)定义接口(在我的例子中,我假设PositionedRepository
)是否可以仅为特定存储库类型扩展基本存储库类?作为第三个选项,您可以扩展实现
JpaRepository
和JpaSpecificationExecutor
的simplejpepository
。
通过这种方式,您可以受益于JpaRepository
的默认实现,同时能够覆盖这些方法
例如:
@Repository
public class PositionedRepository extends SimpleJpaRepository<Positioned, Long> {
@Override
public Positioned save(Positioned positioned) {
...
}
}
@存储库
公共类定位存储扩展了SimpleParepository{
@凌驾
公共定位保存(定位){
...
}
}
作为第四个选项,您还可以定义自己的
savePositioned()
方法,该方法在后台使用JpaRepository.save()
不要在存储库本身中执行该逻辑。将存储库视为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);
}
}
你可以:
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
}
}
public类CustomJpaRepository扩展了SimpleJpaRepository{
私人最终JpaEntityInformation entityInformationWrap;
私有最终实体管理器emWrap;
公共客户jparepository(JpaEntityInformation、EntityManager、EntityManager){
超级(实体信息、实体管理器);
entityInformationWrap=entityInformation;
emWrap=实体管理器;
}
@凌驾
公共存储(S实体){
//做
}
}
然后主类添加:
@EnableJpaRepositories(repositoryBaseClass=CustomJpaRepository.class)回答得很好!但是
EntityManager
并不是最好的名字,因为它代表了JPA中非常具体的东西PositionedService
要保持通用性就更清楚了:)我将我的存储库公开为Spring数据REST端点,希望它保持在默认Spring流中。我将我的存储库公开为Spring数据REST端点。它可能会起作用,但非常令人沮丧。我建议在数据库和客户端之间至少有3层:数据访问层->存储层,业务逻辑层->服务,通信层->控制器。这样的话,你显然已经把责任分开了。通信处理请求并调用业务逻辑,然后业务逻辑调用数据访问。如果您像这样构建应用程序,您将不胜感激