Java 可更新的false behvior不一致

Java 可更新的false behvior不一致,java,hibernate,orm,jpa,Java,Hibernate,Orm,Jpa,我需要LastUpdatedTTM在记录更新时由SYSDATE更新。但下面的注释并没有按预期的那样起作用。SYSDATE只插入一次,不会为后续更新而更新。另外,lastUpdDTTM不是hibernate生成的sql的一部分 @Generated(GenerationTime.ALWAYS) @Column(name="LAST_UPDATED_DTTM",insertable=false,updatable=true, columnDefinition ="timestamp default

我需要LastUpdatedTTM在记录更新时由SYSDATE更新。但下面的注释并没有按预期的那样起作用。SYSDATE只插入一次,不会为后续更新而更新。另外,lastUpdDTTM不是hibernate生成的sql的一部分

@Generated(GenerationTime.ALWAYS)
@Column(name="LAST_UPDATED_DTTM",insertable=false,updatable=true, columnDefinition ="timestamp default SYSDATE")
private Date lastUpdDTTM;

@Generated(GenerationTime.ALWAYS)
@Column(name="CREATED_DTTM", insertable=false, updatable=false)
private Date createdDTTM;
(…)SYSDATE只插入一次,不会为后续更新进行更新

首先,让我澄清一点:
Generated
意味着该字段是由数据库生成的,Hibernate需要在插入/更新后读取该字段以更新实体。在列定义中使用
default SYSDATE
可以很好地进行插入操作,但对于更新操作,您需要一个触发器

另外,lastUpdDTTM不是hibernate生成的sql的一部分

@Generated(GenerationTime.ALWAYS)
@Column(name="LAST_UPDATED_DTTM",insertable=false,updatable=true, columnDefinition ="timestamp default SYSDATE")
private Date lastUpdDTTM;

@Generated(GenerationTime.ALWAYS)
@Column(name="CREATED_DTTM", insertable=false, updatable=false)
private Date createdDTTM;
您告诉Hibernate该字段总是由数据库生成的,因此Hibernate没有将其包含在生成的SQL中并不奇怪(实际上,我认为这与
udpatable=true
有冲突,我希望Hibernate对此表示不满)

无论如何,正如我所说的,不是Hibernate更新这个字段,而是数据库,您需要一个触发器,Hibernate将在更新后刷新实体以获得新值


另一种方法是使用回调注释,例如最后一次更新日期:

@PreUpdate
protected void updateDates() {
    lastUpdDTTM = new Date();
}
为了获得更好的一致性,您甚至可以对
@PrePersit
的创建日期使用相同的方法:

@PrePersist
@PreUpdate
protected void updateDates() {
    Date now = new Date();
    if (createdDTTM == null) {
        createdDTTM = new Date(now.getTime());
    }
    lastUpdDTTM = now;
}
(…)SYSDATE只插入一次,不会为后续更新进行更新

首先,让我澄清一点:
Generated
意味着该字段是由数据库生成的,Hibernate需要在插入/更新后读取该字段以更新实体。在列定义中使用
default SYSDATE
可以很好地进行插入操作,但对于更新操作,您需要一个触发器

另外,lastUpdDTTM不是hibernate生成的sql的一部分

@Generated(GenerationTime.ALWAYS)
@Column(name="LAST_UPDATED_DTTM",insertable=false,updatable=true, columnDefinition ="timestamp default SYSDATE")
private Date lastUpdDTTM;

@Generated(GenerationTime.ALWAYS)
@Column(name="CREATED_DTTM", insertable=false, updatable=false)
private Date createdDTTM;
您告诉Hibernate该字段总是由数据库生成的,因此Hibernate没有将其包含在生成的SQL中并不奇怪(实际上,我认为这与
udpatable=true
有冲突,我希望Hibernate对此表示不满)

无论如何,正如我所说的,不是Hibernate更新这个字段,而是数据库,您需要一个触发器,Hibernate将在更新后刷新实体以获得新值


另一种方法是使用回调注释,例如最后一次更新日期:

@PreUpdate
protected void updateDates() {
    lastUpdDTTM = new Date();
}
为了获得更好的一致性,您甚至可以对
@PrePersit
的创建日期使用相同的方法:

@PrePersist
@PreUpdate
protected void updateDates() {
    Date now = new Date();
    if (createdDTTM == null) {
        createdDTTM = new Date(now.getTime());
    }
    lastUpdDTTM = now;
}

您正在使用哪个JPA实现?这可能会有所帮助。您正在使用哪个JPA实现?也许会有帮助。再次谢谢。但是我真的不想使用触发器。没有otehr解决方案吗?我希望可以使用回调。它必须是数据库服务器日期时间。这种方法将为我提供Web服务器当前时间。@jpanewbie确实如此。最后一个想法是:对更新日期也使用
default SYSDATE
,并在
@PreUpdate
方法中将更新日期设置为
null
。LastUpDttm col在DB级别不是null默认SYSDATE。@Generated(GenerationTime.ALWAYS)@Column(name=“LAST\u UPDATED\u DTTM”,insertable=false,updateable=false,columnDefinition=“timestamp default SYSDATE”)私有日期lastupddtm;即使我在@Preupdate方法中将字段设置为null,它也会被忽略。再次感谢。但是我真的不想使用触发器。没有otehr解决方案吗?我希望可以使用回调。它必须是数据库服务器日期时间。这种方法将为我提供Web服务器当前时间。@jpanewbie确实如此。最后一个想法是:对更新日期也使用
default SYSDATE
,并在
@PreUpdate
方法中将更新日期设置为
null
。LastUpDttm col在DB级别不是null默认SYSDATE。@Generated(GenerationTime.ALWAYS)@Column(name=“LAST\u UPDATED\u DTTM”,insertable=false,updateable=false,columnDefinition=“timestamp default SYSDATE”)私有日期lastupddtm;即使我在@Preupdate方法中将字段设置为null,它也会被忽略。