在PostgreSQL下,我使用PersistentDuration
来MapSQL类型interval和duration,但它不起作用。
另一个用户也发现了同样的问题,并使用了他自己的类:
public void nullSafeSet(PreparedStatement statement, Object value, int index)
throws HibernateException, SQLException {
if (value == null) {
statement.setNull(index, Types.OTHER);
} else {
Long interval = ((Long) value).longValue();
Long hours = interval / 3600;
Long minutes = (interval - (hours * 3600)) / 60;
Long secondes = interval - (hours * 3600) - minutes * 60;
statement.setString(index, "'"+ hours +":"
+ intervalFormat.format(minutes) + ":"
+ intervalFormat.format(secondes)+"'");
}
}
字符串
但它不适用于真实的格式,因为它假设间隔模式仅为“hh:mm:ss”。
这里有一些我需要从数据库中解析的真实的例子:
http://www.postgresql.org/docs/current/interactive/datatype-datetime.html
你有干净的解决方案吗?
6条答案
按热度按时间v7pvogib1#
这是一个适用于JPA、Hibernate的工作解决方案(带注解)。
这是实体类的开头(对于具有Interval列的表):
字符串
这是间隔列:
型
这是Interval类:
型
q0qdq0h22#
您不必编写自己的Hibernate自定义类型来将PostgreSQL
interval
列Map到JavaDuration
对象。您所需要做的就是使用Hibernate Ttypes项目。因此,在添加适当的Hibernate依赖项之后:
字符串
您只需使用
@TypeDef
注解来注册PostgreSQLIntervalType
:型
现在,当持久化
Book
实体时:型
Hibernate将执行正确的SQL语句:
型
当获取
Book
实体时,我们可以看到Duration
属性是从数据库中正确获取的:型
7qhs6swi3#
为什么不把它转换成一个数字,然后Map成一个长型呢?
字符串
9gm1akwq4#
PostgreSQL有一个date_part / extract函数,你可以用它来返回不同的字段,epoch就是其中之一。当从一个interval中提取epoch时,你会收到interval中包含的秒数,从那里你可以任意转换。我失去了使用Hibernate的经验,但你可以这样做:
字符串
4ktjp1zp5#
根据这个链接,你应该有一天,然后是小时:分钟:秒。所以把代码改成下面这样,假设你永远不需要有超过23小时59分钟的时间间隔。
字符串
我无法测试这段代码,因为我没有安装PostgreSQL。关于这个问题的另一个讨论,请参阅下面的链接,尽管你必须修改提供的代码来处理秒数。这应该不会有太大的问题。
https://forum.hibernate.org/viewtopic.php?p=2348558&sid=95488ce561e7efec8a2950f76ae4741c
vdgimpew6#
Hibernate能够做到这一点已经有一段时间了。
Hibernate 5
Hibernate 5在Java方面对
Duration
提供了原生支持,但它希望您将其存储在数据库中的SQL DECIMAL列中,例如,在PostgreSQL中,numeric
类型的列。它将简单地读取和写入Duration
值作为十进制数。这是有意义的,因为通过这种策略,Hibernate能够始终支持Duration
,而不管目标数据库是否对真正的SQL INTERVAL列类型有任何真实的支持。Hibernate 6(当前)
现在已经有了对PostgreSQL
interval
列类型的原生支持。(内容如下:不想破坏现有的应用程序),你需要显式地告诉Hibernate哪些应用程序正在使用你的数据库的SQL INTERVAL特性(如果有的话)。如果你不这样做,那么Hibernate仍然会像在v5中那样,也就是说,它将尝试以十进制的形式写入列。显然,如果你的数据库是PostgreSQL,而你的列是interval
类型,这将不起作用。你的实体类应该看起来像这样:
字符串
重要提示:
您需要设置
hibernate.type.preferred_duration_jdbc_type=INTERVAL_SECOND
属性,让Hibernate知道您正在使用数据库的INTERVAL类型。注意事项:我在这里放的
columnDefinition
只是为了明确在我的例子中对应的数据库列类型是什么。我不认为Hibernate会在Hibernate场景之外使用columnDefinition
。换句话说:你可以省略它。