Наиболее эффективный объект передачи данных с пружинными данными jpa - PullRequest
0 голосов
/ 01 ноября 2018

У меня есть объект, который необходимо немного изменить, прежде чем он будет возвращен пользователю. Насколько я понимаю, лучший способ сделать это - использовать объект передачи данных.

Это работает нормально, но потом я добавил дочернюю сущность. Я снова создал DTO для дочерней сущности. Вот код для хранилища:

@Repository
public interface DrawingReleaseRepository extends CrudRepository<DrawingRelease, Integer> {
    @Query("SELECT new com.engineering.dto.drawings.DrawingReleaseDTO("
            + "dwgrel.drawingReleaseID,"
            + "relType"
            + ") FROM DrawingRelease dwgrel "
            + "JOIN dwgrel.releaseType relType "
            + "WHERE dwgrel.drawingReleaseID = ?1")
    DrawingReleaseDTO getDrawingRelease(int drawingReleaseID);
}

Конструктор для DrawingReleaseDTO это:

public DrawingReleaseDTO(int drawingReleaseID, DrawingReleaseType releaseType) {
    this.drawingReleaseID = drawingReleaseID;
    this.releaseType = new DrawingReleaseTypeDTO(releaseType);
}

На моем сервисном уровне я теперь могу манипулировать данными, которые возвращаются клиенту, но изменения не сохраняются в базе данных (что я и хочу):

@Override
public DrawingReleaseDTO findByID(int id) {
    DrawingReleaseDTO dto = repository.getDrawingRelease(id);
    dto.getReleaseType().setCustom1(true);
    return dto;
}

Проблема этого сценария в том, что он не очень эффективен. Я имею в виду, что Hibernate выполняет два запроса - один для DrawingRelease и один для DrawingReleaseType.

Я подумал, что способ исправить это - указать JOIN FETCH dwgrel.releaseType relType, так как это должно заставить hibernate получить все данные за один снимок, но это приводит к ошибке:

в запросе указано присоединение, но владелец извлечен ассоциации не было в списке выбора

Есть ли способ использовать DTO, включать данные для дочерних объектов и использовать ли все это эффективные запросы?

Ответы [ 2 ]

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

Это идеальный вариант использования для Blaze-Persistence Entity Views , который будет делать именно то, что вы хотите, а также улучшать производительность, генерируя запрос JPQL / HQL, который выбирает только соответствующие атрибуты. Хотя я не знаю вашу модель, использование представлений сущностей для вашей модели, насколько я понял, может выглядеть следующим образом

@EntityView(DrawingRelease.class)
public interface DrawingReleaseDTO
  int getDrawingReleaseID();
  DrawingReleaseTypeDTO getReleaseType();

  @EntityView(DrawingReleaseType.class)
  interface DrawingReleaseTypeDTO {
    boolean isCustom1();
  }
}

При правильной настройке вы можете использовать это представление сущности с репозиториями данных весны

interface DrawingReleaseRepository extends JpaRepository<DrawingReleaseDTO, Long> {
}

DrawingReleaseDTO dto = drawingReleaseRepository.findById(id);

Он сгенерирует запрос JPQL / HQL, подобный этому

SELECT drawingRelease.id, drawingReleaseType.custom1 
FROM DrawingRelease drawingRelease 
LEFT JOIN drawingRelease.drawingReleaseType drawingReleaseType 
WHERE drawingRelease.id = :id
0 голосов
/ 01 ноября 2018

Проблема в том, что вы смешали DTO и сущности.

DTO не должен ссылаться на сущности, а второй запрос возникает при инициализации дочерней сущности.

Кроме того, передача сущности в DTO является анти-паттерном:

this.releaseType = new DrawingReleaseTypeDTO(releaseType);

Вам нужно, чтобы DTO был построен из проекций столбцов. Для более подробной информации, ознакомьтесь с этой статьей .

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