Hibernate:在MySQL中,constraintName为null

elo*_*dsa 2 mysql hibernate constraints

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

使用Oracle,可以正确检索约束名称.使用MySQL,约束名称为NULL.

知道如何用MySQL获取约束名称吗?

谢谢

说过

小智 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;
            }
    
        }
    
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在Hibernate配置文件(hibernate.cfg.xml)中指定新创建的方言:

    <property name="dialect">your.package.MySQL5Dialect</property>
    
    Run Code Online (Sandbox Code Playgroud)
  3. 现在getConstraintName()将返回实际违反的约束名称:

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