【问题标题】:JPA Repository Inheritance - Extend Multiple InterfacesJPA 存储库继承 - 扩展多个接口
【发布时间】:2019-06-07 13:58:24
【问题描述】:

我的 JPA 存储库扩展了一个自定义接口,该接口带有用于以通用方式处理授权的注释。

public interface MultiTenantCrudRepo<T, ID> extends CrudRepository<T, ID>

该接口在 CrudRepository 的方法中添加了@PreAuthorize、@PostAuthorize、@PreFilter 和@PostFilter 注解。

此外,对于某些实体,我需要实现软删除。为此,我创建了一个像这样的“SoftDeleteRepository”:

public interface SoftDeleteRepository<T extends BaseEntity<I> & SoftDeletable, I extends Serializable> extends CrudRepository<T, I> {

    @Query("update #{#entityName} e set e.isDeleted = true where e.id = ?#{#entity.id}")
    @Modifying
    @Override
    public void delete(@Param("entity") T entity);

你可以看到它添加了@Query注解来实现我需要的功能。

两个接口都按预期独立工作,但是当存储库需要像这样的两个属性(授权和软删除)时

public interface FooRepo extends SoftDeleteRepository<Foo, Long>, MultiTenantCrudRepo<Foo, Long> {

似乎只有“扩展”之后的第一个接口的注释才有效。所以在这种情况下,我得到了一个支持软取消但没有授权验证的 FooRepo。

让两者发挥作用的最佳方式是什么?

【问题讨论】:

    标签: java jpa spring-data-jpa


    【解决方案1】:

    猜测这是一件棘手的事情,因为它实际上是 Java 不支持的多继承,例如参见 this

    例如,如果有两个相同的注解具有不同的参数,会选择什么?

    许多框架——比如 Spring 数据——在检查注解的继承时做得很好,但只有在没有多重继承和/或具有相同注解时才猜测。这些框架可能会使用反射在“实现树”上上升,但可能会因为上述原因而只选择一条路径,或者如果实现良好则抛出异常。

    因此,恐怕您需要执行以下操作:

    public interface SoftDeleteMultitenantRepository
                         extends MultiTenantCrudRepo<Foo, Long> {
     // a copy of your soft delete method here
    }
    

    【讨论】:

    • 我希望有办法做到这一点,但我可以忍受。谢谢!一旦第一个实体需要软删除而不是多租户的东西,就会变得有点混乱:D
    猜你喜欢
    • 2014-02-15
    • 1970-01-01
    • 2010-09-29
    • 2017-09-07
    • 2018-08-17
    • 2011-03-31
    • 1970-01-01
    • 2014-09-07
    • 2023-01-28
    相关资源
    最近更新 更多