【问题标题】:Hibernate - OneToOne error休眠 - OneToOne 错误
【发布时间】:2017-05-16 07:22:06
【问题描述】:

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

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

控制台显示 event_id 为空的错误(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

这里有什么问题?

【问题讨论】:

  • 没有看到数据访问代码,就无法知道为什么会出现这个问题。
  • 所有者方是没有 mappedBy 属性的一方。这是 Hibernate 关心的一个。您需要确保设置计划的事件:plan.setEvent(...)。
  • 从浏览器返回的对象是一个事件,它已经附加了一个计划对象,以及一些测试数据。为什么我需要重新设置这种关系?
  • 同样,问题不在于活动没有计划。问题是该计划没有活动。
  • 你能告诉我一个代码 sn-p 吗?因为我所做的所有谷歌搜索都表明这是正确设置的双向 OneToOne?

标签: java hibernate servlets


【解决方案1】:

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

要解决这个问题,您可以通过从一侧删除映射或注入缺失的引用将关系变为单向

【讨论】:

    【解决方案2】:

    答案是将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;
    //
    

    我实际上从来不需要让它成为双向的(上面的解决方案是单向的)。

    【讨论】:

      猜你喜欢
      • 2011-02-13
      • 2021-06-25
      • 2012-10-14
      • 2012-07-30
      • 2011-02-25
      • 2014-12-27
      • 2014-03-12
      • 1970-01-01
      相关资源
      最近更新 更多