我有以下两个实体:
驱动程序.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/