JPA-запрос Spring Boot Data не работает с LocalDateTime.MAX - PullRequest
0 голосов
/ 27 марта 2020

У меня есть метод:

@Query(value = "SELECT bs FROM BookedSlot bs WHERE bs.timeFrom >= :timeFrom AND bs.timeFrom < :timeTo")
Set<BookedSlot> test(@Param("timeFrom") LocalDateTime fromTime, @Param("timeTo") LocalDateTime timeTo);

И два теста

    @Sql(scripts = "/test-data.sql")
    @Test
    public void test1() {
        final Set<BookedSlot> res = unit.test(LocalDateTime.now(), LocalDateTime.MAX);
        assertNotNull(res);
        assertEquals(1, res.size());//fails
    }

    @Sql(scripts = "/test-data.sql")
    @Test
    public void test2() {
        final Set<BookedSlot> res = unit.test(LocalDateTime.now(), LocalDateTime.of(2050,1,1,1,1));
        assertNotNull(res);
        assertEquals(1, res.size());//ok
    }

И Тест-данные. sql

INSERT INTO booked_slots (id, created_at, updated_at, time_from, time_to, user_id, service_box_id)
VALUES (1, NOW(), NOW(), '2040-01-01 08:30:00.0', '2040-01-01 10:00:00.0', 1, 1);

test1 - не удается

test2 - ok

BookedSlots. java

@Entity
@Table(name = "booked_slots")
public class BookedSlot extends DbEntity implements Comparable<BookedSlot> {

    @Column(name = "time_from")
    private LocalDateTime timeFrom;
    @Column(name = "time_to")
    private LocalDateTime timeTo;
}

База данных h2 (и то же самое на MySQL 5.7, я просто использую H2 для интеграционных тестов)

test.properties

spring.datasource.url=jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=MySQL
spring.datasource.username=sa
spring.datasource.password=sa
spring.datasource.initialization-mode=always
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

Есть мысли по этому поводу?

1 Ответ

2 голосов
/ 27 марта 2020

Максимально поддерживаемый LocalDateTime равен 999999999-12-31T23:59:59.999999999. База данных не поддерживает даты, которые так далеко в будущем.

MySQL диапазон для DATETIME значений от 1000-01-01 00:00:00.000000 до 9999-12-31 23:59:59.999999


спящий-ядро: LiteralType :: objectToSQLString Преобразование значения в строковое представление, подходящее для встраивания в оператор SQL в виде литерала.

Здесь вы можете увидеть LocalDateTimeType: : objectToSQLString метод

public class LocalDateTimeType
        extends AbstractSingleColumnStandardBasicType<LocalDateTime>
        implements VersionType<LocalDateTime>, LiteralType<LocalDateTime> {

    public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss.S", Locale.ENGLISH );

    //...

    @Override
    public String objectToSQLString(LocalDateTime value, Dialect dialect) throws Exception {
        return "{ts '" + FORMATTER.format( value ) + "'}";
    }

    //..
}

для LocalDateTime.MAX возвращает {ts '+999999999-12-31 23:59:59.9'}

...