當我想填充連接表時,我得到了 StackOverflowError ......請參閱下面的代碼。
我有兩個物體:
@Entity
public class User {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long userId;
@ManyToMany
@JoinTable(
name = "user_appointment",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "appointment_id"))
Set<Appointment> subscribedAppointments;
}
@Entity
public class Appointment {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long appointmentId;
@JsonIgnore
@ManyToMany(mappedBy = "subscribedAppointments")
Set<User> subscribers; //users who added this appointment to their calendar
}
當我嘗試如下填寫聯接表時:
user.setSubscribedAppointments(appointment); //sheikh fuad
appointment.setSubscribers(user);
appointmentRepository.save(appointment);
userRepository.save(user);
我得到 StackoverflowError:
java.lang.StackOverflowError: null
at java.base/java.lang.Exception.<init>(Exception.java:102) ~[na:na]
at java.base/java.lang.ReflectiveOperationException.<init>(ReflectiveOperationException.java:89) ~[na:na]
at java.base/java.lang.reflect.InvocationTargetException.<init>(InvocationTargetException.java:73) ~[na:na]
at jdk.internal.reflect.GeneratedMethodAccessor60.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:56) ~[hibernate-core-5.4.15.Final.jar:5.4.15.Final]
at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95) ~[hibernate-core-5.4.15.Final.jar:5.4.15.Final]
at com.taqwaapps.entity.Country$HibernateProxy$pGwXHWph.hashCode(Unknown Source) ~[classes/:na]
at com.taqwaapps.entity.City.hashCode(City.java:25) ~[classes/:na]
at jdk.internal.reflect.GeneratedMethodAccessor59.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:56) ~[hibernate-core-5.4.15.Final.jar:5.4.15.Final]
at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95) ~[hibernate-core-5.4.15.Final.jar:5.4.15.Final]
at com.taqwaapps.entity.City$HibernateProxy$9IT2B41W.hashCode(Unknown Source) ~[classes/:na]
at com.taqwaapps.entity.District.hashCode(District.java:21) ~[classes/:na]
at com.taqwaapps.entity.Appointment.hashCode(Appointment.java:31) ~[classes/:na]
at java.base/java.util.ImmutableCollections$Set12.hashCode(ImmutableCollections.java:520) ~[na:na]
at com.taqwaapps.entity.User.hashCode(User.java:29) ~[classes/:na]
at com.taqwaapps.entity.Appointment.hashCode(Appointment.java:31) ~[classes/:na]
at java.base/java.util.ImmutableCollections$Set12.hashCode(ImmutableCollections.java:520) ~[na:na]
...
然后這三行重復了很多次:
at com.taqwaapps.entity.User.hashCode(User.java:29) ~[classes/:na]
at com.taqwaapps.entity.Appointment.hashCode(Appointment.java:31) ~[classes/:na]
at java.base/java.util.ImmutableCollections$Set12.hashCode(ImmutableCollections.java:520) ~[na:na]
為用戶設定約會是否正確,反之亦然?或者如何填充由spring生成的連接表?
uj5u.com熱心網友回復:
從評論中,您正在使用Lombok的注釋@EqualsAndHashCode。
如果您檢查生成的代碼,您將看到User正在呼叫SetAppointments(可能由 支持HashSet)哈希碼。呼叫Set of Users 哈希碼的Appointment也是如此。
Lombok 生成如下內容:
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $set = this.getSet();
result = result * PRIME ($set == null ? 43 : $set.hashCode());
return result;
}
如果您看到 HashSet 哈希碼的 JDK 源代碼:
public int hashCode() {
int h = 0;
Iterator<E> i = iterator();
while (i.hasNext()) {
E obj = i.next();
if (obj != null)
h = obj.hashCode();
}
return h;
}
正在迭代該集合以計算每個成員哈希碼。
既然你這樣做:
user.setSubscribedAppointments(appointment); //sheikh fuad
appointment.setSubscribers(user);
在 setXXX 中都會觸發對 hashcode 的呼叫。
stackoverflow 可能發生在第二行,因為用戶作為約會和約會具有相同的用戶。在計算哈希碼時,一個人一遍又一遍地呼叫另一個。
您需要在哈希碼計算中打破這種依賴關系(在 equals 方法中可能會發生同樣的情況)。您需要洗掉或配置@EqualsAndHashCode,因此它確實會在某些時候中斷計算。如果您自己實作哈希碼,那么更簡單的解決方案是僅使用主鍵(如果物體被持久化)進行計算。如果物體沒有持久化,那么您可以使用其他一些欄位,但要注意計算中可能發生的回圈性(您必須避免/破壞它)。
uj5u.com熱心網友回復:
按此順序嘗試..它可能會幫助您保存記錄。
appointment.setSubscribers(user);
appointmentRepository.save(appointment);
user.setSubscribedAppointments(appointment); //sheikh fuad
userRepository.save(user);
uj5u.com熱心網友回復:
物體約會取決于 user_id,當您要保存約會時,它為空。所以首先保存用戶而不在其中設定約會。然后設定用戶預約并保存。最后,為用戶設定約會并再次保存。這意味著您必須具有以下幾行:
userRepository.save(user);
appointment.setSubscribers(user);
appointmentRepository.save(appointment);
user.setSubscribedAppointments(appointment);
userRepository.save(user);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/445647.html
上一篇:為什么Hibernate沒有使用@ManyToMany和@JoinTable注釋在這個MANYTOMANY關聯表上執行JOIN?
