Phase 4: Replace Joda-Time with java.time#609
Conversation
Replace all org.joda.time.DateTime usage with java.time.OffsetDateTime: - Article.java, Comment.java: OffsetDateTime fields, ZoneOffset.UTC - ArticleData.java, CommentData.java: OffsetDateTime fields - DateTimeHandler.java: MyBatis TypeHandler rewritten for OffsetDateTime - DateTimeCursor.java: cursor serialization using Instant.toEpochMilli - JacksonCustomizations.java: custom serializer using DateTimeFormatter.ISO_OFFSET_DATE_TIME - ArticleQueryService.java, CommentQueryService.java: CursorPageParameter<OffsetDateTime> - ArticleDatafetcher.java, CommentDatafetcher.java: java.time formatting - CommentReadService.java: updated mapper type parameter - Test files: updated to use OffsetDateTime.now(ZoneOffset.UTC) build.gradle: - Removed joda-time:joda-time:2.10.13 dependency All 68 tests pass. Co-Authored-By: Luis Blasco <luis.blasco@cognition.ai>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
| .body(comment.getBody()) | ||
| .updatedAt(ISODateTimeFormat.dateTime().withZoneUTC().print(comment.getCreatedAt())) | ||
| .createdAt(ISODateTimeFormat.dateTime().withZoneUTC().print(comment.getCreatedAt())) | ||
| .updatedAt(comment.getCreatedAt().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)) |
There was a problem hiding this comment.
🟡 buildCommentResult uses getCreatedAt() for updatedAt instead of getUpdatedAt()
In CommentDatafetcher.buildCommentResult, the .updatedAt(...) field is populated using comment.getCreatedAt() instead of comment.getUpdatedAt(). This means the GraphQL Comment.updatedAt response field will always return the creation timestamp rather than the update timestamp. This was a pre-existing bug from the old Joda-Time code, but since the PR rewrote these lines during the migration, it carried the bug forward.
Current MyBatis mapping masks the bug
Currently in src/main/resources/mapper/TransferData.xml:35-36, both fields are mapped from the same DB column (commentCreatedAt), so the values happen to be identical. However, the comments table does have a separate updated_at column (src/main/resources/db/migration/V1__create_tables.sql:48), so the bug will surface if the query and mapping are ever fixed to use the correct column.
| .updatedAt(comment.getCreatedAt().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)) | |
| .updatedAt(comment.getUpdatedAt().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)) |
Was this helpful? React with 👍 or 👎 to provide feedback.
End-to-End Test ResultsBooted the app locally ( All 8 tests passed
Unit tests: 68 passed, 0 failures, 0 errorsKey date serialization evidenceREST response (POST /articles): "createdAt": "2026-05-21T12:59:14.573Z",
"updatedAt": "2026-05-21T12:59:14.573Z"GraphQL response ( "createdAt": "2026-05-21T12:59:14.573Z",
"updatedAt": "2026-05-21T12:59:14.573Z"REST comment (POST /articles/test-article/comments): "createdAt": "2026-05-21T12:59:42.942Z",
"updatedAt": "2026-05-21T12:59:42.942Z"Note: Pre-existing bug preserved during migration — |
Summary
Complete removal of Joda-Time dependency, replacing all
org.joda.time.DateTimeusage withjava.time.OffsetDateTimeacross 17 files.Changes by category:
Domain entities:
Article.java,Comment.java:DateTime→OffsetDateTime,new DateTime()→OffsetDateTime.now(ZoneOffset.UTC)DTOs:
ArticleData.java,CommentData.java:DateTime→OffsetDateTimefieldsInfrastructure:
DateTimeHandler.java: MyBatisTypeHandlerrewritten forOffsetDateTime(usingTimestamp.from(instant)/timestamp.toInstant().atOffset(UTC))DateTimeCursor.java: cursor serialization usingInstant.toEpochMilli()/Instant.ofEpochMilli()CommentReadService.java: updated mapper type parameterApplication/GraphQL layer:
JacksonCustomizations.java: replaced Joda serializer withDateTimeFormatter.ISO_OFFSET_DATE_TIMEArticleQueryService.java,CommentQueryService.java:CursorPageParameter<OffsetDateTime>ArticleDatafetcher.java,CommentDatafetcher.java: replacedISODateTimeFormatwithDateTimeFormatterTests:
TestHelper.java,ArticleApiTest.java,ArticlesApiTest.java,ArticleQueryServiceTest.java: updated to useOffsetDateTimebuild.gradle:
joda-time:joda-time:2.10.13dependencyAll 68 tests pass with
./gradlew test.Review & Testing Checklist for Human
./gradlew test- all 68 tests should pass./gradlew bootRunand verify REST responses serialize dates in ISO-8601 format (e.g.2026-05-21T12:30:00Z)/graphql- verifycreatedAt/updatedAtfields in article and comment queries return ISO-8601 stringsgrep -r "org.joda" src/should return nothingNotes
Phase 4 of 4. Builds on Phase 3 (PR #608). This completes the full migration from Java 11 + Spring Boot 2.6.3 to Java 17 + Spring Boot 3.4.1 with modern dependencies.
Link to Devin session: https://app.devin.ai/sessions/e28d39518c344b59883ff9b9b60cdc8b
Requested by: @luisblascocog
Devin Review