Как реализовать облегченную версию Entity с Jpa-репозиторием? - PullRequest
0 голосов
/ 18 ноября 2018

Иметь класс "полный Сущность":

@Entity(name = "vacancy_dec_to_words")
public class VacancyDescriptionToWords {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @JoinColumn(name = "vacancy_description_id")
    @ManyToOne(cascade = CascadeType.ALL)
    private VacancyDescription vacancyDescription;

    @JoinColumn(name = "words_id")
    @ManyToOne
    private Words words;

    @Column(name = "qty")
    private int qty;

    @Column(name = "create_date")
    private Date date;

    //...getters and setters

В некоторых методах мне нужно использовать только 2 столбца из этой базы данных: word_id и qty

Я стараюсь так:

Проекция https://docs.spring.io/spring-data/jpa/docs/2.1.2.RELEASE/reference/html/#projections

public interface QtyWords {
    Long getWords();
    Integer getQty();
}

JpaReposytory:

* Запрос, что я использую проверено и работоспособно, я использую его в JpaRepository:

@Repository
public interface SmallVDTWRepository extends JpaRepository<VacancyDescriptionToWords, Long> {

@Query(nativeQuery = true,
        value = "SELECT sum(qty), words_id FROM vacancy_desc_to_words WHERE vacancy_description_id IN (" +
                "SELECT id FROM vacancy_description WHERE vacancy_id IN (" +
                "SELECT id FROM vacancy WHERE explorer_id = :exp))" +
                "GROUP BY words_id")
List<QtyWords> getDistinctWordsByExplorer(@Param("exp") long exp);
}

Но я получаю интересный результат, когда получаю список сущностей:

    List<QtyWords> list = vdtwService.getByExplorerId(72);

Я не получаю никаких исключений, но у меня есть список с неизвестными объектами. Этот объект содержит мои данные, которые мне нужны (qty и words_id), но я не могу получить их от него.

enter image description here

Могу ли я использовать этот метод (Projection) для реализации этой задачи и, в общем, как правильно реализовать «Легкую сущность» в этом случае?

1 Ответ

0 голосов
/ 18 ноября 2018

Spring предоставляет два механизма, которые можно использовать для ограничения выборки данных.

Прогнозы

Прогнозы могут помочь вам сократить объем данных, извлекаемых из базы данных, путемнастройка того, какие именно атрибуты вы хотите получить.

Пример:

@Entity
class Person {
    @Id UUID id;
    String firstname, lastname;
    @OneToOne
    Address address;
}

@Entity
static class Address {
    @Id UUID id;
    String zipCode, city, street;
}

interface NamesOnly {
    String getFirstname();
    String getLastname();
}

@Repository
interface PersonRepository extends Repository<Person, UUID> {
    Collection<NamesOnly> findByLastname(String lastname);
}

Граф сущностей

Аннотация EntityGraph может помочь уменьшить количествозапросов к базе данных, указав, какие именно связанные сущности вам нужно выбрать.

Пример:

@Entity
@NamedEntityGraph(name = "GroupInfo.detail", attributeNodes = @NamedAttributeNode("members"))
public class GroupInfo {
    @Id UUID id;
    @ManyToMany //default fetch mode is lazy.
    List<GroupMember> members = new ArrayList<GroupMember>();
}

@Repository
public interface GroupRepository extends CrudRepository<GroupInfo, String> {

    @EntityGraph(value = "GroupInfo.detail", type = EntityGraphType.LOAD)
    GroupInfo getByGroupName(String name); //Despite of GroupInfo.members has FetchType = LAZY, it will be fetched because of using EntityGraph
}

Существует два типа EntityGraph:

  1. EntityGraphType.LOAD - используется для указания графа сущностей, атрибуты, которые указываются узлами атрибутов графа сущностей, обрабатываются как FetchType.EAGER, а атрибуты, которые не указаны, обрабатываются в соответствии с их указанным значением или значением по умолчанию FetchType.
  2. EntityGraphType.FETCH - используется для указания графа сущностей, атрибуты, которые указываются узлами атрибутов графа сущности, обрабатываются как FetchType.EAGER, а атрибуты, которые не указаны, обрабатываются как FetchType.LAZY.

PS: Также помните, что вы можете установить ленивый тип выборки: @ManyToOne(fetch = FetchType.LAZY), и JPA не будет извлекать дочерние объекты при извлечении родителя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...