我正在玩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;
正确填充所有其他字段。我尝试将字段类型更改为Date
,Calendar
,Timestamp
等,并尝试添加@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
字段!
好的......这缩小了问题的范围。
答案 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 {}