11

Consider the following entity class, used with, for example, EclipseLink 2.0.2 - where the link attribute is not the 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 for link beforehand - this obviously would result in an enormous amount of superfluous queries.
wen
  • 3,782
  • 9
  • 34
  • 54
  • I have submitted a bug for this issue. Please vote for it so we can get this issue fixed: https://bugs.eclipse.org/bugs/show_bug.cgi?id=375745 – sdoca Mar 30 '12 at 17:01

2 Answers2

5

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.

Community
  • 1
  • 1
Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • Since you mention EclipseLink in particular here: Do you know of other JPA providers who behave correctly? – Hank Sep 29 '10 at 10:31
  • @Hank Maybe the problem is fixed in recent versions, can't say. But to my knowledge, Hibernate does thrown a `PersistenceException` in such case. – Pascal Thivent Sep 29 '10 at 15:31
2

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;
}
Brian DiCasa
  • 9,369
  • 18
  • 65
  • 97