hibernate - 如何在 JPA 2 实体中映射 postgresql "timestamp with time zone"

标签 hibernate postgresql jpa jpa-2.0

我有一个使用 Postgresql(带有 9.0-801.jdbc3 JDBC 驱动程序)的 JPA 2 应用程序(使用 Hibernate 3.6 作为 JPA 实现)。

我无法将“带时区的时间戳”字段映射到我的 JPA 实体中。

这是一个例子:

CREATE TABLE theme
(
  id serial NOT NULL,
  # Fields that are not material to the question have been edited out
  run_from timestamp with time zone NOT NULL,
  run_to timestamp with time zone NOT NULL,
  CONSTRAINT theme_pkey PRIMARY KEY (id ),
  CONSTRAINT theme_name_key UNIQUE (name )
)

我试过如下映射:

@Entity
@Table(schema = "content", name = "theme")
public class Theme extends AbstractBaseEntity {
    private static final long serialVersionUID = 1L;

    @Column(name = "run_from")
    @NotNull
    @Temporal(TemporalType.TIMESTAMP)
    private Date runFrom;

    @Column(name = "run_to")
    @NotNull
    @Temporal(TemporalType.TIMESTAMP)
    private Date runTo;

    /* The rest of the entity has been edited out */

我不断收到具有以下根本原因的异常:Caused by: org.hibernate.HibernateException: Wrong column type in public.backend_themetopic for column created。找到:timestamptz,预计:date

我尝试过的

  • java.util.Calendar 替换为 java.util.Date - 没有任何区别
  • 使用 java.sql.Timestamp - 提示我无法将 @Temporal 注释应用于 Timestamp
  • 使用带有自定义 @Type 注释的 org.joda.time.DateTime ( @Type(type="org.joda.time.contrib.hibernate .PersistentDateTimeTZ") ) 也不起作用

约束

  • 此应用程序与“遗留系统”交互 - 因此,更改日期字段的类型不是一个好的选择

我的问题是:我应该如何将这些时区感知时间戳映射到我的 JPA 实体中?

最佳答案

我最终通过关闭模式验证使这个“工作” - 以一种 hackish 的方式。

以前,我有 <property name="hibernate.hbm2ddl.auto" value="validate"/>"hibernate.hbm2ddl.auto"在我的 persistence.xml 中。当我注释掉这个属性时,我的应用程序服务器启动并且模型“工作”。

我的实体的最终形式是:

@Entity
@Table(schema = "content", name = "theme")
public class Theme extends AbstractBaseEntity {
    private static final long serialVersionUID = 1L;

    @Column(name = "run_from", columnDefinition = "timestamp with time zone not null")
    @NotNull
    @Temporal(TemporalType.TIMESTAMP)
    private Date runFrom;

    @Column(name = "run_to", columnDefinition = "timestamp with time zone not null")
    @NotNull
    @Temporal(TemporalType.TIMESTAMP)
    private Date runTo;
    
    /* Getters, setters, .hashCode(), .equals() etc omitted */

在阅读了很多相关内容之后,我的印象是没有简单的方法可以将 Postgresql 时间戳与时区列映射。

一些 JPA 实现 + 数据库组合本身就支持这一点(EclipseLink + Oracle 就是一个例子)。对于 hibernate ,使用 jodatime 扩展,可以使用普通时间戳 + 时区的 varchar 字段来存储时区感知时间戳(我不能这样做,因为我被限制更改数据库模式)。 Jadira user types或者也可以使用完全自定义的用户类型来解决这个问题。

我需要注意,我对这个实体的用例是“只读的”,所以我可以用一个看似幼稚的“解决方案”来逃避。

关于hibernate - 如何在 JPA 2 实体中映射 postgresql "timestamp with time zone",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13357487/

相关文章:

java.io.IOException : Illegal UTF-8 sequence: initial byte is 11111xxx: 252 - Eclipse and PostgreSQL 异常

java - 带有分页的 Spring-Data FETCH JOIN 不起作用

java - 按外键值查询而不是左连接

java - JAX-RS 中的回滚事务

java - 使用连接在 Hibernate 查询语言中选择

java - 如何将脚本sql的值获取到对象java

python - 在 SQLAlchemy 原始 SQL 中设置输入参数类型

java - MVC 模板项目看不到 hibernate.cfg.xml

python - 如何读取 psycopg2 的只读状态?

java - 在这种情况下是否需要调用 flush() (JPA 接口(interface))?