英文:
spring-data-jpa : Found shared references to a collection org.hibernate.HibernateException
问题
我知道这个问题已经被问过和回答了很多次,而且也有一种解决方法,比如在以下链接中:
https://stackoverflow.com/q/1692871/3493829
http://www.java2s.com/Questions_And_Answers/JPA/Collection/HibernateException.htm
但是以上方法都对我没有起作用。
我正在使用 SpringBoot, JPA, Hibernate
,
并且有如下提供的映射。
我正在检索 Phone 列表,并使用 for 循环进行迭代。
在迭代 phone 列表时,我遇到了错误 Found shared references to a collection: Phone.person
org.hibernate.HibernateException: Found shared references to a collection: Phone.person
at org.hibernate.engine.internal.Collections.processReachableCollection(Collections.java:188) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.FlushVisitor.processCollection(FlushVisitor.java:50) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:104) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:65) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:59) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:182) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:232) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:92) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
Phone 实体的映射如下:
@Entity
@Table(name = "PHONETABLE")
@Data
public class Phone {
// 其他列映射
@ManyToMany
@JoinTable(name = "SomeTable", joinColumns = {
@JoinColumn(name = "column1", referencedColumnName = "personColumn") }, inverseJoinColumns = {
@JoinColumn(name = "id", referencedColumnName = "id", unique = true) })
@JsonIgnore
private Set<Person> person;
}
我正在调用 findByIdMethod
方法从仓库中获取数据。
我已经使用 lombok
生成 getter 和 setter。
如果有人知道解决方法,那就太好了。
谢谢!
英文:
I know this question is asked and answered a number of times and also has a workaround
like in
https://stackoverflow.com/q/1692871/3493829
http://www.java2s.com/Questions_And_Answers/JPA/Collection/HibernateException.htm
but none of the above worked for me.
I am using SpringBoot, JPA, Hibernate
and have mapping as provided below.
I am retrieving the list of Phone and iterating over it using for loop.
I am getting the error Found shared references to a collection: Phone.person
while iterating over phone list
org.hibernate.HibernateException: Found shared references to a collection: Phone.person
at org.hibernate.engine.internal.Collections.processReachableCollection(Collections.java:188) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.FlushVisitor.processCollection(FlushVisitor.java:50) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:104) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:65) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:59) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:182) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:232) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:92) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
Mapping to Phone
entity
@Entity
@Table(name = "PHONETABLE")
@Data
public class Phone{
// other column mapping
@ManyToMany
@JoinTable(name = "SomeTable", joinColumns = {
@JoinColumn(name = "column1", referencedColumnName = "personColumn") }, inverseJoinColumns = {
@JoinColumn(name = "id", referencedColumnName = "id", unique = true) })
@JsonIgnore
private Set<Person> person;
}
I am calling the findByIdMethod
to fetch the data from the repository.
I have used lombok
for getters are setters.
If anyone knows the solution then it would be great.
Thanks;
答案1
得分: 3
看起来您有多个具有相同“person”实例的“Phone”实例。当您克隆或复制“Phone”,或者执行类似于phone1.setPerson(phone2.getPerson())
的操作时,可能会发生这种情况。
Person
实例相同是可以的,但Set
本身不应相同。每个手机应该创建一个新的Set
实例,该实例仅在实体内部使用。
您可以通过在构造函数中实例化集合或在声明后直接实例化集合,然后永不调用集合的setter方法来确保这一点,例如:
private Set<Person> person = new HashSet<Person>();
void addPerson(Person person) {
this.person.add(person);
}
只使用addPerson
方法,不要使用setPerson
方法(您还可以添加类似的辅助方法来添加多个人员、删除人员等)。
您还可以在getPerson
getter方法中返回集合的副本,而不是返回集合本身,以确保集合实例永远不会泄漏出去。
英文:
It appears that you have multiple Phone
instances with the same Set
instance for person
. This can happen when you clone or copy a Phone
, or do something like phone1.setPerson(phone2.getPerson())
.
It's okay for the Person
s to be the same, but not the Set
itself. Each phone should create a new instance of a Set
that is only used within the entity.
You can make sure of this, by instantiating collections in the constructor or directly after declaration and then never calling the setter for the collection, e.g.
private Set<Person> person = new HashSet<Person>();
void addPerson(Person person) {
this.person.add(person);
}
and only use addPerson
, never setPerson
(you can add similar helper methods to add multiple persons, or remove a person, etc.).
You can also return a copy of the set instead of the set itself in the getPerson
getter to be sure that the collection instance never leaks out.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论