像往常一样简单地创建您的自定义接口,并在那里声明您想要覆盖的方法,并使用与CrudRepository(或JpaRepository等)公开的方法相同的签名。假设您有一个 MyEntity 实体和一个 MyEntityRepository 存储库,并且您想要覆盖默认自动生成的 save 方法 MyEntityRepository 采用唯一的实体实例,然后定义:
public interface MyEntityRepositoryCustom {
<S extends MyEntity> S save(S entity);
}
并像往常一样在您的MyEntityRepositoryImpl 中实现此方法:
@Transactional
public class MyEntityRepositoryImpl implements MyEntityRepositoryCustom {
public <S extends MyEntity> S save(S entity) {
// your implementation
}
}
然后,像往常一样,让MyEntityRepository 扩展MyEntityRepositoryCustom。
这样做,Spring Data JPA 将调用您的 MyEntityRepositoryImpl 的 save 方法而不是默认实现。
至少这适用于 Spring Data JPA 1.7.2 中的 delete 方法。
“引用不明确”错误
正如一些评论者所报告的那样,可能是从某个 Spring Data JPA 版本或 javac 版本开始的(我不能说它是什么时候开始失败的,但我可以肯定它之前工作过)javac 编译器开始在被覆盖的方法上给出一个编译错误:“模糊引用”。
Eclipse JDT 不返回此错误,代码在运行时有效,实际上我打开Bug 463770 的原因是:要么是javac 错误,要么是不符合javac 的JDT 错误。
这就是说,卢卡斯在下面发布了解决方法,乍一看似乎与上面描述的相同。实际上,区别在于MyEntityRepositoryCustom,声明必须包含泛型类型<S>,即使它显然没有用。因此,如果您遇到此错误,请将自定义接口声明更改为:
public interface MyEntityRepositoryCustom<S> {
<S extends MyEntity> S save(S entity);
}
并让标准存储库接口实现MyEntityRepositoryCustom<MyEntity> 而不仅仅是MyEntityRepositoryCustom。
但是,如果您不想生成自定义接口,您可以为save 方法2 提取一个单独的片段接口。那么解决方案如下:
public interface MyEntityRepositoryCustom {
// custom methods
}
public interface CustomizedSaveRepository<T> {
<S extends T> S save(S entity);
}
@Transactional
public class MyEntityRepositoryImpl implements MyEntityRepositoryCustom,
CustomizedSaveRepository<MyEntity> {
@Override
public MyEntity save(MyEntity entity) {
// your implementation for CustomizedSaveRepository#save
}
// implementations of MyEntityRepositoryCustom
}