2010-01-22 6 views
2

J'ai un code utilisant JPA avec Hibernate 3.3.x. Ce code Java peut être utilisé avec les schémas stockés sur Oracle 10g ou MySQL 5.1.x. Les tables sont définies avec des contraintes pour définir des enregistrements uniques. Lorsqu'une violation de contrainte se produit, je souhaite récupérer le nom de contrainte de l'exception.Hibernate: constraintName est null dans MySQL

Avec Oracle, le nom de la contrainte est correctement récupéré. Avec MySQL, le nom de la contrainte est NULL.

Une idée pour obtenir le nom de la contrainte avec MySQL?

Merci

Ces

Répondre

0

Vous spécifiez les noms de contrainte dans MySQL au niveau de la base de données? dans Oracle les contraintes obtiennent des noms par défaut si elles ne sont pas spécifiées, mais en MySQL je ne sais pas, je pense avoir entendu une fois que si vous ne spécifiez pas de nom pour la contrainte, MySQL n'en mettra pas une par défaut !!

+0

Oui, j'ai mis un nom comme illustré ci-dessous. ALTER TABLE MY_TABLE AJOUTER CONSTRAINT MY_CONSTRAINT UNIQUE (Col1, Col2, Col3); J'ai un script DDL pour créer le schéma de base de données pour MySQL et Oracle 10g. Les contraintes sont définies de la même manière dans les scripts DDL. Lorsque j'ai débogué mon application, j'ai vu que dans Oracle, le nom de la contrainte était celui attendu (MY_Constraint basd sur mon illustration). Lorsque je change l'unité de persistance pour activer MySQL, je reçois NULL comme nom de contrainte. – eloudsa

+0

avez-vous essayé de jeter un oeil aux noms de contraintes de votre base de données MySQL en utilisant un client SQL pour voir s'ils sont affichés ou non? –

5

Je suis venu avec la solution suivante:

  1. Étendre Hibernate MySQL5Dialect existant:

    public class MySQL5Dialect extends org.hibernate.dialect.MySQL5Dialect { 
    
        /** 
        * Pattern to extract violated constraint name from {@link SQLException}. 
        */ 
        private static final Pattern PATTERN = Pattern.compile(".*constraint\\W+(\\w+).*", Pattern.CASE_INSENSITIVE); 
    
        private ViolatedConstraintNameExtracter constraintNameExtracter; 
    
        public MySQL5Dialect() { 
         constraintNameExtracter = new ConstraintNameExtractor(); 
        } 
    
        @Override 
        public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() { 
         return constraintNameExtracter; 
        } 
    
        private class ConstraintNameExtractor implements ViolatedConstraintNameExtracter { 
    
         @Override 
         public String extractConstraintName(SQLException sqle) { 
          final String msg = sqle.getMessage(); 
          final Matcher matcher = PATTERN.matcher(msg); 
          String constraintName = null; 
          if (matcher.matches()) { 
           constraintName = matcher.group(1); 
          } 
    
          return constraintName; 
         } 
    
        } 
    
    } 
    
  2. dialecte nouvellement créé Spécifiez dans le fichier config Mise en veille prolongée (hibernate.cfg.xml):

    <property name="dialect">your.package.MySQL5Dialect</property> 
    
  3. maintenant getConstraintName() va ret urne le nom de contrainte réelle violé:

    try { 
        ... 
    } catch (ConstraintViolationException e) { 
        LOG.error(String.format("Constraint=%s, code=%d", e.getConstraintName(), e.getErrorCode())); 
    } 
    
1

Essayez cette utilisation:

try { 
// ... 
} catch (ConstraintViolationException t) { 
     if (t.getCause().getLocalizedMessage().contains("your_constraint_name")) { 
      // ... 
     } 
}