java - Spring Boot 存储库双向加入

标签 java hibernate spring-boot jpa

我有以下两个实体:

驱动程序.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

最佳答案

当您执行内部联合时,两个表都会被获取,就像加入同一个表一样,您复制了寄存器。如果你使用 DISTINCT 就不应该有这个问题

例如:

@Query( value = "SELECT DISTINCT d, l FROM Driver d INNER JOIN d.laps l")

关于java - Spring Boot 存储库双向加入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59857008/

相关文章:

java - 从构造函数调用重写的方法

java - @在HSQL数据库中生成

java - 如何计算hibernate中两个字段之间差异的结果并将其显示在jsp上?

java - 无法使用 hibernate PostgreSQL 存储 java.time.ZonedDateTime

Maven、Spring-boot - 导入 javax.validation 无法解析

spring-boot - 其他程序语言客户端如何使用Spring Cloud Config Server?

java - 在真实mysql系统中处理DELETE的最佳方法

java - Function::identity 在 Collectors.toMap 中不起作用

java - 在 Java 8 中,如果映射具有重复值,则获取重复值异常

java - 如何在 Spring Boot 中进行多个 URL 映射(别名)