使用主键作为外键的Hibernate OneToOne无法正常工作

时间:2019-04-15 08:58:19

标签: hibernate spring-boot spring-data one-to-one

我正在将Spring Boot 2.1.4与Spring Data 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]中分配ID

我一直使用在线文档和示例进行此操作,但无法使其正常工作。

2 个答案:

答案 0 :(得分:0)

如果您具有双向的OneToOne关系,则必须设置双方。 在您的情况下,从CommProfile到Mainprofile的关系丢失。

例如:

[10:12:17] I/launcher - Running 1 instances of WebDriver
[10:12:17] I/hosted - Using the selenium server at http://localhost:4444/wd/hub
[10:13:03] E/launcher - Timed out waiting 45 seconds for Firefox to start.
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:25:53' os.name: 'Linux', os.arch: 'amd64', os.version: '4.15.0-47-generic', java.version: '1.8.0_181'
Driver info: driver.version: unknown
[10:13:03] E/launcher - WebDriverError: Timed out waiting 45 seconds for Firefox to start.
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:25:53' os.name: 'Linux', os.arch: 'amd64', os.version: '4.15.0-47-generic', java.version: '1.8.0_181'
Driver info: driver.version: unknown
    at Object.checkLegacyResponse (/home/Development/lrp-protractor/node_modules/selenium-webdriver/lib/error.js:546:15)
    at parseHttpResponse (/home/Development/lrp-protractor/node_modules/selenium-webdriver/lib/http.js:509:13)
    at doSend.then.response (/home/Development/lrp-protractor/node_modules/selenium-webdriver/lib/http.js:441:30)
    at process.internalTickCallback (internal/process/next_tick.js:77:7)
From: Task: WebDriver.createSession()
    at Function.createSession (/home/Development/lrp-protractor/node_modules/selenium-webdriver/lib/webdriver.js:769:24)
    at Function.createSession (/home/Development/lrp-protractor/node_modules/selenium-webdriver/firefox/index.js:521:41)
    at createDriver (/home/Development/lrp-protractor/node_modules/selenium-webdriver/index.js:170:33)
    at Builder.build (/home/Development/lrp-protractor/node_modules/selenium-webdriver/index.js:632:16)
    at Hosted.getNewDriver (/home/Development/lrp-protractor/node_modules/protractor/built/driverProviders/driverProvider.js:53:33)
    at Runner.createBrowser (/home/Development/lrp-protractor/node_modules/protractor/built/runner.js:195:43)
    at q.then.then (/home/Development/lrp-protractor/node_modules/protractor/built/runner.js:339:29)
    at _fulfilled (/home/Development/lrp-protractor/node_modules/q/q.js:834:54)
    at /home/sree/Development/lrp-protractor/node_modules/q/q.js:863:30
    at Promise.promise.promiseDispatch (/home/Development/lrp-protractor/node_modules/q/q.js:796:13)
[10:13:03] E/launcher - Process exited with error code 199

答案 1 :(得分:0)

答案分为两部分:

关系处理

Tom正确指出,如果您具有双向OneToOne关系,则必须设置关系的双方(在MainProfile构造函数中调用commProfile.setMainProfile(this);)。

Spring数据存储库

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

当您将实体传递给save方法时,isNew错误地得出该实体不是新实体的结论。有关详细信息,请参见AbstractEntityInformation.isNew

直接使用entityManager.persist(mainProfile);来解决该问题。