使用@MapsId持久保存@OneToOne子实体会在Hibernate中抛出“错误:已分离的实体传递给持久化”

我读了https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/.
我试过建议配置(使用spring数据JPA,hibernate 5.0作为供应商):

public class PaperSubjectType{
    @Id
    private Long id;

    @OneToOne(fetch = FetchType.LAZY)
    @MapsId
    private PaperSetting paperSetting;
..
}

class PaperSetting{
  @Id
  @GeneratedValue
  private Long id;
..
}

首先我尝试了这个例子:

PaperSetting paperSettingInDb = paperSettingRepository.findOne(1);
PaperSubjectType paperSubjectType = new PaperSubjectType();
paperSubjectType.setSubjectCode("91");
paperSubjectType.setPaperSetting(paperSettingInDb);

paperSubjectTypeRepository.save(paperSubjectType);

错误:传递给persist的分离实体:PaperSetting.
似乎hibernate将PaperSetting作为级联时分离

2如果我想同时创建PaperSubjectType和PaperSetting,我是否需要这样做:

PaperSetting paperSetting = new PaperSetting();
paperSetting.setxx;
PaperSetting  paperSettingInDbNew = paperSettingRepository.save(paperSetting);
PaperSubjectType paperSubjectType = new PaperSubjectType();
paperSubjectType.setPaperSetting(paperSettingInDbNew);
paperSubjectTypeRepository.save(paperSubjectType);

或者我应该在这种情况下使用双向?
谢谢!

最佳答案
我想您可能忘记将逻辑包装在@Transactional块中

@Transactional
PaperSetting paperSettingInDb = paperSettingRepository.findOne(1);
PaperSubjectType paperSubjectType = new PaperSubjectType();
paperSubjectType.setSubjectCode("91");
paperSubjectType.setPaperSetting(paperSettingInDb);

paperSubjectTypeRepository.save(paperSubjectType);

没有那个crudRepository.findOne()将打开它自己的短期事务,所以当你得到findOne()的返回时,实体已经分离,因此错误

转载注明原文:使用@MapsId持久保存@OneToOne子实体会在Hibernate中抛出“错误:已分离的实体传递给持久化” - 代码日志