【问题标题】:H2 + Hibernate with non nullable String stores empty string具有不可为空字符串的 H2 + Hibernate 存储空字符串
【发布时间】:2013-01-16 14:10:42
【问题描述】:

我目前正在将一些现有代码从 Hibernate 3.2 迁移到 Hibernate 3.6.10.Final (顺便说一下,从 Spring 2.0 到 Spring 3.1.2)。

我遇到了一些针对 H2 数据库运行的集成测试的问题,验证了某些字段不可为空。 - 我测试尝试将空字符串插入标记为 nullable=false 的字段以异常结束 - 我检查了架构是否正确创建:该列不可为空。

  • 使用 H2(与 MySQL 模式),可空约束被忽略:在数据库中插入一个空字符串。
  • 如果我对 MySQL 数据库运行测试,我不会重现该案例。
  • 它以前与 Hibernate 3.2 一起工作

例如,如果我有一个类 Person :

@Entity
class Person {
    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable=false)
    private String name;

    //getters and setters

}

然后我有一个测试(仍然使用 JUnit3,我稍后会迁移):

@ExpectedException(value=DataIntegrityViolationException.class)
public void testPerson_NameCantBeNull() throws Exception {
    // Given
    Person person = new Person();
    person.setName(null);

    // When
    getHibernateTemplate().persist(person);
    //Flush and clear session
}

我可以通过将 nullable=false 替换为 @NotNull 注释来解决此问题,但我不想在我庞大的代码库中替换它,因为我不希望出现相同的异常。 我快速查看了 Hibernate 中的 H2Dialect 类和 JIRA 问题,但没有找到任何东西。

有人知道它是从哪里来的吗?

编辑: 一些额外的信息,我在 Hibernate 日志中添加了 TRACE 级别。

  • 当我插入 null 并且该字段标有 @Column(nullable=false) 时,我有以下日志: 2013-01-16 15:57:52 TRACE [BasicExtractor] 发现 [] 作为列 [NAME1_3_]

  • 当我插入 null 并且该字段用@Column(nullable=false)未标记时,我有以下日志: 2013-01-16 15:57:52 TRACE [BasicExtractor] 发现 [null] 作为列 [NAME1_3_]

编辑(22/01/13):

我仍然没有找到问题到底来自哪里,但我发现它与 H2 的 MySQL 模式有关:如果我禁用 MySQL 模式,Hibernate 不会再尝试用空字符串替换我的空字符串. 但我不能这样做,因为其他一些代码与 MySQL 语法相关。

有什么想法吗?

【问题讨论】:

  • 一些数据库(Oracle 是一个例子,IIRC)将空字符串视为空值 - 其他数据库则不会。听起来H2没有。当然,在 Java 本身中,这两者是非常不同的——你有任何理由相信 H2 确实将空字符串视为空值吗?
  • Sounds like MySQL 在此处的行为类似于 Oracle:“在 SQL 中,NULL 表示缺少值。在 MySQL 中,显式 NULL 也可能表示伪序列的下一个值,而隐式 NULL 可能表示由 MySQL 确定的隐式默认值(零或空字符串)。” (来自sql-info.de/mysql/gotchas.html
  • 事实上,我遇到了相反的问题:我正在测试一个带有空字符串(使用 Hibernate)的插入,它在数据库中以空字符串结尾,因此不会发生异常。
  • 啊,现在我了解测试了。正确的。并且没有构造函数将名称设置为以空字符串开头?

标签: java hibernate h2


【解决方案1】:

我没有足够的时间深入研究 Hibernate 和 MySQL 方言,所以我转向 Java Validation Framework,使用 @NotNull 注解。

它完成了这项工作并满足了我们的其他要求之一:我们模型的一部分在 Grails 应用程序中使用,我们希望使用约束来验证部分 CRUD 操作(纯 javax.persistence 注释不可能)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    相关资源
    最近更新 更多