JPA Repository Inheritance - Extend Multiple Interfaces

user3235738 :

My JPA repositories extend a custom interface that carries annotations for handling authorization in a generic way.

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

This interface adds @PreAuthorize, @PostAuthorize, @PreFilter and @PostFilter annotations to the methods of CrudRepository.

Further, for some entities, I have the need to implement soft deletion. For this purpose, I created a "SoftDeleteRepository" like this:

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);

You can see it adds @Query annotations to implement the functionality I need.

Both interfaces work independently as expected, but when a repository required both attributes (authorization and soft deletion) like this

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

it seems like only the annotations of the first interface after "extends" are effective. So in this case, I get a FooRepo that supports soft delection but without authorization validation.

What is the best way to get both to work?

pirho :

Guess that it is a tricky thing to do because it actually would be multi inheritance thing which Java does not support, for example see this.

What would be chosen if there were two of the same annotations with different parameters, for example?

Many frameworks - like Spring data - do just fine when checking for inheritance of annotations but guess only if there is no multi-inheritance and/or with same annotations. These frameworks might use reflection to go up on the "implements tree" but might choose only one path because of the above or if well implemented throw an exception.

Because of this I am afraid you need to do something like:

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=82464&siteId=1