【问题标题】:Hibernate : Foreign Key not updated for in-memory object with unidirectional OneToMany RelationshipHibernate:没有为具有单向 OneToMany 关系的内存对象更新外键
【发布时间】:2018-08-21 14:22:17
【问题描述】:

我对 2 个实体有以下问题 - 请求和参与者。一个请求可能包含多个参与者的单向关系。

 @Entity
    public class Request {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "id_sequence")
    @SequenceGenerator(
            name = "id_sequence",
            sequenceName = "REQUEST_SEQUENCE",
            allocationSize = 1
    )
    private Long id;

    private String requestorFullName;

    @OneToMany(cascade = CascadeType.ALL, fetch = LAZY, orphanRemoval = true)
    @JoinColumn(name = "requestId")
    private Set<Participant> participants = Sets.newHashSet();

    }

  @Entity
    public class Participant {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = 
    "id_sequence")
    @SequenceGenerator(
            name = "id_sequence",
            sequenceName = "PARTICIPANT_SEQUENCE",
            allocationSize = 1
    )
    private Long id;

    //foreign key-----------
    private Long requestId;

    }

我正在尝试保存一个包含多个参与者的新请求。当我尝试保存新的请求实例时,Participant 表中的外键被保留,但在内存对象中没有反映,因此字段“requestId”为空。

Request request ; //contains multiple participants
requestRepository.save(request);
//foreign key is peristed in DB, but 'requestId' in in-memory(now persisted) participants is 
//not updated, whereas both the id fields are updated.

【问题讨论】:

  • 不会的,你必须从 db 重新加载所有内容或自己更新 FK。
  • 我是否遗漏了什么或休眠不会填充外键,因为这是单向关系?
  • 它永远不会在更新时自行设置关系,仅在获取实体时。如果您从数据库中查询某些内容,您将获得具有双向/单向关系的完整实体图(取决于映射)。但是,如果您在双向关系中更改某些内容,则必须自己更新关系的另一端-在您的情况下,您正在创建新的关系。在 db 中它只需要 1 次更新,但在这里你必须设置父母的孩子以及孩子的父母。更新的 ID 是特殊情况 (PK),因为实体成为托管的,因此它必须包含 ID。否则,您将不得不再次获取它;)
  • 但是request实体OP正在持久化已经有关联的participants填写。

标签: hibernate jpa hibernate-mapping


【解决方案1】:

requestId 不会被填充,它在Request 实体中的OneToMany 注释中指定为连接列。 JPA 不会像其他列一样对待它。如果您想要它的价值,请使用request::getId

【讨论】:

  • 正如您所提到的,它与其他专栏不同——这正是我的观点。 JPA 提供者隐含地知道它是一个外键,因此我认为应该填充它。
  • 列已填充,实体属性未填充。 “对象”世界不需要外键来指定关系,这就是 RDMS 的工作方式。使用@JoinColumn 注解,我们告知hibernate 这种关系是如何在db 中编排的。
  • 是的,我明白你在说什么。我无法理解 - 为什么当它已经在更新 ID 时,hibernate 不会更新对象中的外键。
  • 因为参与者对象不需要知道与它们关联的请求对象的任何信息,所以表需要外键。您是否尝试在 requestId 上添加@Column?另外,不要将ParticipantRequest 对象视为一些复杂的JDBC ResultSet
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-13
  • 2019-06-29
相关资源
最近更新 更多