使用 Hibernate 设置与数据库无关的默认列时间戳

Posted

技术标签:

【中文标题】使用 Hibernate 设置与数据库无关的默认列时间戳【英文标题】:Setting database-agnostic default column timestamp using Hibernate 【发布时间】:2010-06-08 18:22:30 【问题描述】:

我正在开发一个包含 Hibernate (3.3.1) 映射文件的 java 项目,这些映射文件对大多数域对象具有以下类型的声明。

<property name="dateCreated" generated="insert">
     <column name="date_created" default="getdate()" />
</property>

这里的问题是 getdate() 是一个特定于 MSSQL 的函数,当我使用 H2 之类的东西来测试项目的子部分时,H2 会尖叫

getdate() 

不是公认的功能。它自己的时间戳功能是

current_timestamp(). 

我希望能够继续使用 H2 进行测试,并想知道是否有办法告诉 Hibernate“使用此数据库自己的机制来检索当前时间戳”。对于 H2,我提出了以下解决方案。

CREATE ALIAS getdate AS $$ java.util.Date now()  return new java.util.Date();  $$;
CALL getdate();

它有效,但显然是 H2 特定的。

我尝试过扩展 H2Dialect 并注册函数 getdate(),但是当 Hibernate 创建表时似乎没有调用它。是否可以从特定的数据库引擎中抽象出默认时间戳的概念?

【问题讨论】:

【参考方案1】:

您可以尝试以下方法吗(没有generated,因为您的数据库没有生成值):

<column  name="DATE_CREATED" sql-type="timestamp"  default="CURRENT_TIMESTAMP"/>

【讨论】:

我可以。我的意思不是我想完全切换到 H2,而是我正在测试我真的不需要使用 MSSQL 的一小部分代码,并且使用像 H2 这样的内存数据库使我测试更快,更有趣。在每个 DBMS 中为时间戳功能使用不同的名称感觉很愚蠢。 HSQLDB 与 H2 非常相似(从未使用过 H2,所以我不知道确切的功能细分)并支持CURRENT_TIMESTAMP。我一直使用 HSQL 进行内存单元测试。 hsqldb.org/doc/2.0/guide/sqlgeneral-chapt.html#N10544 @unsquared:我不是 100% 确定,但我认为上述建议是可移植的。 @matt:是的,但我说的是 H2 与 MSSQL,而不是 H2 与 HQL @unsquared,对,但是 CURRENT_TIMESTAMP 在 MSSQL 和 HSQL 中都有效。【参考方案2】:

您是否尝试在您的&lt;class&gt; 中使用a &lt;timestamp&gt; mapping?

文档不是很清楚,但听起来这应该会导致映射一个值为时间戳的列。

您可以通过设置generated="insert"generated="always" 来指定Hibernate 是否应该使用database generated value。

【讨论】:

生成的属性实际上并没有进行任何生成(我已经尝试过了)。从您引用的文档中:“当 Hibernate 为已定义生成属性的实体发出 SQL INSERT 或 UPDATE 时,它会立即发出选择以检索生成的值。”这假定数据库已配置为进行生成。我们已经在使用时间戳映射,但是只要 Hibernate 访问对象,它就会更新,而不是在创建时简单。 啊,我认为“生成”文档意味着方言会知道的“由特定于数据库的函数生成”。 是的。当我实际尝试并看到我的所有列都设置为 NULL 时,我假设相同并且正在放弃所有这些 getdate() 函数。这将是 Hibernate 文档中免责声明的一个方便点。

以上是关于使用 Hibernate 设置与数据库无关的默认列时间戳的主要内容,如果未能解决你的问题,请参考以下文章

在 Hibernate 中使用注释定义默认列值

在 Hibernate 中使用注释定义默认列值

使用 Hibernate 注释映射 PostgreSQL 串行类型

Jpa设置默认值约束

Hibernate基础

Hibernate:从应用程序而不是数据库插入列值