Подтвердить что ты не робот

Лучший способ обработки наследования объектов в Spring Data JPA

У меня есть три класса JPA A, B и C со следующей иерархией:

    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> { }

но если в классе A есть поле name, и я добавляю этот метод в ARepository:

public A findByName(String name);

Я должен написать такой метод и в двух других репозиториях, и это немного раздражает. Есть ли лучший способ справиться с такой ситуацией?

Еще одна точка, которую я хотел бы иметь, заключается в том, что ARespository должен быть репозиторием только для чтения (т.е. расширять класс Repository), в то время как другие два репозитория должны выставлять все операции CRUD.

Позвольте мне знать возможные решения.

4b9b3361

Ответ 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> { /* ... */ }

Кроме того, для получения репозитория только для чтения для ARepository я могу определить ABaseRepository как только для чтения:

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

и из BRepository также распространяются Spring Data JPA CrudRepository для создания репозитория чтения/записи:

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