Как получить сущность через абстрактный MappedSuperClass с помощью CrudRepository findByName - PullRequest
0 голосов
/ 24 июня 2018

У меня есть сценарий использования, в котором большинство моих классов моделей имеют в качестве полей идентификатор и имя вместе с полями, специфичными для сущности.

Для достижения того же у меня есть суперкласс:

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

@MappedSuperclass
public abstract class BasicEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String name;

    public BasicEntity() {

    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Производный класс:

@Entity
public class DerivedEntity extends BasicEntity {

}

Затем я пытаюсь использовать CrudRepository, чтобы получить сущность по ее имени:

@Repository
public interface GenericRepository<T extends BasicEntity> extends CrudRepository<T, Integer> {

    //T findByName(String name);
}

Этот код выдает ошибку

«Не сущность: класс BasicEntity».

Здесь я понимаю ошибку, она дает ошибку, потому что класс BasicEntity не является сущностью по отдельности, я хочу знать, есть ли какой-нибудь способ, которым я могу указать универсальные элементы для crudRepository, такие как T, расширяет BaseEntity без включения BasicEntity.

Я также знаю, что могу использовать наследование, отображая класс BasicEntity @entity & @Inheritance, используя конкретное отображение, но я этого не хочу.

Есть ли другой способ решить эту проблему?

1 Ответ

0 голосов
/ 24 июня 2018

Вы можете написать что-то вроде этого

  @Entity
  @Inheritance
  public abstract class BasicEntity {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private int id;

     private String name;

    }

Теперь создайте один базовый репозиторий

  @NoRepositoryBean
  public interface BaseRepository<T extends BasicEntity> 
  extends CrudRepository<T, Long> {

  public T findByName(String name);

  }

Теперь другой репозиторий расширяет Базовый репозиторий.

   public interface DevivedRepository extends BaseRepository<User> { /* ... */ }

для пользовательских запросов Вы можете ссылаться на правильный объект в пользовательском запросе Базового репозитория, например

  public interface BaseRepository 
  extends CrudRepository<T, Long> {

  @Query("select u from #{#entityName} as u where u.name = ?1 ")
  T findByName(String name);

  }

Значение entityName равно rplacae jpa типа T

Это будет работать

...