SpringBoot Repository Join Двунаправленный - PullRequest
0 голосов
/ 22 января 2020

У меня есть следующие две сущности:

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

1 Ответ

0 голосов
/ 22 января 2020

Когда вы выполняете внутреннее объединение, обе таблицы берутся, как будто при объединении в одну таблицу вы дублируете регистр. Если вы используете DISTINCT, у вас не должно быть этой проблемы

Например:

@Query( value = "SELECT DISTINCT d, l FROM Driver d INNER JOIN d.laps l")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...