У меня есть следующие две сущности:
Driver. java
@Entity
@Table(name = "driver")
@Getter @Setter
public class Driver {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int dbid;
private String lastName;
private String firstName;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "driver")
private List<Lap> laps;
}
Lap. java
@Entity
@Table(name = "lap")
@Getter @Setter
public class Lap {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer dbid;
private Integer entryDbid;
private Integer lapNumber;
private Double lapTime;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "driver_dbid")
@JsonIgnoreProperties("laps")
private Driver driver;
}
А теперь я хочу создать два хранилища. Один для выбора всех драйверов с соответствующими кругами, а другой - для выбора всех кругов с соответствующим драйвером.
LapRepository. java
public interface LapRepository extends JpaRepository<Lap, Integer> {
@Query( value = "SELECT l, d FROM Lap l INNER JOIN l.driver d")
List<Lap> findWithDriver();
}
DriverRepository. java
public interface DriverRepository extends JpaRepository<Driver, Integer> {
@Query( value = "SELECT d FROM Driver d")
List<Driver> findWithoutLaps();
@Query( value = "SELECT d, l FROM Driver d INNER JOIN d.laps l")
List<Driver> findWithLaps();
}
следующий вызов функции работает должным образом. Будет выполнен только один запрос, и результаты будут преобразованы в Lap-Entity.
List<Lap> laps = this.lapRepository.findWithDriver()
Здесь журнал:
1796761 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
2003707 nanoseconds spent preparing 1 JDBC statements;
58061128 nanoseconds spent executing 1 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
Если я хочу выполнить следующее:
List<Driver> drivers = this.driverRepo.findWithoutLaps()
тоже работает как положено. Здесь возникает проблема n + 1, потому что соответствующие круги не будут выбраны в запросе.
Но здесь: список драйверов = this.driverRepo.findWithLaps ()
Я ожидаю, что соответствующие круги будут выбраны во время запроса и будут установлены на объекте водителя. Но я получаю следующий журнал:
761869 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
2337819 nanoseconds spent preparing 87 JDBC statements;
305405297 nanoseconds spent executing 87 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
Кроме того, для каждой отдельной строки результатов, круги были объединены. Например, это означает следующее: у меня 50 водителей, у каждого из них 2 круга -> в результате я получаю 100 объектов водителя.
Что-то не так с запросом, но я не знаю что?
Редактировать: Вот таблицы postgres:
Драйвер
dbid serial not null primary key
first_name text not null
last_name text not null
Круг
dbid serial not null primary key
entry_dbid int not null foreign key
driver_dbid int not null foreign key
lap_number int not null
lap_time double not null