Skip to content

Commit abaf8a7

Browse files
wynnteoWynn Teo
andauthored
Bael 6855 (#18870)
* BAEL-6855 * Test --------- Co-authored-by: Wynn Teo <[email protected]>
1 parent f6a0a01 commit abaf8a7

File tree

6 files changed

+280
-0
lines changed

6 files changed

+280
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.baeldung.jpa.localdatetimequery;
2+
3+
import jakarta.persistence.*;
4+
import java.time.LocalDateTime;
5+
6+
@Entity
7+
@Table(name = "events")
8+
public class Event {
9+
@Id
10+
@GeneratedValue(strategy = GenerationType.IDENTITY)
11+
private Long id;
12+
private String name;
13+
private LocalDateTime createdAt;
14+
private LocalDateTime updatedAt;
15+
16+
public Event() {}
17+
18+
public Event(String name, LocalDateTime createdAt) {
19+
this.name = name;
20+
this.createdAt = createdAt;
21+
}
22+
23+
@PreUpdate
24+
protected void onUpdate() {
25+
updatedAt = LocalDateTime.now();
26+
}
27+
28+
// Getters and setters
29+
public Long getId() {
30+
return id;
31+
}
32+
33+
public void setId(Long id) {
34+
this.id = id;
35+
}
36+
37+
public String getName() {
38+
return name;
39+
}
40+
41+
public void setName(String name) {
42+
this.name = name;
43+
}
44+
45+
public LocalDateTime getCreatedAt() {
46+
return createdAt;
47+
}
48+
49+
public void setCreatedAt(LocalDateTime createdAt) {
50+
this.createdAt = createdAt;
51+
}
52+
53+
public LocalDateTime getUpdatedAt() {
54+
return updatedAt;
55+
}
56+
57+
public void setUpdatedAt(LocalDateTime updatedAt) {
58+
this.updatedAt = updatedAt;
59+
}
60+
61+
@Override
62+
public String toString() {
63+
return "Event{" +
64+
"id=" + id +
65+
", name='" + name + '\'' +
66+
", createdAt=" + createdAt +
67+
", updatedAt=" + updatedAt +
68+
'}';
69+
}
70+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.baeldung.jpa.localdatetimequery;
2+
3+
import java.time.LocalDate;
4+
import java.time.LocalDateTime;
5+
import java.util.List;
6+
7+
import org.springframework.stereotype.Repository;
8+
9+
import jakarta.persistence.EntityManager;
10+
import jakarta.persistence.PersistenceContext;
11+
import jakarta.persistence.criteria.CriteriaBuilder;
12+
import jakarta.persistence.criteria.CriteriaQuery;
13+
import jakarta.persistence.criteria.Root;
14+
15+
@Repository
16+
public class EventCriteriaRepository {
17+
18+
@PersistenceContext
19+
private EntityManager entityManager;
20+
21+
public List<Event> findByCreatedDate(LocalDate date) {
22+
LocalDateTime startOfDay = date.atStartOfDay();
23+
LocalDateTime endOfDay = date.plusDays(1).atStartOfDay();
24+
25+
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
26+
CriteriaQuery<Event> cq = cb.createQuery(Event.class);
27+
Root<Event> root = cq.from(Event.class);
28+
29+
cq.select(root).where(
30+
cb.between(root.get("createdAt"), startOfDay, endOfDay)
31+
);
32+
33+
return entityManager.createQuery(cq).getResultList();
34+
}
35+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.baeldung.jpa.localdatetimequery;
2+
3+
import org.springframework.data.jpa.repository.JpaRepository;
4+
import org.springframework.data.jpa.repository.Query;
5+
import org.springframework.data.repository.query.Param;
6+
import java.time.LocalDate;
7+
import java.time.LocalDateTime;
8+
import java.util.List;
9+
10+
public interface EventRepository extends JpaRepository<Event, Long> {
11+
12+
List<Event> findByCreatedAtBetween(LocalDateTime start, LocalDateTime end);
13+
14+
List<Event> findByCreatedAtGreaterThanEqualAndCreatedAtLessThan(
15+
LocalDateTime start,
16+
LocalDateTime end
17+
);
18+
19+
20+
@Query("SELECT e FROM Event e WHERE FUNCTION('DATE', e.createdAt) = :date")
21+
List<Event> findByDate(@Param("date") LocalDate date);
22+
23+
@Query(
24+
value = "SELECT * FROM events " +
25+
"WHERE created_at >= :startOfDay " +
26+
"AND created_at < :endOfDay",
27+
nativeQuery = true
28+
)
29+
List<Event> findByDateRangeNative(
30+
@Param("startOfDay") LocalDateTime startOfDay,
31+
@Param("endOfDay") LocalDateTime endOfDay
32+
);
33+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.baeldung.jpa.localdatetimequery;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication
7+
public class LocalDateTimeQueryApplication {
8+
9+
public static void main(String[] args) {
10+
SpringApplication.run(LocalDateTimeQueryApplication.class, args);
11+
}
12+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
spring.datasource.url=jdbc:h2:mem:testdb;MODE=MySQL
2+
spring.datasource.driverClassName=org.h2.Driver
3+
spring.datasource.username=sa
4+
spring.datasource.password=
5+
6+
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
7+
spring.jpa.hibernate.ddl-auto=create-drop
8+
spring.jpa.show-sql=false
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package com.baeldung.jpa.localdatetimequery;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import java.time.LocalDate;
6+
import java.time.LocalDateTime;
7+
import java.util.List;
8+
9+
import org.junit.jupiter.api.BeforeEach;
10+
import org.junit.jupiter.api.Test;
11+
import org.springframework.beans.factory.annotation.Autowired;
12+
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
13+
import org.springframework.context.annotation.Import;
14+
15+
@DataJpaTest
16+
@Import(EventCriteriaRepository.class)
17+
public class EventRepositoryUnitTest {
18+
@Autowired
19+
private EventRepository eventRepository;
20+
21+
@Autowired
22+
private EventCriteriaRepository eventCriteriaRepository;
23+
24+
private LocalDate testDate;
25+
26+
@BeforeEach
27+
public void setUp() {
28+
testDate = LocalDate.of(2025, 10, 12);
29+
30+
eventRepository.deleteAll();
31+
32+
eventRepository.save(new Event("Morning Meeting", LocalDateTime.of(2025, 10, 12, 9, 0, 0)));
33+
eventRepository.save(new Event("Lunch Discussion", LocalDateTime.of(2025, 10, 12, 12, 30, 0)));
34+
eventRepository.save(new Event("Evening Review", LocalDateTime.of(2025, 10, 12, 18, 45, 0)));
35+
eventRepository.save(new Event("Next Day Planning", LocalDateTime.of(2025, 10, 13, 10, 0, 0)));
36+
}
37+
@Test
38+
public void givenLocalDateAndEventsWithTimestamps_whenQueryUsingBetween_thenReturnAllEventsForThatDay() {
39+
LocalDateTime startOfDay = testDate.atStartOfDay();
40+
LocalDateTime endOfDay = testDate.plusDays(1).atStartOfDay();
41+
42+
List<Event> results = eventRepository.findByCreatedAtBetween(startOfDay, endOfDay);
43+
44+
assertEquals(3, results.size());
45+
assertEquals("Morning Meeting", results.get(0).getName());
46+
assertEquals("Lunch Discussion", results.get(1).getName());
47+
assertEquals("Evening Review", results.get(2).getName());
48+
}
49+
50+
@Test
51+
public void givenLocalDateAndEventsWithTimestamps_whenQueryUsingExplicitBoundaries_thenReturnAllEventsForThatDay() {
52+
LocalDateTime startOfDay = testDate.atStartOfDay();
53+
LocalDateTime endOfDay = testDate.plusDays(1).atStartOfDay();
54+
55+
List<Event> results = eventRepository.findByCreatedAtGreaterThanEqualAndCreatedAtLessThan(startOfDay, endOfDay);
56+
57+
assertEquals(3, results.size());
58+
assertEquals("Morning Meeting", results.get(0).getName());
59+
assertEquals("Lunch Discussion", results.get(1).getName());
60+
assertEquals("Evening Review", results.get(2).getName());
61+
}
62+
63+
// @Test
64+
// public void givenLocalDateAndEventsWithTimestamps_whenQueryUsingJpqlDateFunction_thenReturnAllEventsForThatDay() {
65+
// LocalDate queryDate = LocalDate.of(2025, 10, 12);
66+
//
67+
// List<Event> results = eventRepository.findByDate(queryDate);
68+
//
69+
// assertEquals(3, results.size());
70+
// assertEquals("Morning Meeting", results.get(0).getName());
71+
// assertEquals("Lunch Discussion", results.get(1).getName());
72+
// assertEquals("Evening Review", results.get(2).getName());
73+
// }
74+
75+
@Test
76+
public void givenLocalDateAndEventsWithTimestamps_whenQueryUsingCriteriaApi_thenReturnAllEventsForThatDay() {
77+
LocalDate queryDate = LocalDate.of(2025, 10, 12);
78+
79+
List<Event> results = eventCriteriaRepository.findByCreatedDate(queryDate);
80+
81+
assertEquals(3, results.size());
82+
assertEquals("Morning Meeting", results.get(0).getName());
83+
assertEquals("Lunch Discussion", results.get(1).getName());
84+
assertEquals("Evening Review", results.get(2).getName());
85+
}
86+
87+
@Test
88+
public void givenLocalDateAndEventsWithTimestamps_whenQueryUsingNativeSql_thenReturnAllEventsForThatDay() {
89+
LocalDateTime startOfDay = testDate.atStartOfDay();
90+
LocalDateTime endOfDay = testDate.plusDays(1).atStartOfDay();
91+
92+
List<Event> results = eventRepository.findByDateRangeNative(startOfDay, endOfDay);
93+
94+
assertEquals(3, results.size());
95+
assertEquals("Morning Meeting", results.get(0).getName());
96+
assertEquals("Lunch Discussion", results.get(1).getName());
97+
assertEquals("Evening Review", results.get(2).getName());
98+
}
99+
100+
@Test
101+
public void givenLocalDateForDifferentDay_whenQueryUsingBetween_thenReturnOnlyEventForThatDay() {
102+
LocalDate differentDate = LocalDate.of(2025, 10, 13);
103+
LocalDateTime startOfDay = differentDate.atStartOfDay();
104+
LocalDateTime endOfDay = differentDate.plusDays(1).atStartOfDay();
105+
106+
List<Event> results = eventRepository.findByCreatedAtBetween(startOfDay, endOfDay);
107+
108+
assertEquals(1, results.size());
109+
assertEquals("Next Day Planning", results.get(0).getName());
110+
}
111+
112+
@Test
113+
public void givenNoEventsForDate_whenQueryUsingBetween_thenReturnEmptyList() {
114+
LocalDate emptyDate = LocalDate.of(2025, 10, 14);
115+
LocalDateTime startOfDay = emptyDate.atStartOfDay();
116+
LocalDateTime endOfDay = emptyDate.plusDays(1).atStartOfDay();
117+
118+
List<Event> results = eventRepository.findByCreatedAtBetween(startOfDay, endOfDay);
119+
120+
assertEquals(0, results.size());
121+
}
122+
}

0 commit comments

Comments
 (0)