1

使用 Hibernate 4.1.0 提供的 Spring 3.1/JPA 2。

我的所有实体都有一个基类,它提供基本的审计功能(更新时间戳、版本号等)。因为其他应用程序访问我们的数据库,这些必须通过触发器设置。

我的映射看起来像:

public abstract class AbstractBaseModel implements Serializable {

@Version
@Generated(GenerationTime.ALWAYS)
@Column(name = "VERSION", insertable = false, updatable = false)
protected Long version;

@Generated(GenerationTime.ALWAYS)
@Column(name = "UPDATE_TIMESTAMP", insertable = false, updatable = false)
protected Date updateDate;
...
}

提交事务时始终调用该org.hibernate.engine.internal.increment(...)方法 - 并导致StaleObjectStateException.

奇怪的是,如果我GenerationTime.NEVER在版本列上设置,休眠仍然会增加版本,但会正确保留。问题是即使数据库中的版本没有更新(例如,表上没有更改),从合并返回的版本也会比数据库值高 1,这显然会导致后续保存出现问题。

我的期望是GenerationTime.ALWAYS告诉hibernate永远不要尝试增加版本并依赖数据库来这样做,然后在插入/更新之后选择更新的值。

谁能告诉我我的理解和实施哪里出了问题?

4

2 回答 2

0

对于您的实际问题,我没有答案,但我确实为您的问题提供了解决方案。:)

在 Hibernate 中,这样做是完全有效的:

@Version
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "UPDATE_TIMESTAMP"
private Date updateDate;

这也将使您的更新日期成为您的版本。这既更精简,又会为实体上的每次合并自动更新。

顺便说一句:我建议将成员设为私有并在课程中添加getters 和setters。

于 2012-04-18T09:11:20.740 回答
0

您可以通过在 SQL 列定义和实体映射中指定以下内容来使用 DB。以下示例适用于 MySQL:

create table if not exists table_name (
    ...
    modified timestamp default current_timestamp on update current_timestamp not null,
    ...
);

在代码中:

@Version
@Column(name = "modified", columnDefinition = "timestamp default current_timestamp on update current_timestamp")
private Date modified;
于 2019-01-23T23:41:13.063 回答