在Spring Data JPA中处理实体继承的最佳方法

我有三个 JPA 实体类,具有以下层次结构:ABC

    A
    |
+---+---+
|       |
C       B

那是:

@Entity
@Inheritance
public abstract class A { /* ... */ }

@Entity
public class B extends A { /* ... */ }

@Entity
public class C extends A { /* ... */ }

使用Spring Data JPA,为这些实体编写存储库类的最佳方法是什么?

我知道我可以写这些:

public interface ARespository extends CrudRepository<A, Long> { }

public interface BRespository extends CrudRepository<B, Long> { }

public interface CRespository extends CrudRepository<C, Long> { }

但是如果在类中有一个字段,并且我在:AnameARepository

public A findByName(String name);

我也必须在其他两个存储库中编写这样的方法,这有点烦人。有没有更好的方法来处理这种情况?

我想说的另一点是,它应该是一个只读的存储库(即扩展类),而其他两个存储库应该公开所有CRUD操作。ARespositoryRepository

让我知道可能的解决方案。


答案 1

我使用了Netgloo博客中这篇文章中描述的解决方案。

我们的想法是创建一个通用存储库类,如下所示:

@NoRepositoryBean
public interface ABaseRepository<T extends A> 
extends CrudRepository<T, Long> {
  // All methods in this repository will be available in the ARepository,
  // in the BRepository and in the CRepository.
  // ...
}

然后我可以以这种方式编写三个存储库:

@Transactional
public interface ARepository extends ABaseRepository<A> { /* ... */ }

@Transactional
public interface BRepository extends ABaseRepository<B> { /* ... */ }

@Transactional
public interface CRepository extends ABaseRepository<C> { /* ... */ }

此外,要获取只读存储库,我可以将ARepositoryABaseRepository

@NoRepositoryBean
public interface ABaseRepository<T> 
extends Repository<T, Long> {
  T findOne(Long id);
  Iterable<T> findAll();
  Iterable<T> findAll(Sort sort);
  Page<T> findAll(Pageable pageable);
}

并且从扩展Spring Data JPA来实现读/写存储库:BRepositoryCrudRepository

@Transactional
public interface BRepository 
extends ABaseRepository<B>, CrudRepository<B, Long> 
{ /* ... */ }

答案 2

推荐