【问题标题】:JPA OneToMany, always emptyJPA OneToMany,始终为空
【发布时间】:2011-02-26 00:28:21
【问题描述】:

我有一个双向、一对多和多对一的关系。比如说,一个公司有很多人,一个人有一个公司,所以,在公司里,

@OneToMany(mappedBy = "company", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Collection<Person> persons;

亲自,

@ManyToOne
@JoinColumn(name="COMPANY_ID")
private Company company;

现在,假设我在 Company 上有一个 @PrePersist / @PreUpdate 方法,当它更新时,我想为所有 People 设置相同的时间戳......就像,

@PrePersist
@PreUpdate
public void setLastModified() {
    this.lastModified = System.currentTimeMillis();
    if (persons != null) {
        for (Person person : persons) {
            person.setLastModified(this.lastModified);
        }
    }
}

当我调试它时,我看到公司中的人员字段始终为空。当我查看persons 集合的类型时,它是一个java.util.Vector。不确定这是否相关。我希望看到一些自动加载的 JPA 集合类型。

我做错了什么?

【问题讨论】:

    标签: jpa one-to-many


    【解决方案1】:

    您必须设置关系的双方。当您创建一个新人员并设置其公司时,您还必须将该人员添加到公司的人员(员工?)。

    另外,你不应该在一个对象的 prePersist/Update 中改变另一个对象,你应该使用它自己的 prePersist/Update 事件。

    看, http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Object_corruption.2C_one_side_of_the_relationship_is_not_updated_after_updating_the_other_side

    【讨论】:

    • 我打算用这个链接指定的基本版本添加我自己的 hack,但我不知道这实际上是专家建议的方法。
    【解决方案2】:

    将 fetch = FetchType.Eager 添加到 @ManyToOne 注释。您在关系的另一端添加了它。

    【讨论】:

    • 谢谢。我还没有机会验证这一点,但我会在验证时更新这个问题。
    【解决方案3】:

    如果您想在Company 中获取personList,请使用FetchType.EAGER。 在 JPA 中,

    @--ToOne    =>  Default :  FetchType.EAGER 
    @--ToMany   =>  Default :  FetchType.LAZY
    
    @JoinColumn(name="COMPANY_ID", fetch = FetchType.EAGER)
    private Company company;
    

    【讨论】:

      【解决方案4】:

      在我的情况下,我意识到我不需要(双向)OneToMany - ManyToOne 关系,从而解决了这个问题。

      例如,在单向 OneToMany 关系中,只需编写如下内容:

      // Company Class:
      @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
      private Set<Person> persons = new HashSet<Person>();
      
      // Person Class:
      // - Remove the 3 lines
      

      检查这个例子: https://github.com/thombergs/code-examples/tree/master/spring-data/spring-data-rest-associations/src/main/java/com/example/demo

      如果这不能解决您的问题,请检查您是否在 Person 或 Company 类中使​​用 Lombok

      如果是这种情况,请在 Company 类中添加这两个注解(Person 类反之亦然):

      @Data
      @Entity
      @EqualsAndHashCode(exclude = { "persons"}) // This,
      @ToString(exclude = { "persons"}) // and this
      public class Company implements Serializable {
      
      // ...
      private Set<Person> persons = ...
      / ...
      

      【讨论】:

        【解决方案5】:

        这是由 Hibernate 中的一个已知错误引起的,请参阅 https://hibernate.atlassian.net/browse/HHH-9979

        很遗憾,我不知道有任何解决方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-06-04
          • 2017-04-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多