我读了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);
或者我应该在这种情况下使用双向? 谢谢!
答案 0 :(得分:0)
我tried it Hibernate 5.2,它就像一个魅力。
假设你有这些实体:
@Entity(name = "Person")
public static class Person {
@Id
@GeneratedValue
private Long id;
@NaturalId
private String registrationNumber;
public Person() {}
public Person(String registrationNumber) {
this.registrationNumber = registrationNumber;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getRegistrationNumber() {
return registrationNumber;
}
}
@Entity(name = "PersonDetails")
public static class PersonDetails {
@Id
private Long id;
private String nickName;
@OneToOne
@MapsId
private Person person;
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
这个数据访问逻辑:
Person _person = doInJPA( this::entityManagerFactory, entityManager -> {
Person person = new Person( "ABC-123" );
entityManager.persist( person );
return person;
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Person person = entityManager.find( Person.class, _person.getId() );
PersonDetails personDetails = new PersonDetails();
personDetails.setNickName( "John Doe" );
personDetails.setPerson( person );
entityManager.persist( personDetails );
} );
测试在Hibernate ORM中正常通过。
也许这是5.0中的一个错误,已经修复了,所以你最好升级。
答案 1 :(得分:0)
1)添加级联选项:
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@MapsId
private PaperSetting paperSetting;
2)有了这个,你可以在重新创建两个实体时只保存PaperSubjectType:
PaperSetting paperSetting = new PaperSetting();
paperSetting.setxx;
PaperSubjectType paperSubjectType = new PaperSubjectType();
paperSubjectType.setPaperSetting(paperSettingInDbNew);
paperSubjectTypeRepository.save(paperSubjectType);
答案 2 :(得分:0)
我想您可能忘记将逻辑包装在@Transactional块
中@Transactional
PaperSetting paperSettingInDb = paperSettingRepository.findOne(1);
PaperSubjectType paperSubjectType = new PaperSubjectType();
paperSubjectType.setSubjectCode("91");
paperSubjectType.setPaperSetting(paperSettingInDb);
paperSubjectTypeRepository.save(paperSubjectType);
没有crudRepository.findOne()
将打开它自己的短期事务,所以当你得到findOne()的返回时,实体已经分离,因此错误