Home โบ Java exceptions โบ DataIntegrityViolationException
DataIntegrityViolationException: causes and fixes
Spring's translation of a database integrity constraint failure such as a duplicate key or a NOT NULL violation.
What it looks like
org.springframework.dao.DataIntegrityViolationException: could not execute statement [Duplicate entry ...] [insert into users ...]Extends NonTransientDataAccessException in org.springframework.dao.
What it means
Spring Data and JdbcTemplate catch vendor-specific SQL exceptions and rethrow them as members of Spring's DataAccessException hierarchy, so that service code does not depend on the database. DataIntegrityViolationException is the umbrella for constraint violations. Under it sits DuplicateKeyException for unique key collisions. The original SQLException, with the vendor message naming the constraint, is the root cause at the bottom of the trace.
Common causes
- A unique constraint hit by a duplicate insert or update.
- A foreign key violation when saving a child whose parent is missing or deleting a parent that is referenced.
- A NOT NULL or CHECK constraint failing, or a value too long for the column ("Data too long for column").
- Concurrent transactions inserting the same natural key.
How to fix it
- Scroll to the root cause and read the constraint name and column.
- Catch DataIntegrityViolationException at the service boundary and translate it into a domain error or an HTTP 409 Conflict.
- Validate lengths and nulls with Bean Validation before they reach the database.
- Make operations idempotent (upsert, unique request ids) where retries can repeat an insert.
Broken and fixed
@PostMapping
public User create(@RequestBody User u) {
return repo.save(u); // duplicate email -> 500@ExceptionHandler(DataIntegrityViolationException.class)
ResponseEntity<String> conflict(DataIntegrityViolationException e) {
return ResponseEntity.status(409).body("Already exists");
}๐ Unravel the failing code ๐ Unravel the fix
In Spring and enterprise code
Inside a @Transactional method the exception may only surface at commit time, after your catch block, because JPA flushes late. Call saveAndFlush to fail early.
Debug it faster
Paste the whole stack trace into the stack trace beautifier to hide framework frames, jump to the root cause and find the first line of your own code. It runs in your browser, so the trace never leaves your machine.
Frequently asked questions
Is DataIntegrityViolationException a checked or unchecked exception?
DataIntegrityViolationException is an unchecked exception (it extends NonTransientDataAccessException, which is a RuntimeException), so you are not forced to catch it. Prevent it with validation, or handle it where the input enters the system.
Which package is DataIntegrityViolationException in?
It lives in org.springframework.dao, so the import is import org.springframework.dao.DataIntegrityViolationException;.
What is the first thing to check when I see DataIntegrityViolationException?
Read the message and the first stack trace line in your own code. The usual causes are: A unique constraint hit by a duplicate insert or update; and A foreign key violation when saving a child whose parent is missing or deleting a parent that is referenced.