0

I have two entities that look kind of like this:

@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,
    ...
)

My repository just looks like:

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

Whenever I retrieve a list of steps, I pretty much always need to access the startTime on the associated TimeRange. Each one of these requires that a separate query be issued to retrieve the time range entity which ends up being really inefficient. Ideally I'd like to instruct Hibernate to always retrieve this data immediately, ideally with a join, rather than requiring a separate select.

It seemed like adding @Fetch(FetchMode.JOIN) to timeRange should do what I wanted, but this doesn't seem to be the case (or I've missed something else). I'm basing this on watching debug logs go by that show Hibernate issuing lots of select statements for TimeRange entities; not sure if there's a better way to diagnose this sort of thing.

Alternatively, I would be fine with promoting startTime and endTime to be properties on the Step itself, but I'm not clear on how to accomplish this, either. I do not want to create an inheritance relationship between the two entities as it's not really fair to say that a step "is a " time range.

Is @Fetch the right way to do this? If so, is there something more to getting it to work than adding the annotation to the property? If not, how should I go about tackling this?

AwesomeTown
  • 2,800
  • 2
  • 27
  • 41
  • This question seems to be related to the Fetch not working as expected, but doesn't really explain what was done to resolve the issue: https://stackoverflow.com/questions/5457731/hibernate-issuing-select-statement-even-if-fetchmode-join – AwesomeTown Apr 27 '18 at 18:49

1 Answers1

2

It seems like maybe @Fetch just doesn't work with JPA? Instead, modifying my repository to include an explicit query with JOIN FETCH seems to have done the job:

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

Not sure if that's the best route to go or not.

AwesomeTown
  • 2,800
  • 2
  • 27
  • 41