I have a Spring Boot application using Hibernate as JPA provider. My application has two entities connected with a @OneToMany / @ManyToOne relation. The relation is annotated with @Fetch(FetchMode.JOIN) on both directions, and fetch = FetchType.EAGER.
My entities are called Car and Driver:
@Entity
@Table(name = "car")
@Data
public class Car implements Serializable, Cloneable {
@Id
@GenericGenerator(name = "car_seq", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator", parameters = {
@Parameter(name = "sequence_name", value = "car_seq") })
@GeneratedValue(generator = "car_seq")
private Integer id;
@OneToMany(mappedBy = "car", fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
private List<Driver> drivers = new ArrayList<>();
@Column(name = "license_no", nullable = false)
private String licenseNo;
}
@Entity
@Table(name = "driver")
@Data
public class Driver implements Serializable, Cloneable {
@Id
@GenericGenerator(name = "driver_seq", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator", parameters = {
@Parameter(name = "sequence_name", value = "driver_seq") })
@GeneratedValue(generator = "driver_seq")
private Integer id;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "car_id", nullable = true)
@Fetch(FetchMode.JOIN)
private Car car;
@Column(name = "name", nullable = false)
private String name;
}
When selecting a care (e.g. by calling Car.findById()), Hibernate joins the the two tables in a single SQL, and returns a Car object with a list of Drivers.
But if I select a single driver, Hibernate will join the Driver and Car table to give me the Driver object with the Car property populated, but it will run a second query to fetch all the driver objects on for the list on the car object.
For performance reasons I would like all the involved objects to be fetched in a single query, as is the case when I fetch a car. But I cannot find a way to make Hibernate do this. There is a property, hibernate.max_fetch_depth, which is supposed to do this, but I have found that it only affects the behavior of fetching a car, not when I fetch a driver.
I know I can use an EntityGraph to control the fetching, and by using an EntityGraph I have successfully retrieved a driver object with its car and all the car's drivers in one query. But to do that, I have to explicitly use a graph when retrieving the object, and I cannot do that in all the various cases where a Car object is needed. There are lots of other entities that have a relation to Car, and I don't want to write an EntityGraph for each and every one of those.
So is there a way to tell Hibernate how you want the fetching to be done by default on an entity? I would have thought that the annotations would be enough, but it seems that there either has to be something more, or that this simply cannot be done.
Arndt