You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot操作MongoDB遇LocalDateTime访问错误,求IntelliJ解决方案

问题:Spring Boot + MongoDB 查询LocalDateTime字段时的模块访问错误

错误信息

运行时抛出以下异常:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookingHistoryController': Unsatisfied dependency expressed through field 'bookingHistoryService': Error creating bean with name 'bookingHistoryService': Unsatisfied dependency expressed through field 'bookingHistoryRepo': Error creating bean with name 'bookingHistoryRepo' defined in hotelbookingsystem.repositories.BookingHistoryRepo defined in @EnableMongoRepositories declared on MongoRepositoriesRegistrar.EnableMongoRepositoriesConfiguration: Could not create query for public abstract java.util.List otelbookingsystem.repositories.BookingHistoryRepo.findCheckinByCustomerId(java.lang.Integer); Reason: Unable to make private java.time.LocalDateTime(java.time.LocalDate,java.time.LocalTime) accessible: module java.base does not "opens java.time" to unnamed module @77523395

根因异常:

Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make private java.time.LocalDateTime(java.time.LocalDate,java.time.LocalTime) accessible: module java.base does not "opens java.time" to unnamed module @77523395

背景

在Spring Boot应用中,尝试从MongoDB的bookinghistories集合按customer_id查询checkin_date字段,返回LocalDateTime列表。已编写原生MongoDB查询的Repository方法,但触发上述模块访问错误。已知可通过--add-opens java.base/java.time=ALL-UNNAMED参数解决,希望了解IntelliJ中的最优实现方式。

相关代码

实体类BookingHistory

package hotelbookingsystem.documents;

import java.time.LocalDateTime;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import org.springframework.format.annotation.DateTimeFormat;

@Document(collection = "bookinghistories")
public class BookingHistory {

    @Id
    @Field(name = "_id")
    private String id;

    @Field(name = "customer_id")
    private Integer customerId;

    @Field(name = "room_number")
    private Integer roomNumber;

    @Field(name = "checkin_date")
    private LocalDateTime checkinDate;

    @Field(name = "checkout_date")
    private LocalDateTime checkoutDate;

    @Field(name = "days_of_stay")
    private Integer daysOfStay;

    public BookingHistory(String id, Integer customerId, Integer roomNumber, LocalDateTime checkinDate,
                          LocalDateTime checkoutDate, Integer daysOfStay) {
        super();
        this.id = id;
        this.customerId = customerId;
        this.roomNumber = roomNumber;
        this.checkinDate = checkinDate;
        this.checkoutDate = checkoutDate;
        this.daysOfStay = daysOfStay;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Integer getCustomerId() {
        return customerId;
    }

    public void setCustomerId(Integer customerId) {
        this.customerId = customerId;
    }

    public Integer getRoomNumber() {
        return roomNumber;
    }

    public void setRoomNumber(Integer roomNumber) {
        this.roomNumber = roomNumber;
    }

    public LocalDateTime getCheckinDate() {
        return checkinDate;
    }

    public void setCheckinDate(LocalDateTime checkinDate) {
        this.checkinDate = checkinDate;
    }

    public LocalDateTime getCheckoutDate() {
        return checkoutDate;
    }

    public void setCheckoutDate(LocalDateTime checkoutDate) {
        this.checkoutDate = checkoutDate;
    }

    public Integer getDaysOfStay() {
        return daysOfStay;
    }

    public void setDaysOfStay(Integer daysOfStay) {
        this.daysOfStay = daysOfStay;
    }
}

Repository接口BookingHistoryRepo

package hotelbookingsystem.repositories;

import hotelbookingsystem.documents.BookingHistory;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;

import java.time.LocalDateTime;
import java.util.List;

public interface BookingHistoryRepo extends MongoRepository<BookingHistory, Integer> {

    @Query(value = "{customer_id : ?0}", fields = "{_id: 0, checkin_date: 1}")
    List<LocalDateTime> findCheckinByCustomerId(Integer customerId);

}

解决方案

方案1:修改Repository返回类型(最优)

直接返回LocalDateTime列表会导致Spring Data MongoDB反射访问LocalDateTime的私有构造器,触发模块权限问题。推荐以下两种更规范的实现方式:

方式A:使用投影接口

定义仅包含目标字段的投影接口,Spring Data会自动实现该接口并映射数据:

// 新增投影接口
public interface CheckinDateProjection {
    LocalDateTime getCheckinDate();
}

// 修改Repository方法
@Query(value = "{customer_id : ?0}", fields = "{_id: 0, checkin_date: 1}")
List<CheckinDateProjection> findCheckinByCustomerId(Integer customerId);

在业务层提取日期:

List<LocalDateTime> checkinDates = bookingHistoryRepo.findCheckinByCustomerId(customerId)
    .stream()
    .map(CheckinDateProjection::getCheckinDate)
    .collect(Collectors.toList());

方式B:返回实体类列表后提取字段

简化Repository方法,返回完整的BookingHistory列表,再在业务层提取目标字段:

// 修改Repository方法
List<BookingHistory> findByCustomerId(Integer customerId);

业务层处理:

List<LocalDateTime> checkinDates = bookingHistoryRepo.findByCustomerId(customerId)
    .stream()
    .map(BookingHistory::getCheckinDate)
    .collect(Collectors.toList());

方案2:在IntelliJ中添加VM参数

若需保留原Repository方法,可通过添加VM参数解决模块权限问题:

  • 打开Run/Debug Configurations(右上角运行配置下拉框 → Edit Configurations...)
  • 选择你的Spring Boot应用配置
  • 在VM options输入框中添加:--add-opens java.base/java.time=ALL-UNNAMED
  • 保存配置后启动应用

内容的提问来源于stack exchange,提问作者Govardhan Lingampalli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 19:43:10