postgresql 如何将时间戳列映射到 JPA 类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8528439/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 23:14:52  来源:igfitidea点击:

How to map timestamp column to JPA type?

postgresqljpaplayframework

提问by slattery

I'm using Play! 1.2.4 and PostgreSQL 9.1. I created a table with a created_atcolumn, of type: timestamp without time zone. It has a default value of now().

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

The problem comes when I fetch data using my Entity class for this table. The createdAtfield is always coming back null. Here is the field definition:

当我使用我的实体类为这个表获取数据时,问题就出现了。该createdAt领域总是会回来null。这是字段定义:

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

All the other fields are populated correctly. I have tried changing the field type to a Date, Calendar, Timestamp, etc., and tried adding a @Timestampannotation. But no combination has proved successful.

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

Thanks in advance for any help!

在此先感谢您的帮助!

For reference, here is the DDL I used to create the table.

作为参考,这里是我用来创建表的 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)
);

Update:I think the problem has to do with using JPA to insert a record. The database populates a default value of now()for created_at, but somehow Hibernate doesn't know about it when fetching that row.

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

If I query for a row that already existed, the createdAtfield is populated correctly! OK... this narrows down the problem.

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

回答by slattery

I didn't solve the problem exactly, but I worked around it.

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

Instead of having the database supply the default value of now(), I expressed it in JPA with @PrePersist:

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

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

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

That works fine! Inspiration taken from this answer. I'm still not sure why Hibernate didn't get updated with the default value that was applied in the database. It was stuck thinking the value was still null.

这很好用!灵感来自这个答案。我仍然不确定为什么 Hibernate 没有使用数据库中应用的默认值进行更新。它被困在认为该值仍然为空。

回答by Anderson Carniel

Try this:

尝试这个:

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

回答by norbertas.gaulia

You need to detach and fetch entity from db. Insert statement does not contain created_at field so it's not managed by JPA at the time of creation. In repository it would look like this:

您需要从数据库中分离和获取实体。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());
}

回答by Aquarius

Just in case, if the class where you fill the field definition is a master class, which all the other class extends it, don't forget to define it with the annotation:

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

import javax.persistence.MappedSuperclass;

@MappedSuperclass
public class MySuperClass {}