Извлечение связанной сущности в одном запросе в Hibernate - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть две сущности, которые выглядят примерно так:

@Entity
class TimeRange(
    @Id val id: UUID,
    val startTime: Instant,
    val endTime: Instant,
    ...
)

@Entity
class StepInProcess(
    @Id val id: UUID,
    val projectId: UUID,
    @OneToOne()
    @JoinColumn(name = "range_id", referencedColumnName = "id")
    val timeRange: TimeRange,
    ...
)

Мой репозиторий выглядит так:

@Repository
interface StepInProcessRepository : JpaRepository<StepInProcess, UUID> {
    fun findAllByProjectId(projectId: UUID): List<StepInProcess>
}

Всякий раз, когда я получаю список шагов, мне почти всегда необходимо получить доступ к startTime на соответствующем TimeRange. Каждый из них требует выдачи отдельного запроса для извлечения сущности временного диапазона, которая в итоге оказывается неэффективной. В идеале я хотел бы поручить Hibernate всегда получать эти данные немедленно, в идеале с объединением, а не требовать отдельного выбора.

Казалось, что добавление @Fetch(FetchMode.JOIN) к timeRange должно делать то, что я хотел, но, похоже, это не так (или я пропустил что-то еще). Я основываюсь на том, как смотрят журналы отладки, показывающие, как Hibernate выдает множество операторов select для TimeRange сущностей; не уверен, что есть лучший способ диагностировать подобные вещи.

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

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

1 Ответ

0 голосов
/ 27 апреля 2018

Кажется, что, возможно, @Fetch просто не работает с JPA? Вместо этого изменение моего репозитория для включения явного запроса с JOIN FETCH, похоже, сделало свою работу:

@Query("SELECT step FROM StepInProcess step JOIN FETCH step.timeRange WHERE step.projectId = :projectId")
fun findAllByProjectId(projectId: UUID): List<StepInProcess>

Не уверен, что это лучший маршрут или нет.

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