【问题标题】:Hibernate: constraintName is null in MySQL休眠:MySQL 中的约束名称为空
【发布时间】:2010-01-22 15:22:13
【问题描述】:

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

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

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

谢谢

【问题讨论】:

    标签: mysql hibernate constraints


    【解决方案1】:

    我想出了以下解决方案:

    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() 将返回实际违反的约束名称:

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

    【讨论】:

      【解决方案2】:

      试试这个:

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

      【讨论】:

        【解决方案3】:

        您是否在数据库级别指定 MySQL 中的约束名称?在 Oracle 中,如果未指定,约束将获得默认名称,但是在 MySQL 中我不知道,我想我曾经听说过,如果您不为约束指定名称,MySQL 将不会设置默认名称!

        【讨论】:

        • 是的,我设置了如下图所示的名称。 ALTER TABLE MY_TABLE 添加约束 MY_CONSTRAINT 唯一(Col1,Col2,Col3);我有一个 DDL 脚本来为 MySQL 和 Oracle 10g 创建数据库模式。约束在 bith DDL 脚本中的定义方式相同。当我调试我的应用程序时,我在 Oracle 中看到约束名称是预期的(MY_Constraint 基于我的插图)。当我更改持久性单元以打开 MySQL 时,我收到 NULL 作为约束名称。
        • 您是否尝试使用 SQL 客户端查看 MySQL 数据库的约束名称以查看它们是否显示?
        猜你喜欢
        • 2016-12-20
        • 2017-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多