如何通过JPA将存储过程输出的DateTime读取到Java对象中?
Let's walk through fixing this issue step by step—your problem boils down to matching the correct Java type to SQL Server's DATETIME to avoid losing time data or hitting mapping errors.
1. Spot the Type Mismatch
Your current code uses java.sql.Date for the timestamp output parameter, but there's a critical mismatch here:
java.sql.Dateonly maps to SQLDATEtypes (which store date without time)- SQL Server's
DATETIMEincludes both date and time components, so you need a type that preserves both. The best options are:java.sql.Timestamp(legacy Java SQL type, works with all JPA providers)java.time.LocalDateTime(Java 8+ modern time API, supported by Hibernate 5.2+ and newer JPA implementations)
2. Update the JPA Stored Procedure Code
Here's the fixed implementation using java.sql.Timestamp first (compatible with most setups):
import java.sql.Timestamp; import java.time.LocalDateTime; // ... other necessary imports // Configure the stored procedure query StoredProcedureQuery storedProcedure = em.createStoredProcedureQuery("dbo.GetErrorandTimestampDetails") .registerStoredProcedureParameter("IncidentID", Integer.class, ParameterMode.IN) .registerStoredProcedureParameter("Errorcount", Integer.class, ParameterMode.OUT) // Replace Date.class with Timestamp.class to capture full date+time .registerStoredProcedureParameter("timestamp", Timestamp.class, ParameterMode.OUT) .setParameter("IncidentID", incidentID); // Execute the procedure boolean executionStatus = storedProcedure.execute(); // Retrieve output values Integer errorCount = (Integer) storedProcedure.getOutputParameterValue("Errorcount"); Timestamp sqlTimestamp = (Timestamp) storedProcedure.getOutputParameterValue("timestamp"); // Optional: Convert to modern LocalDateTime for easier handling LocalDateTime incidentTimestamp = sqlTimestamp.toLocalDateTime();
If you're using Java 8+ and a modern JPA provider (like Hibernate 5.2+), you can use LocalDateTime directly without conversion:
import java.time.LocalDateTime; // ... other necessary imports StoredProcedureQuery storedProcedure = em.createStoredProcedureQuery("dbo.GetErrorandTimestampDetails") .registerStoredProcedureParameter("IncidentID", Integer.class, ParameterMode.IN) .registerStoredProcedureParameter("Errorcount", Integer.class, ParameterMode.OUT) // Use LocalDateTime.class directly for the output parameter .registerStoredProcedureParameter("timestamp", LocalDateTime.class, ParameterMode.OUT) .setParameter("IncidentID", incidentID); storedProcedure.execute(); Integer errorCount = (Integer) storedProcedure.getOutputParameterValue("Errorcount"); LocalDateTime incidentTimestamp = (LocalDateTime) storedProcedure.getOutputParameterValue("timestamp");
3. Quick Check on the Stored Procedure
Your existing SQL Server stored procedure is correctly pulling the DATETIME value from Incident_Info.[Date Added]—no changes needed there.
Key Takeaways
- Always align SQL types with their correct Java counterparts to prevent data loss (like truncated time) or runtime mapping exceptions.
- If you're on Java 8+, stick to the
java.timeAPI classes (likeLocalDateTime) for cleaner, more maintainable code compared to legacyjava.sqltypes.
内容的提问来源于stack exchange,提问作者Prateek Narendra

