当某个实体日期字段与当前日期相比过去时,如何自动更新实体字段?

时间:2019-02-14 06:37:32

标签: java spring postgresql jpa

我有一个包含以下字段的表:

@Entity
public class TableA{
    @Temporal(TemporalType.TIMESTAMP)
    private Date date;

    private String status;

    public TableA() {
    }
    //Setter and getter methods
}

日期字段说明此条目的到期日期/时间,当当前日期/时间达到规定的到期日期时,状态应更新为“已到期”。

是否有一种完善的方法来设置此到期时间,而不是使用定期计时器来检查所有记录?

我正在使用JpaRepository和PostgreSQL。

3 个答案:

答案 0 :(得分:1)

除了轮询和更新之外,没有其他方法可以代表JPA或其他技术进行自动更新。但是,您的状态应该是计算状态(而不是字段)的方法,例如:

public String getStatus() {
    if(date.before(new Date())) return "expired";
    return ""; // or what ever are statuses
}

此外,您应该将状态收集为enum值。

使用JPA,您当然可以在获取或存储到数据库时使用@PrePersist@PostLoad,例如:

@PrePersist // benefit of this would be marginal since usually you do not deal 
            // much with entity after persisting
@PostLoad
private void updateStatus() {
    if(date.before(new Date())) status = "expired";

上述方法的问题在于,仅当持久化或加载实体时才触发上述更新。因此,如果您加载了一个未过期的实体,并且该实体将在会话期间过期,那么您将不会注意到它已过期,直到它在过期后第一次持续存在。

答案 1 :(得分:0)

CREATE EVENT updateEvent
    ON SCHEDULE
      EVERY 3 HOUR
        DO
update TableA 
set status='Expired' 
where date < date_sub(now(),interval 24 hour);

您可以创建数据库事件,以便通过此事件每3小时更新一次状态。

答案 2 :(得分:0)

当您从db中选择数据时,您实际上可以计算此状态:

SELECT date < NOW() as status FROM TableA;

或在您的代码或数据库中创建cron作业,以不时进行该操作。