Left Join Fetch Behaving Like Inner Join - PullRequest
       41

Left Join Fetch Behaving Like Inner Join

0 голосов
/ 30 декабря 2018

У меня отношение один-ко-многим между маршрутами и остановками.Для ведения контрольного журнала мои объекты 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);

Это прекрасно работает, когда у маршрута есть неисторические остановки и нет остановок, но когда у маршрута есть только историческая остановка (что не должно происходить, но я хочу иметь возможность по крайней мере справиться с этим), он возвращает пустой дополнительныйкак будто внутреннее соединение было выполнено.

При регистрации запроса JPA, созданного hibernate, я вижу, что запрос использует левое внешнее соединение.

Что я сделал неправильно?

Объекты 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() {
    }

}
...