Skip to content
Share
Explore

Scenario: “Placing Order Fails in Microservice Landscape”


Architecture (simplified):
API Gateway → order-service → inventory-service → Oracle DB

Users say:
“When we click Place Order, we get ‘Internal Server Error’. Logging in and viewing products works fine, only placing order fails.”
You are looking at order-service logs.

Full-Length Log (Order-Service):
2025-11-09 10:14:32.101 INFO 18432 --- [ main] c.c.o.OrderServiceApplication : Starting OrderServiceApplication v1.4.2 on app-node-01 with PID 18432 (/opt/order-service/app.jar started by svcuser in /opt/order-service)
2025-11-09 10:14:32.105 INFO 18432 --- [ main] c.c.o.OrderServiceApplication : No active profile set, falling back to default profiles: default
2025-11-09 10:14:33.890 INFO 18432 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8081 (http)
2025-11-09 10:14:33.915 INFO 18432 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2025-11-09 10:14:33.916 INFO 18432 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.89]
2025-11-09 10:14:34.102 INFO 18432 --- [ main] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
2025-11-09 10:14:35.432 INFO 18432 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2025-11-09 10:14:35.987 INFO 18432 --- [ main] c.c.o.OrderServiceApplication : Started OrderServiceApplication in 4.356 seconds (JVM running for 4.947)

2025-11-09 10:15:01.054 INFO 18432 --- [nio-8081-exec-3] c.c.o.controller.OrderController : Received request to place order for userId=1042, items=[P1001, P2009]
2025-11-09 10:15:01.312 INFO 18432 --- [nio-8081-exec-3] c.c.o.service.InventoryClient : Calling inventory-service: http://inventory-service:8082/api/stock/check

2025-11-09 10:15:02.421 ERROR 18432 --- [nio-8081-exec-3] o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.web.client.HttpServerErrorException$InternalServerError: 500 : "Internal Server Error"]

org.springframework.web.client.HttpServerErrorException$InternalServerError: 500 : "Internal Server Error"
at org.springframework.web.client.HttpServerErrorException.create(HttpServerErrorException.java:100)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:186)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:125)
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:890)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:858)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:776)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:357)
at com.company.order.service.InventoryClient.checkAvailability(InventoryClient.java:48)
at com.company.order.service.OrderService.validateAndPlaceOrder(OrderService.java:72)
at com.company.order.controller.OrderController.placeOrder(OrderController.java:51)
...

2025-11-09 10:15:02.428 WARN 18432 --- [nio-8081-exec-3] c.c.o.controller.OrderController : Error while placing order for userId=1042

2025-11-09 10:15:02.429 INFO 18432 --- [nio-8081-exec-3] c.c.o.controller.OrderController : Returning HTTP 500 with message='Unable to place order, please try again later'

# Now you open logs of inventory-service (downstream microservice)

2025-11-09 10:14:30.550 INFO 19120 --- [ main] c.c.i.InventoryServiceApplication : Starting InventoryServiceApplication v2.1.0 on app-node-02 with PID 19120 (/opt/inventory-service/app.jar started by svcuser in /opt/inventory-service)
2025-11-09 10:14:31.878 INFO 19120 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8082 (http)
2025-11-09 10:14:33.104 INFO 19120 --- [ main] c.c.i.InventoryServiceApplication : Started InventoryServiceApplication in 2.812 seconds (JVM running for 3.232)

2025-11-09 10:15:01.317 INFO 19120 --- [nio-8082-exec-1] c.c.i.controller.StockController : Received stock check request for items=[P1001, P2009]

2025-11-09 10:15:01.599 ERROR 19120 --- [nio-8082-exec-1] c.c.i.service.StockService : Error while checking stock in database

org.springframework.dao.DataAccessResourceFailureException: Could not execute JDBC batch update; SQL [select product_code, qty from INVENTORY where product_code in (?)]; nested exception is java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:95)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:82)
at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1444)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:632)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:669)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:700)
at com.company.inventory.repository.InventoryRepository.findStock(InventoryRepository.java:41)
at com.company.inventory.service.StockService.checkStock(StockService.java:58)
at com.company.inventory.controller.StockController.checkAvailability(StockController.java:44)
...

Caused by: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1059)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:522)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:587)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:225)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:53)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:774)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:925)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1111)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:4798)
...

2025-11-09 10:15:01.603 ERROR 19120 --- [nio-8082-exec-1] o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [select product_code, qty from INVENTORY where product_code in (?)]; nested exception is java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist]

2025-11-09 10:15:01.605 WARN 19120 --- [nio-8082-exec-1] c.c.i.controller.StockController : Sending HTTP 500 to caller due to DB error: ORA-00942


Step-by-Step Breakdown

You can walk them through like this:

Step 1 – Start from the symptom

Ask your learners:
“What did the user see?”
From description:
User gets Internal Server Error when placing order.
Other parts of the app work (login, view products).
So: The problem is related to order placement flow, not entire system down.

Step 2 – Look at order-service first (the service handling the request)

Show this part:
2025-11-09 10:15:01.054 INFO ... OrderController : Received request to place order ...
2025-11-09 10:15:01.312 INFO ... InventoryClient : Calling inventory-service: http://inventory-service:8082/api/stock/check
2025-11-09 10:15:02.421 ERROR ... ExceptionHandlerExceptionResolver : Resolved [HttpServerErrorException$InternalServerError: 500 : "Internal Server Error"]

Ask:
“Is order-service itself throwing an exception from its own code, or is it unhappy with a downstream service?”
We see HttpServerErrorException$InternalServerError → order-service got 500 from inventory-service.
“What does that tell you about where to look next?”
Next, we must check inventory-service logs.
Key teaching point: order-service is not the origin, it’s just propagating a 500 from inventory-service.

Step 3 – Jump into inventory-service logs

Now focus on the detailed error:
2025-11-09 10:15:01.599 ERROR ... StockService : Error while checking stock in database

org.springframework.dao.DataAccessResourceFailureException: Could not execute JDBC batch update; SQL [select product_code, qty from INVENTORY where product_code in (?)]; nested exception is java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
...
Caused by: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
...

Questions to ask the class:
“Where do you see the real root cause?”
Here: Caused by: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
“What does ORA-00942 mean in plain English?”
The table or view we’re querying does not exist in the DB (or in that schema).
“Is this App / DB / Infra?”
This is a DB schema / SQL issue (DB side / data layer).
“Which table is the problem?”
It is trying to query INVENTORY table.
So:
Root cause: Inventory-Service is using SQL that refers to a table (INVENTORY) which does not exist (or not in that schema).

Step 4 – Understanding the exception chain

Explain how to read the chain:
Outer exception:
org.springframework.dao.DataAccessResourceFailureException: Could not execute JDBC batch update...

This is Spring’s generic data access wrapper.
Caused by:
Caused by: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist

This is the database’s own specific error.
Teaching phrase you can use:
“Whenever you see a long stack trace, scroll down to the last Caused by — that’s where the DB/driver/JVM tells you what actually went wrong.”

Step 5 – Connect back to microservice chain

Let them connect the dots:
Pricing request from user → API Gateway → order-service /placeOrder
order-service → calls inventory-service /api/stock/check
inventory-service → calls DB with bad SQL (table missing)
DB returns ORA-00942 → inventory-service throws 500
order-service receives 500 → throws 500 to gateway
User sees “Internal Server Error”.
So the origin is:
DB schema / table missing in inventory-service behavior, not in order-service, not in gateway, not in network.
You can even draw the chain on whiteboard and put a big red X on the DB leg.

Step 6 – First Actions (what a good L1/L2 should do)

Ask them:
“If you were on shift, what 3 things would you do now?”
Expected answers (you can nudge them):
Verify table existence
Login to DB:
SELECT * FROM INVENTORY;

Does it exist? Correct schema?
Check deployment/migration
Was there a recent release?
Did migration scripts run?
Did we change schema/user?
Communicate clearly in ticket Example template:
“Order placement is failing because inventory-service is getting a DB error ORA-00942: table or view does not exist when querying table INVENTORY. Root cause appears to be missing or incorrect DB schema/table. Requesting DB/schema team to validate and create/restore the table or update configuration.”
This reinforces root cause → domain → next action → communication.

How You Can Use This in Class

Give them only the logs first (without your breakdown).
Ask them in small groups:
Where is the root cause?
App / DB / Infra?
What are your first 2 actions?
Then walk through the step-by-step breakdown above.
End with a short recap:
“When you see logs in microservices: 1️⃣ Start from the service closest to the user’s error 2️⃣ Follow the chain to downstream services 3️⃣ In each stack trace, scroll to the last Caused by 4️⃣ Classify (App / DB / Infra) 5️⃣ Decide clear, small next steps and log them in the ticket.”
Want to print your doc?
This is not the way.
Try clicking the ··· in the right corner or using a keyboard shortcut (
CtrlP
) instead.