【问题标题】:Spring data JPA. Cascade update works for special cases only弹簧数据 JPA。级联更新仅适用于特殊情况
【发布时间】:2017-10-16 19:15:36
【问题描述】:

最重要的结构描述:

在我的应用程序中使用了 Spring data JPA。 我的应用程序中有一个模型部分:

@Entity
public class Event implements Identifiable {
  // ...
  @OneToMany(cascade = CascadeType.ALL, mappedBy = "event", orphanRemoval = true)
  @OrderColumn(name = "order_index")
  private List<Attendee> attendees = new ArrayList<>();
  // ...
}

@Entity
public class Attendee implements Identifiable {
  // ...
  @ManyToOne
  @JoinColumn(columnDefinition = "event_id")
  private Event event;
  // ...
}

所有知道JPA的人都应该清楚。

我已经实现了保存event 的测试,因为结果依赖于attendees 集合也保存(由于一开始显示的对应关系设置,使用了休眠魔法。)

eventRepository.save(event);

提供保存|更新事件并将所有旧的嵌套参与者替换为新参与者。

问题描述:

有时我需要在保存事件的同一事务中使用额外的处理程序。他们也使用存储库:

// transaction starts... some handlers are used
eventRepository.save(event);
// some additional handlers2 are used
// transaction ends

如果handlers2包含任何具有独立实体的存储库操作,例如:

profileRepository.findAll();
// or
profileRepository.findByEmail("anyEmail");

,它失败并出现异常org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.nextiva.calendar.entity.Attendee。似乎应该保存与会者收藏,因为它没有。

为了解决这个问题,我使用了以下解决方法:

// transaction starts... some handlers are used
attendeeRepository.save(event.getAttendees());
eventRepository.save(event);
// some additional handlers2 are used
// transaction ends

现在可以了,但我不喜欢这种方式。

问题:

  1. 这是我的架构问题吗?
  2. 是休眠问题吗?
  3. 应该如何配置没有冗余调用attendeeRepository.save(event.getAttendees());

【问题讨论】:

  • 没有尝试使用eventRepository.saveAndFlush(event)(来自JpaRepository)?
  • 不,我没有因为 spring jpa 存储库,例如:org.springframework.data.repository.PagingAndSortingRepositoryorg.springframework.data.jpa.repository.JpaRepository 不提供saveAndFlush
  • 什么会阻止将 PagingAndSortingReposito‌​ry 替换为 JpaRepository?
  • 它有什么帮助?

标签: java spring hibernate jpa spring-data-jpa


【解决方案1】:

尝试切换到JpaRepository并使用

eventRepository.saveAndFlush(event);

而不是eventRepository.save(event)

或者

eventRepository.save(event);
eventRepository.flush();

它将强制 repo 刷新数据库的所有未决更改。


同时检查你是否在你的 repo 接口上设置了@Transactional(readOnly = true),将刷新模式设置为 NEVER(如reference 中所述,或here 中所述的MANUAL)也适用于save 方法。或许这就是问题所在……

【讨论】:

    猜你喜欢
    • 2014-03-28
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-06
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    相关资源
    最近更新 更多