我有一个使用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. Found: timestamptz, expected: date
我尝试过的
  • java.util.Calendar替换java.util.Date-
  • 没有区别
    使用java.sql.Timestamp
  • -抱怨我无法将@Temporal批注应用于Timestamp
  • 使用带有自定义org.joda.time.DateTime注释(@Type)的@Type(type="org.joda.time.contrib.hibernate.PersistentDateTimeTZ")也不起作用

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

  • 我的问题是:如何将这些了解时区的时间戳映射到我的JPA实体中?

    最佳答案

    我最终通过关闭模式验证以一种有点怪异的方式完成了这项“工作”。

    以前,我在persistence.xml中有<property name="hibernate.hbm2ddl.auto" value="validate"/>"hibernate.hbm2ddl.auto"。当我注释掉此属性后,我的应用服务器启动,模型“正常运行”。

    我实体的最终形式是:

    @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 = "timestampt with time zone not null")
        @NotNull
        @Temporal(TemporalType.TIMESTAMP)
        private Date runTo;
    
        /* Getters, setters, .hashCode(), .equals() etc omitted */
    

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

    一些JPA实现+数据库组合本身就支持此功能(EclipseLink + Oracle是一个示例)。对于休眠状态,使用jodatime扩展,可以使用正常时间戳+时区的varchar字段来存储时区感知时间戳(由于无法更改数据库架构,所以我不能这样做)。 Jadira user types或完全自定义的用户类型也可以用于解决此问题。

    我需要注意的是,该实体的用例是“只读”的,因此我可以摆脱看似幼稚的“解决方案”。

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

    10-15 19:40