Hibernate - OneToOne错误

时间:2017-05-16 07:22:06

标签: java hibernate servlets

我正在尝试在以下实体上设置OneToOne关系事件&计划。问题是,当我提交(这是一个更新)事件时,没有任何内容进入计划表(为计划创建)

在IDE中,我可以检查从浏览器返回的内容,并且计划中有一个值 - 尽管plan.id为null,因为计划是新的。

控制台显示event_id为null的错误(event_id是计划表上的FK)。

事件

@Entity
public class Event {
@Id
private Long id;
@OneToOne(mappedBy = "event", cascade = CascadeType.PERSIST)
private Plan plan;
//

计划

@Entity
public class Plan {
@Id
private Long id;
@OneToOne
@JoinColumn(name = "event_id", nullable = false)
private Event event
//

我有一个更新现有活动的表单,需要创建一个计划。

当我提交表单时,会抛出以下错误:

浏览器:

There was an unexpected error (type=Internal Server Error, status=500).
could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

控制台

""2017-05-16 19:16:34 - Column 'event_id' cannot be null
""2017-05-16 19:16:34 - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
"com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'event_id' cannot be null
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)

我理解这个错误的基础是event_id(在表计划中)不能为空 - 但计划是作为事件更新的一部分提交的 - 所以event_id应该通过正确设置获得关系?

活动服务

Event savedEvent = eventRepository.save(event); // this line ok
return eventRepository.save(event); // this line errors as above

这里有什么问题?

2 个答案:

答案 0 :(得分:0)

这是双向关系,所以基本上你需要的是关系的每一方都引用另一方,在你的情况下你只有一个引用。

要解决此问题,您可以通过从一侧删除映射或注入缺少的引用来将关系转为单向

答案 1 :(得分:0)

答案是将plan_id记录在事件表中。所以注释成了:

<强>事件

@Entity
public class Event {
@Id
private Long id;
@OneToOne(cascade = CascadeType.ALL)
private Plan plan;
//

<强>计划

@Entity
public class Plan {
@Id
private Long id;
//

我实际上从不需要将其设为双向(上面的解决方案是单向的)。