JPA OneToMany,始终为空

发布于 2024-10-19 07:24:51 字数 781 浏览 2 评论 0原文

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

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

和个人中,

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

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

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

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

我做错了什么?

i have a bidirectional, one to many, and many to one relationship. say, a Company has many Persons, and a Persons has one company, so, in company,

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

and in Person,

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

now, say i have a @PrePersist / @PreUpdate method on Company, where when it is updated, i want to set the same timestamp on all the People ... like,

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

when i debug this, i see that the persons field in Company is always empty. when i look at the type of the persons collection, it's a java.util.Vector. not sure if that's relevant. i expected to see some auto-loading JPA collection type.

what am i doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

梦里兽 2024-10-26 07:24:51

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

另外,您不应该在一个对象的 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

You must set both sides of your relationship. When you create a new Person and set its Company you must also add the Person to the Company's persons (employees?).

Also, you should not change another object in one object's prePersist/Update, you should use its own prePersist/Update event.

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

我不是你的备胎 2024-10-26 07:24:51

就我而言,我通过意识到我不需要(双向)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

< strong>如果这不能解决您的问题,请检查您是否在 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 = ...
/ ...

In my case I got this fixed by realizing that I did not need a (Bidirectional) OneToMany - ManyToOne relationship.

For example, in a Unidirectional OneToMany relationship, just write something like:

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

// Person Class:
// - Remove the 3 lines

Check this example:
https://github.com/thombergs/code-examples/tree/master/spring-data/spring-data-rest-associations/src/main/java/com/example/demo

If this does not fix your issue, check if you are using Lombok in your Person or Company classes.

If that is the case, add these two annotations in the Company class (vice-versa for the Person class):

@Data
@Entity
@EqualsAndHashCode(exclude = { "persons"}) // This,
@ToString(exclude = { "persons"}) // and this
public class Company implements Serializable {

// ...
private Set<Person> persons = ...
/ ...
一身软味 2024-10-26 07:24:51

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

Add fetch = FetchType.Eager to @ManyToOne annotation. You added it on the other side of relationship.

那伤。 2024-10-26 07:24:51

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

@--ToOne    =>  Default :  FetchType.EAGER 
@--ToMany   =>  Default :  FetchType.LAZY

@JoinColumn(name="COMPANY_ID", fetch = FetchType.EAGER)
private Company company;

if you would like to getpersonList in Company, use FetchType.EAGER.
In JPA,

@--ToOne    =>  Default :  FetchType.EAGER 
@--ToMany   =>  Default :  FetchType.LAZY

@JoinColumn(name="COMPANY_ID", fetch = FetchType.EAGER)
private Company company;
酷遇一生 2024-10-26 07:24:51

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

不幸的是我不知道有任何解决方法。

This is caused by a known bug in Hibernate, see https://hibernate.atlassian.net/browse/HHH-9979.

Unfortunately I am not aware of any workarounds.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文