Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip
14 changes: 7 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.2.RELEASE")
classpath("org.springframework.boot:spring-boot-gradle-plugin:3.2.5")
}
}

Expand All @@ -14,19 +14,19 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

bootJar {
baseName = 'gs-spring-boot'
version = '0.1.0'
archiveBaseName = 'gs-spring-boot'
archiveVersion = '0.1.0'
}

repositories {
mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8
sourceCompatibility = 21
targetCompatibility = 21

dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
testCompile("junit:junit")
implementation("org.springframework.boot:spring-boot-starter-web")
testImplementation("junit:junit")
}

2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
9 changes: 2 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,10 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<version>3.2.5</version>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-properties-migrator</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
Expand All @@ -35,7 +30,7 @@
</dependencies>

<properties>
<java.version>1.8</java.version>
<java.version>21</java.version>
</properties>


Expand Down
11 changes: 6 additions & 5 deletions src/main/java/hello/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public static void main(String[] args) {
}

RestTemplate restTemplate = new RestTemplate();
Quote quote = restTemplate.getForObject("http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
Quote quote = restTemplate.getForObject("https://jsonplaceholder.typicode.com/posts/1", Quote.class);
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 New API endpoint response schema doesn't match Quote model, resulting in all-null deserialization

The API URL was changed from the old quoters service to https://jsonplaceholder.typicode.com/posts/1, but the Quote model class was not updated. The JSONPlaceholder endpoint returns {userId, id, title, body}, while Quote (src/main/java/hello/model/Quote.java:3-34) expects type (String) and value (Value), where Value (src/main/java/hello/model/Value.java:3-33) expects id (Long) and quote (String). Since Jackson's FAIL_ON_UNKNOWN_PROPERTIES defaults to false in Jackson 2.12+, the unknown fields are silently ignored and the Quote object is created with type=null and value=null. This affects both the manual RestTemplate call in main() (line 39) and the Spring-managed bean call in run() (lines 52-53), causing the application to log meaningless Quote{type='null', value=null} output instead of actual data.

Prompt for agents
The Quote and Value model classes need to be updated to match the JSONPlaceholder /posts/1 API response format. The API returns JSON like: {userId: 1, id: 1, title: "...", body: "..."}. Either: (1) create a new model class (e.g., Post) with fields userId (int), id (int), title (String), body (String), and update both getForObject calls in Application.java to use Post.class instead of Quote.class, or (2) find a different API that returns data matching the Quote/Value model structure. The affected locations are Application.java line 39 (in main()) and lines 52-53 (in the run() CommandLineRunner bean).
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acknowledged — this is intentional and matches the original task spec, which permitted "a working placeholder or mock endpoint (e.g., https://jsonplaceholder.typicode.com/posts/1 or a local stub)" precisely because the original gturnquist-quoters.cfapps.io service is permanently dead. The bot's analysis is correct that Quote will deserialize with all null fields against the JSONPlaceholder response shape.

I deliberately did NOT modify the Quote / Value model classes because:

  1. The migration scope is "Java 8 → Java 21 / Spring Boot 2.0.2 → 3.2.5" — changing the domain model is out of scope.
  2. Quote is only used in two startup-time RestTemplate calls that just log the result; they are not part of any user-facing flow.
  3. Repointing the URL keeps the build green and the app reachable, which is the migration's actual goal. The "all-null Quote" log line is acceptable as a stub and is explicitly called out in the PR description's testing checklist (item 4).

If the team wants real data flowing through Quote again, the right follow-up is one of: (a) add a tiny local @RestController stub under src/main/java/hello/ returning a Quote-shaped JSON payload and point the RestTemplate at http://localhost:8080/..., or (b) introduce a new Post model and switch getForObject to use it. Either is a separate, non-migration change.

log.info(quote.toString());
}

Expand All @@ -50,7 +50,7 @@ public RestTemplate restTemplate(RestTemplateBuilder builder) {
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
Quote quote = restTemplate.getForObject(
"http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
"https://jsonplaceholder.typicode.com/posts/1", Quote.class);
log.info(quote.toString());
};
}
Expand All @@ -63,7 +63,7 @@ public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
public void run(String... args) throws Exception {
log.info("Creating tables");

jdbcTemplate.execute("DROP TABLE customers IF EXISTS");
jdbcTemplate.execute("DROP TABLE IF EXISTS customers");
jdbcTemplate.execute("CREATE TABLE customers(id SERIAL, first_name VARCHAR(255), last_name VARCHAR(255))");

// Split up the array of whole names into an array of first/last names
Expand All @@ -80,8 +80,9 @@ public void run(String... args) throws Exception {

log.info("Querying for customer records where first_name = 'Josh':");
jdbcTemplate.query(
"SELECT id, first_name, last_name FROM customers WHERE first_name = ?", new Object[]{"Josh"},
(rs, rowNum) -> new Customer(rs.getLong("id"), rs.getString("first_name"), rs.getString("last_name"))
"SELECT id, first_name, last_name FROM customers WHERE first_name = ?",
(rs, rowNum) -> new Customer(rs.getLong("id"), rs.getString("first_name"), rs.getString("last_name")),
"Josh"
).forEach(customer -> log.info(customer.toString()));

}
Expand Down