Hibernate OneToOne с первичным ключом, являющимся внешним ключом, не работает - PullRequest
1 голос
/ 15 апреля 2019

Я использую Spring Boot 2.1.4 с данными Spring 2.1.6.RELEASE и Hibernate 5.3.9.Final.

У меня есть две сущности:

@Entity
@Table(name = "comm_profile")
@NamedQuery(name = "CommProfile.findAll", query = "SELECT c FROM CommProfile c")
public class CommProfile implements Serializable {

private static final long serialVersionUID = 1L;

@Id
private String customerId;

@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "customer_id", foreignKey = @ForeignKey(name = "COMM_PROFILE_MAIN_PROFILE_FK"))
@MapsId
private MainProfile mainprofile;

 ....
}

и

@Entity
public class MainProfile implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@Column(name = "customer_id")
private String customerId;


@OneToOne(mappedBy = "mainprofile", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
private CommProfile commProfile;

protected MainProfile() {

}

public MainProfile(final String customerId, final CommProfile commProfile)      {
    this();
    this.customerId = customerId;
    this.commProfile = commProfile;
}  
....

Я пытаюсь сохранить следующий код:

private CommProfile createNewProfile(final String customerId, Lang lang) {

    CommProfile commProfile = new CommProfile(lang);

    MainProfile mainProfile = new MainProfile(customerId, commProfile);
    MainProfile mainProfile2 = mainProfileService.save(mainProfile);
    return mainProfile2.getCommProfile();
}

Для этогоЯ попытался присвоить идентификатор из нулевого свойства «один к одному» [... CommProfile.mainprofile]

Я делал это, используя онлайн-документацию и примеры, но не могу сделать этоРабота.

Ответы [ 2 ]

0 голосов
/ 15 апреля 2019

Ответ состоит из двух частей:

Обработка отношений

Как правильно указал Том, если у вас есть двустороннее отношение OneToOne, вы должны установитьобе стороны отношения (вызовите commProfile.setMainProfile(this); в конструкторе MainProfile).

Хранилище данных Spring

@Transactional
    public <S extends T> S save(S entity) {
    if (entityInformation.isNew(entity)) {
        em.persist(entity);
        return entity;
    } else {
        return em.merge(entity);
    }
}

Когда вы передаете свою сущность методу сохранения, isNewнеправильно делает вывод, что сущность не нова.Подробнее см. AbstractEntityInformation.isNew.

Используйте entityManager.persist(mainProfile); напрямую, чтобы обойти эту проблему.

0 голосов
/ 15 апреля 2019

Если у вас двунаправленные отношения OneToOne, вы должны установить обе стороны.В вашем случае связь между CommProfile и Mainprofile отсутствует.

Например:

public MainProfile(final String customerId, final CommProfile commProfile)      {
    this();
    this.customerId = customerId;
    this.commProfile = commProfile;
    commProfile.setMainProfile(this);
} 
...