我正在开发一个公交车时刻表的网络应用程序.我的任务是搜索一个时刻表,其中有用户输入的停靠点.但是当我将我的查询写入数据库时,我得到一个白色标签错误页"Error:Argument of Join/On必须是Boolean类型,而不是Bigint类型"

There was an unexpected error (type=Internal Server Error, status=500).
JDBC exception executing SQL [SELECT DISTINCT c FROM schedules c JOIN routes r ON c.routes_id JOIN routes_stops rs on r.route_id JOIN stops s ON rs.stop_id WHERE s.name = ? and c.departure_time >= ? and c.departure_time < ?] [ERROR: argument of JOIN/ON must be type boolean, not type bigint Position: 53] [n/a]; SQL [n/a]
org.springframework.dao.InvalidDataAccessResourceUsageException: JDBC exception executing SQL [SELECT DISTINCT c FROM schedules c JOIN routes r ON c.routes_id JOIN routes_stops rs on r.route_id JOIN stops s ON rs.stop_id WHERE s.name = ? and c.departure_time >= ? and c.departure_time < ?] [ERROR: argument of JOIN/ON must be type boolean, not type bigint
  Position: 53] [n/a]; SQL [n/a]
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:256)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:229)

我的请求如下所示:

public interface ScheduleRepository extends JpaRepository<Schedule, Long> {
    
// more methods ... 

    @Query(value = "SELECT DISTINCT c FROM schedules c " +
                    "JOIN routes r ON c.routes_id " +
                    "JOIN routes_stops rs on r.route_id " +
                    "JOIN stops s ON rs.stop_id " +
                    "WHERE s.name = :stopName and c.departure_time >= :departureTime and c.departure_time < :endOfDay", nativeQuery = true)
    List<Schedule> findAllByStopsAndTimeForSearch(@Param("stopName") String stopName,
                                              @Param("departureTime")LocalDateTime departureTime,
                                              @Param("endOfDay") LocalDateTime endOfDay);

}

服务接口:

public interface ScheduleService {

    // more methods ... 

    List<Schedule> findAllByStopsAndTimeForSearchToday(String stopName);
    List<Schedule> findAllByStopsAndTimeForSearchTomorrow(String stopName);
    List<Schedule> findAllByStopsAndTimeForSearchAfterTomorrow(String stopName);
}

服务导入:

@Service
public class ScheduleServiceImpl implements ScheduleService {
    private ScheduleRepository repository;

    @Autowired
    public ScheduleServiceImpl(ScheduleRepository repository) {
        this.repository = repository;
    }

    // more methods ... 

    @Override
    public List<Schedule> findAllByStopsAndTimeForSearchToday(String stopName) {
        LocalDateTime currentDateTime = LocalDateTime.now();
        LocalDateTime endOfDay = currentDateTime.toLocalDate().plusDays(1).atTime(LocalTime.MIDNIGHT);

        List<Schedule> scheduleToday = repository.findAllByStopsAndTimeForSearch(stopName, currentDateTime, endOfDay);
        return scheduleToday;
    }

    @Override
    public List<Schedule> findAllByStopsAndTimeForSearchTomorrow(String stopName) {
        LocalDateTime currentDateTime = LocalDateTime.now();
        LocalDateTime startOfNextDay = currentDateTime.toLocalDate().plusDays(1).atTime(LocalTime.MIDNIGHT);
        LocalDateTime endOfNextDay = startOfNextDay.toLocalDate().plusDays(1).atTime(LocalTime.MIDNIGHT);
        List<Schedule> scheduleTomorrow = repository.findAllByStopsAndTimeForSearch(stopName, startOfNextDay, endOfNextDay);
        return scheduleTomorrow;
    }

    @Override
    public List<Schedule> findAllByStopsAndTimeForSearchAfterTomorrow(String stopName) {
        LocalDateTime currentDateTime = LocalDateTime.now();
        LocalDateTime startOfNextDay = currentDateTime.toLocalDate().plusDays(2).atTime(LocalTime.MIDNIGHT);
        LocalDateTime endOfNextDay = startOfNextDay.toLocalDate().plusDays(2).atTime(LocalTime.MIDNIGHT);
        List<Schedule> scheduleAfterTomorrow = repository.findAllByStopsAndTimeForSearch(stopName, startOfNextDay, endOfNextDay);
        return scheduleAfterTomorrow;
    }
}

控制器:

@Controller
public class BusController {
    private ScheduleService scheduleService;

    @Autowired
    public BusController(ScheduleService scheduleService) {
        this.scheduleService = scheduleService;
    }

    // more methods ...

    @GetMapping("/schedule/search")
    public String searchBuses(@Valid @ModelAttribute("search") SearchDto search,
                              BindingResult bindingResult,
                              Model model){
        if(bindingResult.hasErrors()){
            LocalDateTime currentTime = LocalDateTime.now();

            model.addAttribute("time", currentTime);
            model.addAttribute("search", search);
            return "buses-list";
        }

        LocalDateTime currentTime = LocalDateTime.now();
        List<Schedule> scheduleToday = scheduleService.findAllByStopsAndTimeForSearchToday(search.getSearchLine());
        List<Schedule> scheduleTomorrow = scheduleService.findAllByStopsAndTimeForSearchTomorrow(search.getSearchLine());
        List<Schedule> scheduleAfterTomorrow = scheduleService.findAllByStopsAndTimeForSearchAfterTomorrow(search.getSearchLine());

        model.addAttribute("time", currentTime);
        model.addAttribute("scheduleToday", scheduleToday);
        model.addAttribute("scheduleTomorrow", scheduleTomorrow);
        model.addAttribute("scheduleAfterTomorrow", scheduleAfterTomorrow);
        model.addAttribute("search", new SearchDto());

        return "buses-list";
    }
}

数据库表对象如下所示:

日程安排:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "schedules")
public class Schedule {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @ManyToOne
    @JoinColumn(name = "buses_id")
    private Bus bus;
    @ManyToOne
    @JoinColumn(name = "routes_id")
    private Route route;
    private Double price;
    private String accessibility;
    private Integer seats;
    private LocalDateTime arrivalTime;
    private LocalDateTime departureTime;
}

路由:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "routes")
public class Route {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    @OneToMany(mappedBy = "route")
    private List<Schedule> schedule;
    @OneToMany(
            mappedBy = "route",
            cascade = CascadeType.ALL,
            orphanRemoval = true
    )
    private List<RoutesStops> routesStops;
}

停止:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "stops")
public class Stop {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    @OneToMany(
            mappedBy = "stop",
            cascade = CascadeType.ALL,
            orphanRemoval = true
    )
    private List<RoutesStops> routesStops;
}

路由停止ID:

@Embeddable
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class RoutesStopsId implements Serializable {
    private Long routeId;
    private Long stopId;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        RoutesStopsId that = (RoutesStopsId) o;
        return Objects.equals(routeId, that.routeId) && Objects.equals(stopId, that.stopId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(routeId, stopId);
    }
}

路由停止:

@Entity
@Table(name = "routes_stops")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class RoutesStops {
    @EmbeddedId
    private RoutesStopsId id;
    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("routeId")
    private Route route;
    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("stopId")
    private Stop stop;
    private Integer stopNumber;
    private Double price;
    private LocalTime arrivalTime;
    private LocalTime departureTime;
}

巴士:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "buses")
public class Bus {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String licensePlate;
    @OneToMany(mappedBy = "bus")
    private List<Schedule> schedule;
    @ManyToOne
    @JoinColumn(name = "company_id")
    private Company company;
}

公司:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "companies")
public class Company {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    @OneToMany(mappedBy = "company")
    private List<Bus> bus;
}

我认为问题出在对数据库的请求的构造上,或者我没有正确地组织或链接DB表.

根据我读到的其中一条建议,我将请求更改为如下内容 存储库中的方法:

@Query("SELECT DISTINCT c FROM Schedule c " +
        "JOIN Route r ON c.route " +
        "JOIN RoutesStops rs on r.routesStops " +
        "JOIN Stop s ON rs.stop " +
        "WHERE s.name = :stopName and c.departureTime >= :departureTime and c.departureTime < :endOfDay")
List<Schedule> findAllByStopsAndTimeForSearch(@Param("stopName") String stopName,
                                             @Param("departureTime")LocalDateTime departureTime,
                                             @Param("endOfDay") LocalDateTime endOfDay);

但在那之后,我得到了另一个错误:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'busController' defined in file [/Users/artem/IdeaProjects/Bus Schedule Application/target/classes/com/busschedule/web/controller/BusController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'scheduleServiceImpl' defined in file [/Users/artem/IdeaProjects/Bus Schedule Application/target/classes/com/busschedule/web/service/impl/ScheduleServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'scheduleRepository' defined in com.busschedule.web.repository.ScheduleRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Could not create query for public abstract java.util.List com.busschedule.web.repository.ScheduleRepository.findAllByStopsAndTimeForSearch(java.lang.String,java.time.LocalDateTime,java.time.LocalDateTime); Reason: Validation failed for query for method public abstract java.util.List com.busschedule.web.repository.ScheduleRepository.findAllByStopsAndTimeForSearch(java.lang.String,java.time.LocalDateTime,java.time.LocalDateTime)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-6.0.11.jar:6.0.11]
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:245) ~[spring-beans-6.0.11.jar:6.0.11]

现在我很困惑,不知道哪个错误更好,应该朝哪个方向前进

推荐答案

由于您使用的是nativeQuery(不是JPQL/HQL),因此需要正确指定联接表达式:

@Query(value = "SELECT DISTINCT c FROM schedules c " +
                "JOIN routes r ON c.routes_id = r.id " +
                "JOIN routes_stops rs on rs.route_id = r.id " +
                "JOIN stops s ON rs.stop_id = s.id" +
                "WHERE s.name = :stopName and c.departure_time >= :departureTime and c.departure_time < :endOfDay", nativeQuery = true)

Java相关问答推荐

javafx getHostServices(). showDocument()调出Chrome而不是默认浏览器(Linux)

RxJava PublishSubject缓冲区元素超时

Android Studio—java—在onBindViewHolder中,将断点和空白添加到BackclerView中

在模拟超类中设置非setter属性的值

匹配一组字符或另一组字符

如何将Java文档配置为在指定的项目根目录中生成?

有没有可能在时间范围内得到多种解决方案?

在处理2个映射表时,没有更多的数据可从套接字读取

如何在盒子的顶部和底部创建两张不同图片(大小相同)的盒子?

对从Spring Boot 3.1.5升级到3.2.0的方法的查询验证失败

在使用具有不同成本的谓词调用allMatch之前对Java流进行排序会带来什么好处吗?

当我在Java中有一个Synchronized块来递增int时,必须声明一个变量Volatile吗?

如何在运行docker的应用程序中获取指定的配置文件

在打开搜索结果时,如何让Eclipse打开整个文件?

在Java中将对象&转换为&q;HashMap(&Q)

Java HashMap保留所有时间复杂性

PhantomReference无法访问时会发生什么?

ReturnedRect在升级后反转

可以';不要在Intellij IDEA中使用最新的Java版本(JDK 21)

Hibernate 命名策略导致 Java Spring Boot 应用程序中出现未知列错误