【问题标题】:entityManager.merge(object) is persisting only the last record from listentityManager.merge(object) 仅保留列表中的最后一条记录
【发布时间】:2019-07-03 12:07:20
【问题描述】:

我的ArrayList<Object> 中有两条记录,但是当我尝试将这些记录插入数据库时​​,只有最后一条记录会保存到数据库中。

我正在使用 Spring data JPA entityManager.merge() 方法,因为我有自定义序列生成器用于实体。

summaryList.stream().forEach{(summary -> entityManager.merge(summary)};

在调试时,我在 summaryList 中获得了两条记录,但是当我检查我的数据库表时,只插入了一条记录。

【问题讨论】:

  • 您之前检查过您的自定义生成器吗?似乎它两次返回相同的值。
  • @amseager:我没有得到。您能否详细说明一下,因为我之前能够在数据库中获得正确的值。自定义生成器仅用于从常见序列之一生成 ID。
  • 既然您不发布实体,那么您期待什么?您也没有提及事务边界在哪里,或者在调用合并时要持久化的对象处于什么生命周期状态。
  • @BillyFrost:代码如下所示: public void saveTable(List summary) { summary.stream().forEach(sum -> entityManager.merge(sum)); } 其中摘要是我的实体。
  • 实体如下:@Id @GeneratedValue(generator = "SUM_ID_SEQ") @GenericGenerator(name = "SUM_ID_SEQ", strategy = "com.sbc.test.SummarySequenceIdGenerator") @Column(name = " SUM_ID",可插入 = 真,可更新 = 真,唯一 = 真,可空 = 假)私有 BigInteger mbrshpLdgrSumId; @Column(name = "Name", nullable = false) 私有字符串名称;

标签: jpa java-8 spring-data-jpa entitymanager


【解决方案1】:

Hibernate 首先生成一个SELECT 语句来获取底层数据库记录的最新状态,然后,它将分离的实体状态复制到新获取的托管实体上。这样,脏检查机制可以检测任何状态变化并将其传播到数据库。

虽然对于IDENTITYSEQUENCE 生成器策略,您实际上可以使用合并来持久化实体,但对于分配的生成器,这会降低效率。

您实际上可以通过向您的实体添加版本属性来解决此问题。

@Version
private Long version;

【讨论】:

  • 我是否需要在我的服务层中也设置版本的值。
  • 我的问题是它如何识别“版本”的值。是否需要在 DB 表中添加一个新列。
  • 正如我所说,只需添加@Version private 长版;休息休眠会照顾好
  • 在合并()内部触发的选择查询中出现错误,当添加 @Version 时,因为它添加了一个列版本,而该列版本也不存在于表中。
  • Hibernate 应该在你重启服务器时创建列版本
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-14
  • 1970-01-01
相关资源
最近更新 更多