2010-01-22 71 views
2

我有一个使用JPA和Hibernate 3.3.x的代码。 此Java代码可以与存储在Oracle 10g或MySQL 5.1.x上的模式一起使用。 使用约束来定义表以定义唯一记录。 发生约束违规时,我想从异常中检索约束名称。Hibernate:constraintName在MySQL中为null

使用Oracle,可正确检索约束名称。 使用MySQL,约束名称是NULL

任何想法如何获得与MySQL约束名称?

感谢

回答

0

你在数据库级别指定在MySQL中的约束的名字呢?在Oracle中,如果没有指定,约束会得到默认名称,但是在MySQL中,我不知道,我想我曾经听说过,如果您没有为约束指定名称,MySQL不会放置默认名称!

+0

是我设置的名称,如下图所示。 ALTER TABLE MY_TABLE ADD CONSTRAINT MY_CONSTRAINT UNIQUE(Col1,Col2,Col3); 我有一个DDL脚本来为MySQL和Oracle 10g创建数据库模式。约束在bith DDL脚本中以相同的方式定义。 当我调试我的应用程序时,我看到在Oracle中约束名称是预期的(MY_Constraint基于我的插图)。 当我更改持续单元以开启MySQL时,我收到NULL作为约束名称。 – eloudsa 2010-01-22 22:19:40

+0

您是否尝试使用SQL客户端查看MySQL数据库的约束名称以查看它们是否显示? – 2010-01-24 11:04:01

5

我已经想出了以下解决方案:

  1. 扩展现有的Hibernate MySQL5Dialect:

    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. 指定的Hibernate配置文件(hibernate.cfg.xml中),新创建的话:

    <property name="dialect">your.package.MySQL5Dialect</property> 
    
  3. 现在getConstraintName()会ret瓮实际违反约束名称:

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

尝试使用这样的:

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