что использовать вместо fetch.EAGER в весенних данных? - PullRequest
0 голосов
/ 25 мая 2018

Я работаю с spring-boot и angular5, у меня есть эта сущность весной:

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Contrat implements Serializable{

    @Id @GeneratedValue
    private Long id;
    private Date dateDebut ;
    private Date dateFin ;
    @ManyToOne
    @JoinColumn(name = "Id_Project")
    @JsonBackReference(value="projet-contrat")
    private Project project;

    @ManyToOne
    @JoinColumn(name = "Id_AppUser")
    @JsonBackReference(value="appuser-contrat")
    private AppUser appUser;
}

Репозиторий:

public interface ContratRepo extends JpaRepository<Contrat,Long> {

    public Page<Contrat> findByAppUser(@Param("userApp") AppUser userApp, Pageable pageable);

}

Поскольку fetch.lazy используется по умолчаниюВо-первых, когда я пытаюсь вызвать метод findByAppUser, я получаю в результате:

{id: 1, dateDebut: 1526083200000, dateFin: 1526083200000} 

Что нормально, я хочу в моем случае также загрузить объект 'project', который существует в сущности, ноя не хочу использовать fetch.EAGER, какое-нибудь решение для этой цели?

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

Укажите запрос в методе репо, например (синтаксис может быть неправильным, просто покажите вам идею)

 public interface ContratRepo extends JpaRepository<Contrat,Long> {

    @Query(query="from Contrat c left join fetch c.project " +
                  "where c.userApp = :userApp")
    public Page<Contrat> findByAppUser(@Param("userApp") AppUser userApp, Pageable pageable);

}
0 голосов
/ 25 мая 2018

Ваша сущность является объектом отношений один-много.Если вы не используете EAGER, данные Spring получат объект без связанного объекта-члена.И если вы получите это с contract.getProject().getName(), то для получения этого члена будет отправлен другой запрос.

Если вы зарегистрируете SQL, вы увидите, что будет 2 запроса.Но если вы установите поле EAGER, будет только 1 запрос.Вы можете получить улучшение, очевидно.

Но вы не должны использовать EAGER всегда.Если в 90% времени вам просто нужен объект Контракт, но не нужны данные проекта для него.Это пустая трата времени, чтобы получить это.Поскольку в SQL он будет связывать 2 таблицы и получать все столбцы данных.

ТАК, вам следует принять это решение в зависимости от использования этой сущности.

[Обновлено на основе комментариев]

Вы можете использовать Query, чтобы написать выражение sql.Например, у меня есть метод для получения объекта с деталями:

    @Query("select s from Contract s left join fetch s.project pr where s.id = ?1 ")
    Contract findOneWithDetail(Long id);

Если мне нужно получить детали в ОДНОМ sql, я могу использовать этот метод.Если мне не нужны детали проекта, я просто использую findOne(Long id), который предоставляет интерфейс.

И, если вы просто хотите получить несколько столбцов, вам нужно определить DTO с помощью конструктора,и напишите свой метод так:

    @Query("SELECT NEW com.mypackage.dto.ContractDTO(s.id, s.name, s.status)  FROM Contract AS s WHERE s.status = ?1")
    List<ContractDTO> findDTOAllByStatus(String status);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...