休眠/JPA 持久映射一对一与序列生成器



我有 2 个实体使用这样的@OneToOne关系连接:

public class FirstEntity {
    @Id
    @Column(name = "FIRST_ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "S_FIRST")
    private Long ID;
    @OneToOne(mappedBy = "first", targetEntity = SecondEntity.class,  cascade = CascadeType.MERGE)
    private SecondEntity second;
}

而另一个实体像这样:

public class SecondEntity {
    @Id
    @Column(name = "SECOND_ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "S_SECOND")
    private Long ID;
    @OneToOne(targetEntity = firstEntity.class)
    @JoinColumn(name = "H_FIRST_FK")
    private FirstEntity first;
}

但是当我想添加新的第一个实体并将第二个实体(已经存在(链接到它时,我遇到了一些问题。

    FirstEntity firstEntity = mapper.toEntity(firstDto);
    if(firstDto.getSecond() != null) {
        firstEntity.getSecond().setFirst(first);
    }
    firstRepository.save(firstEntity);

问题:使用此代码,我收到"分离实体"错误,可能是因为Hibernate无法设置第一个实体的id,因为它是sql生成器。

使用此代码:

    FirstEntity firstEntity = mapper.toEntity(firstDto);
    firstRepository.save(firstEntity);
    if(firstDto.getSecond() != null) {
        firstEntity.getSecond().setFirst(first);
    }

问题:未为secondEntity保存任何内容,并且未设置映射。

目前,似乎唯一有效的是:

    FirstEntity firstEntity = mapper.toEntity(firstDto);
    firstRepository.save(firstEntity);
    if(firstDto.getSecond() != null) {
        firstEntity.getSecond().setFirst(first);
    }
    firstRepository.save(firstEntity);

有没有办法告诉休眠:

  • 获取下一个序列
  • 保存第一个
  • 将第二个与 FK 的第一个 ID 合并在一个指令中而不是手动进行 2 次保存?

所有这些都无需双重保存?

所以我假设第二个实体已经有一个@Id字段集。

由于您已经有了正确的级联选项:cascade = CascadeType.MERGE,我将在第一个示例中简单地用合并替换保存:

FirstEntity firstEntity = mapper.toEntity(firstDto);
if(firstDto.getSecond() != null) {
    firstEntity.getSecond().setFirst(first);
}
firstRepository.merge(firstEntity);

这将保留新的第一个实体实例,然后合并第二个实体。

请记住,如果要在合并后对第一个实体执行任何操作,则必须处理新实例:

FirstEntity mergedFirstEntity = firstRepository.merge(firstEntity);
// operations on mergedFirstEntity from now on

最新更新