Catching constraint violations in JPA 2.0
Consider the following entity class, used with, for example, EclipseLink 2.0.2 - where the link
attribute is not the开发者_JS百科 primary key, but unique nontheless.
@Entity
public class Profile {
@Id
private Long id;
@Column(unique = true)
private String link;
// Some more attributes and getter and setter methods
}
When I insert records with a duplicate value for the link
attribute, EclipseLink does not throw a EntityExistsException
, but throws a DatabaseException
, with the message explaining that the unique constraint was violated.
This doesn't seem very usefull, as there would not be a simple, database independent, way to catch this exception. What would be the advised way to deal with this?
A few things that I have considered are:
- Checking the error code on the
DatabaseException
- I fear that this error code, though, is the native error code for the database; - Checking the existence of a
Profile
with the specific value forlink
beforehand - this obviously would result in an enormous amount of superfluous queries.
When I insert records with a duplicate value for the link attribute, EclipseLink does not throw a EntityExistsException
Yes, and a JPA provider is not supposed to throw an EntityExistException
in that case, you won't get an EntityExistException
on something else than the primary key.
(...) but throws a DatabaseException, with the message explaining that the unique constraint was violated.
This is very WRONG from EclipseLink, a JPA provider should throw a PersistenceException
or a subclass but certainly not a specific exception like o.e.p.e.DatabaseException
. This is a bug and should be reported as such as I already mentioned in a previous answer.
This doesn't seem very usefull, as there would not be a simple, database independent, way to catch this exception. What would be the advised way to deal with this?
Same answer as above, see my previous answer.
It's too bad they don't have a ConstraintViolationException in JPA. I've created a helper method to determine if the PersistenceException is a constraint violation for a given class - it is hibernate only though. I imagine there is a way to do it using other implementations.
protected Boolean isUniqueConstraintViolation(PersistenceException ex, Class entity) {
if (((NonUniqueObjectException)ex.getCause()).getEntityName().equals(entity.getName())) {
return true;
}
return false;
}
精彩评论