如何将timestamp列映射到JPA类型?

时间:2011-12-16 00:27:31

标签: postgresql jpa playframework

我正在玩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插入记录有关。数据库为now()填充默认值created_at,但在获取该行时Hibernate不知道它。

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

4 个答案:

答案 0 :(得分:14)

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

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

@Column(name="created_at", nullable=false)
@Temporal(TemporalType.TIMESTAMP)
public Date createdAt;

@PrePersist
protected void onCreate() {
    createdAt = new Date();
}

工作正常!灵感来自this answer。 我仍然不确定为什么Hibernate没有使用数据库中应用的默认值进行更新。它被认为价值仍然无效。

答案 1 :(得分:2)

试试这个:

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

答案 2 :(得分:0)

您需要从db分离并获取实体。 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());
}

答案 3 :(得分:0)

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

import javax.persistence.MappedSuperclass;

@MappedSuperclass
public class MySuperClass {}