【问题标题】:How to map timestamp column to JPA type?如何将时间戳列映射到 JPA 类型?
【发布时间】:2012-01-21 15:24:07
【问题描述】:

我正在使用 Play! 1.2.4 和 PostgreSQL 9.1。我创建了一个带有created_at 列的表,类型为:timestamp without time zone。它的默认值为now()

当我使用该表的 Entity 类获取数据时,问题就出现了。 createdAt 字段总是返回 null。这是字段定义:

@Column(name="created_at", insertable=false)
public java.sql.Date createdAt;

所有其他字段均已正确填充。我尝试将字段类型更改为DateCalendarTimestamp 等,并尝试添加@Timestamp 注释。但没有一种组合被证明是成功的。

提前感谢您的帮助!

作为参考,这里是我用来创建表的 DDL。

CREATE TABLE Users
(
  id serial     NOT NULL,
  username text NOT NULL,
  email text    NOT NULL,
  password_hash text NOT NULL DEFAULT 0,
  created_at timestamp without time zone DEFAULT now(),
  CONSTRAINT Users_pkey PRIMARY KEY (id),
  CONSTRAINT Users_username_key UNIQUE (username)
);

更新: 我认为问题与使用 JPA 插入记录有关。数据库为created_at 填充默认值now(),但不知何故,Hibernate 在获取该行时并不知道它。

如果我查询已存在的行,createdAt 字段将正确填充! 好的...这缩小了问题范围。

【问题讨论】:

    标签: postgresql jpa playframework


    【解决方案1】:

    我没有完全解决这个问题,但我解决了它。

    我没有让数据库提供默认值now(),而是在JPA 中用@PrePersist 表示:

    @Column(name="created_at", nullable=false)
    @Temporal(TemporalType.TIMESTAMP)
    public Date createdAt;
    
    @PrePersist
    protected void onCreate() {
        createdAt = new Date();
    }
    

    效果很好!灵感来自this answer。 我仍然不确定为什么 Hibernate 没有使用数据库中应用的默认值进行更新。它被认为该值仍然为空。

    【讨论】:

      【解决方案2】:

      试试这个:

      @Column(name="create_at", insertable=false)
      @Temporal(TemporalType.TIMESTAMP)
      private Date createAt;
      

      【讨论】:

      • 我试过了,但是不行。该字段仍然从数据库返回 null。
      • 试试这个然后@Column(name="create_at", insertable=false, nullable=false)
      • 您的查询怎么样?或者也试试这个:@Column(name="create_at", insertable=false, columnDefinition = "now()")
      • 该表已在数据库中定义。我没有使用 JPA DDL 在运行时创建它。我可以使用 JPA 插入一行,created_at 在数据库中自动设置为 now()。但是当我获取该行时,所有字段都存在,除了 createdAt 字段为空。不知何故,timestamap 数据库值没有被转换。
      • 阅读此java2s.com/Tutorial/Java/0355__JPA/TemporalTypeTIMESTAMP.htm 使用java.util.Datejava.util.Calendar。希望对您有所帮助
      【解决方案3】:

      您需要从数据库中分离和获取实体。 Insert 语句不包含 created_at 字段,因此它在创建时不受 JPA 管理。在存储库中,它看起来像这样:

      @Transactional
      public Log save(Log log) {
          this.em.persist(log);
          this.em.detach(log);
          return this.em.find(Log.class, log.getId());
      }
      

      【讨论】:

        【解决方案4】:

        以防万一,如果您填写字段定义的类是主类,所有其他类都对其进行了扩展,请不要忘记使用注释对其进行定义:

        import javax.persistence.MappedSuperclass;
        
        @MappedSuperclass
        public class MySuperClass {}
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-08
          • 2016-05-06
          • 2023-03-29
          • 2019-11-17
          相关资源
          最近更新 更多