Hibernate / JPA持久映射OneToOne与序列生成器

时间:2017-03-22 10:33:36

标签: java hibernate jpa orm

我有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);

问题:使用此代码我收到了“ Detach Entity ”错误,可能是因为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);

有没有办法告诉hibernate:

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

所有这一切都无需双重保存?

1 个答案:

答案 0 :(得分:1)

所以我假设SecondEntity已经设置了@Id字段。

由于您已经拥有正确的级联选项:cascade = CascadeType.MERGE,我只需在第一个示例中使用合并替换保存:

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

firstRepository.merge(firstEntity);

这将保留新的FirstEntity实例,然后合并SecondEntity。

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

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