Hibernate的saveOrUpdate忽略非空列属性

时间:2013-06-27 19:37:54

标签: oracle hibernate

我有一个映射文件,它将给定列指定为not-null="true"。这是一个错误,因为表的列在Oracle数据库上设置为NULL。但是我们没有注意到,直到现在,创建映射文件一年多之后,因为Hibernate一直在“忽略”这个。这可能吗?

让它更清晰。在数据库上:

  

CREATE TABLE db.my_table
(...)
my_column NUMBER(10,0) NULL, (...)

在映射文件中:

  

<column name="MY_COLUMN" precision="10" scale="0" not-null="true">

然后在Java代码上:

  

getHibernateTemplate().saveOrUpdate(myEntity);

     

getHibernateTemplate().flush();

此代码正在我们的环境中运行。一直以来。但是有些客户遇到ot-null property references a null or transient value的问题,当我调试代码时没有任何意义。据我所知,此代码永远不能运行。

当然解决客户端问题很简单,我只需更正映射文件,以便正确表示我的实体。但真正的问题是为什么没有Hibernate抱怨它呢?

我已经让其他一些工程师在Hibernate上有更多的经验,但他们都没有见过这个。

那么,任何人都可以提供一些提示吗?

编辑:只是想强调我们的测试环境和我的客户端都运行完全相同的代码,并且在这两种情况下myEntity对象都具有myColumn属性设为NULL。所以,令我困惑的是为什么它不会在我们的环境中产生任何例外。

2 个答案:

答案 0 :(得分:3)

绝对正确的行为。

not-null属性有两个含义:

  • 支持架构导出工具
  • 在运行时检查实体(即不检查数据库列设置)

请参阅:5.1. Mapping declaration,摘录:

  

映射文档还包含一些额外的可选属性和   影响模式导出的数据库模式的元素   导出工具(例如,not-null属性)。

5.1.11. Property,提取:

  

not-null (可选):启用DDL生成可空性   列的约束。

因此,如果您的客户运行了一些代码,那么会尝试:

getHibernateTemplate().saveOrUpdate(myEntity);

虽然myEntity缺少某些属性设置为not-null="true",但它在抛出运行时异常时是正确的。在测试环境中,您很可能始终将属性设置为某些非空值。

甚至还有一个优点。数据库和应用程序松散耦合。因此,如果需要,您可以在App端制定更多约束,同时不触及数据库(例如,您不被允许)

答案 1 :(得分:1)

我有完全相同的问题:

在我的hibernate映射文件中,我为特殊列设置了not-null="true"

在我的开发机器上,我可以保持空值,没有任何例外。在客户计算机上,我们始终收到 a PropertyValueException / DataIntegrityViolationException

这是一种危险的行为。手动和自动测试不会失败。

<强>解决方案:

在我的开发机器上,我将属性hibernate.check_nullability设置为true。只有这样,我的开发系统才有例外。

<强>结论

这种奇怪的行为可能来自于将hibernate validator添加到类路径中。这会将check_nullability变为false。 请参阅此相关问题:How to Enable Spring Validation

不知何故,这只适用于我的开发系统,而不适用于生产。这可能源于不同应用程序服务器中的不同依赖关系加载。