首页 > 解决方案 > Left Join Fetch 表现得像 Inner Join

问题描述

我在路线和站点之间有一对多的关系。为了维护审计跟踪,我的 Stop 实体有一个“历史”布尔值。

获取路线时,我想忽略历史停靠点,因此我构建了以下查询:

@Query("select r from Route r " +
            "left join fetch r.schedules schedule " +
            "left join fetch r.stops stop " +
            "where r.routeId = :routeId and stop.historic = false ")
Optional<Route> findByIdLoadStops(@Param("routeId") int routeId);

当路线有非历史停靠点且没有停靠点时,这很好用,但是当路线只有历史停靠点时(这不应该发生,但我希望至少能够处理它),它返回一个空的可选,好像已执行内部连接。

在记录 hibernate 创建的 JPA 查询时,我可以看到该查询使用左外连接。

我做错了什么?

Route 和 Stop 实体:

@Table(name = "route")
@Entity
public class Route {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "routeId", columnDefinition = "SMALLINT(5) UNSIGNED")
    private int routeId;

    @Column(name = "locked")
    private boolean locked = false;

    @OneToMany(mappedBy = "route",
            cascade = CascadeType.ALL,
            fetch = FetchType.LAZY)
    @OrderBy("stopTime asc")
    private SortedSet<Stop> stops = new TreeSet<>();

    public Route() {
    }

}

@Table(name = "stop", uniqueConstraints = {
        @UniqueConstraint(columnNames = {"stopTime", "routeId"}),
        @UniqueConstraint(columnNames = {"stopName", "routeId"})})
@Entity
public class Stop implements Comparable<Stop> {

    @Id
    @Column(name = "stopId")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int stopId;

    @Column(name = "routeId",
            columnDefinition = "SMALLINT(5)",
            updatable = false, insertable = false)
    private int routeId;

    @ManyToOne(cascade = CascadeType.MERGE,
            fetch = FetchType.LAZY)
    @JoinColumn(name = "routeId")
    private Route route;

    @Column(name = "stopTime")
    private LocalTime stopTime;

    @Column(name = "stopName")
    private String stopName;

    @JoinColumn(name = "originalId", referencedColumnName = "stopId")
    @ManyToOne(fetch = FetchType.LAZY)
    private Stop originalStop = this;

    @Column(name = "historic")
    private boolean historic = false;

    public Stop() {
    }

}

标签: springhibernatejpaspring-data-jpaspring-data

解决方案


推荐阅读