我有以下两个实体:
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
答案 0 :(得分:0)
执行内部联合时,将同时使用两个表,就像在同一表中联接一样,您将复制寄存器。如果您使用DISTINCT,应该不会有问题
例如:
@Query( value = "SELECT DISTINCT d, l FROM Driver d INNER JOIN d.laps l")