我是Spring的新手,我使用Spring Roo开发的应用程序有一个Cron,每天都会下载一些文件并更新数据库。
在下载并解析文件后,使用 merge()完成更新, 在我下载之后,实体类数据集有一个名为 resources 的列表:
dataset.setResources(resources);
dataset.merge();
和 dataset.merge()执行以下操作:
@Transactional
public Dataset Dataset.merge() {
if (this.entityManager == null) this.entityManager = entityManager();
Dataset merged = this.entityManager.merge(this);
this.entityManager.flush();
return merged;
}
我希望做 dataset.setResources(resources); 我会覆盖已归档的资源,因此即使数据库条目也会被覆盖。
但我在数据库中获得了双重条目:每个资源都出现两次,具有不同的ID(增量)。
我怎样才能让我的应用程序进行更新而不插入?一个天真的解决方案是手动删除旧资源,然后调用 merge();这是方式还是有更智能的解决方案?
答案 0 :(得分:0)
当您使用Hibernate作为持久性引擎并且您的实体具有版本字段时会出现这种情况。
通常,ID字段是我们在数据库中合并分离对象及其持久状态所需要的,但是Hibernate在帐户中使用了version字段,如果你没有设置它(它为null),Hibernate会丢弃它的值ID字段并使用新ID创建新对象。
要知道你是否受到Hibernate的这个奇怪功能的影响,请在版本字段中设置一个值,如果抛出了异常,你就得到了它。在这种情况下,解决它的最佳方法是要解析的数据包含正确的版本值。另一种方法是禁用版本检查(请参阅Hibernate参考指南以了解它)或在合并之前加载持久状态。