Java 休眠保存时堆栈溢出错误
我有一个学生表,自动生成的id作为主键,并且一对多映射到电话表 My Phone表有一个复合主键PhonePK,其中包含学生表的电话号码和外键id 如果我只做student.setPhones而不做phonepk.setStudent,它对id的抱怨不能为null。所以我正在设置student.setPhones和phonePk.setStudent。但是现在我在toString上得到了一个stackoverflow错误 我真的不喜欢在一开始就设置为两种方式,但不知道如何绕过id不能为null的错误。我问了很多人,但他们帮不上忙。谁能看一下吗 Student.javaJava 休眠保存时堆栈溢出错误,java,hibernate,one-to-many,composite-key,stack-overflow,Java,Hibernate,One To Many,Composite Key,Stack Overflow,我有一个学生表,自动生成的id作为主键,并且一对多映射到电话表 My Phone表有一个复合主键PhonePK,其中包含学生表的电话号码和外键id 如果我只做student.setPhones而不做phonepk.setStudent,它对id的抱怨不能为null。所以我正在设置student.setPhones和phonePk.setStudent。但是现在我在toString上得到了一个stackoverflow错误 我真的不喜欢在一开始就设置为两种方式,但不知道如何绕过id不能为null的
import java.io.Serializable;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
@Entity
@SuppressWarnings("serial")
public class Student implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String fName;
private String lName;
private String mName;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "id")
private Set<Phone> phones;
/**
* @return the fName
*/
public String getfName() {
return fName;
}
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @return the lName
*/
public String getlName() {
return lName;
}
/**
* @return the mName
*/
public String getmName() {
return mName;
}
/**
* @return the phones
*/
public Set<Phone> getPhones() {
return phones;
}
/**
* @param fName
* the fName to set
*/
public void setfName(final String fName) {
this.fName = fName;
}
/**
* @param id
* the id to set
*/
public void setId(final int id) {
this.id = id;
}
/**
* @param lName
* the lName to set
*/
public void setlName(final String lName) {
this.lName = lName;
}
/**
* @param mName
* the mName to set
*/
public void setmName(final String mName) {
this.mName = mName;
}
/**
* @param phones
* the phones to set
*/
public void setPhones(final Set<Phone> phones) {
this.phones = phones;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return String.format("Student [id=%s, fname=%s, lname=%s, mname=%s, phones=%s]",
id,
fName, lName, mName, phones);
}
}
import java.io.Serializable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
@Entity
@SuppressWarnings("serial")
public class Phone implements Serializable {
@EmbeddedId
private PhonePK PK;
private String color;
/**
* @return the color
*/
public String getColor() {
return color;
}
public PhonePK getPK() {
return PK;
}
/**
* @param color
* the color to set
*/
public void setColor(final String color) {
this.color = color;
}
public void setPK(final PhonePK pK) {
PK = pK;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return String.format("Phone [PK=%s, color=%s]", PK, color);
}
}
import java.io.Serializable;
import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Embeddable
@SuppressWarnings({ "serial" })
public class PhonePK implements Serializable {
@ManyToOne
@JoinColumn(name = "id", insertable = false, updatable = false)
private Student student;
private String phoneNumber;
public String getPhoneNumber() {
return phoneNumber;
}
public Student getStudent() {
return student;
}
public void setPhoneNumber(final String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public void setStudent(final Student student) {
this.student = student;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return String.format("PhonePK [student=%s, phoneNumber=%s]", student, phoneNumber);
}
}
import java.util.LinkedHashSet;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class Main {
public static void main(final String args[]) {
Configuration configuration = new Configuration();
Transaction transaction = null;
configuration.addAnnotatedClass(Student.class);
configuration.addAnnotatedClass(Phone.class);
configuration.configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Student student = new Student();
student.setfName("Bob");
student.setlName("Buster");
Set<Phone> phones = new LinkedHashSet<Phone>();
Phone phone = new Phone();
phone.setColor("Black");
PhonePK phonePK = new PhonePK();
phonePK.setPhoneNumber("1111111111");
phonePK.setStudent(student); // Do not do this? But won't work (id cannot be null
error) if
// commented out??
phone.setPK(phonePK);
phones.add(phone);
student.setPhones(phones);
try {
transaction = session.beginTransaction();
System.out.println(student.toString()); // stackoverflow error!
session.save(student);
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}
PhonePK.java
import java.io.Serializable;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
@Entity
@SuppressWarnings("serial")
public class Student implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String fName;
private String lName;
private String mName;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "id")
private Set<Phone> phones;
/**
* @return the fName
*/
public String getfName() {
return fName;
}
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @return the lName
*/
public String getlName() {
return lName;
}
/**
* @return the mName
*/
public String getmName() {
return mName;
}
/**
* @return the phones
*/
public Set<Phone> getPhones() {
return phones;
}
/**
* @param fName
* the fName to set
*/
public void setfName(final String fName) {
this.fName = fName;
}
/**
* @param id
* the id to set
*/
public void setId(final int id) {
this.id = id;
}
/**
* @param lName
* the lName to set
*/
public void setlName(final String lName) {
this.lName = lName;
}
/**
* @param mName
* the mName to set
*/
public void setmName(final String mName) {
this.mName = mName;
}
/**
* @param phones
* the phones to set
*/
public void setPhones(final Set<Phone> phones) {
this.phones = phones;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return String.format("Student [id=%s, fname=%s, lname=%s, mname=%s, phones=%s]",
id,
fName, lName, mName, phones);
}
}
import java.io.Serializable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
@Entity
@SuppressWarnings("serial")
public class Phone implements Serializable {
@EmbeddedId
private PhonePK PK;
private String color;
/**
* @return the color
*/
public String getColor() {
return color;
}
public PhonePK getPK() {
return PK;
}
/**
* @param color
* the color to set
*/
public void setColor(final String color) {
this.color = color;
}
public void setPK(final PhonePK pK) {
PK = pK;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return String.format("Phone [PK=%s, color=%s]", PK, color);
}
}
import java.io.Serializable;
import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Embeddable
@SuppressWarnings({ "serial" })
public class PhonePK implements Serializable {
@ManyToOne
@JoinColumn(name = "id", insertable = false, updatable = false)
private Student student;
private String phoneNumber;
public String getPhoneNumber() {
return phoneNumber;
}
public Student getStudent() {
return student;
}
public void setPhoneNumber(final String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public void setStudent(final Student student) {
this.student = student;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return String.format("PhonePK [student=%s, phoneNumber=%s]", student, phoneNumber);
}
}
import java.util.LinkedHashSet;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class Main {
public static void main(final String args[]) {
Configuration configuration = new Configuration();
Transaction transaction = null;
configuration.addAnnotatedClass(Student.class);
configuration.addAnnotatedClass(Phone.class);
configuration.configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Student student = new Student();
student.setfName("Bob");
student.setlName("Buster");
Set<Phone> phones = new LinkedHashSet<Phone>();
Phone phone = new Phone();
phone.setColor("Black");
PhonePK phonePK = new PhonePK();
phonePK.setPhoneNumber("1111111111");
phonePK.setStudent(student); // Do not do this? But won't work (id cannot be null
error) if
// commented out??
phone.setPK(phonePK);
phones.add(phone);
student.setPhones(phones);
try {
transaction = session.beginTransaction();
System.out.println(student.toString()); // stackoverflow error!
session.save(student);
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}
Main.java
import java.io.Serializable;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
@Entity
@SuppressWarnings("serial")
public class Student implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String fName;
private String lName;
private String mName;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "id")
private Set<Phone> phones;
/**
* @return the fName
*/
public String getfName() {
return fName;
}
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @return the lName
*/
public String getlName() {
return lName;
}
/**
* @return the mName
*/
public String getmName() {
return mName;
}
/**
* @return the phones
*/
public Set<Phone> getPhones() {
return phones;
}
/**
* @param fName
* the fName to set
*/
public void setfName(final String fName) {
this.fName = fName;
}
/**
* @param id
* the id to set
*/
public void setId(final int id) {
this.id = id;
}
/**
* @param lName
* the lName to set
*/
public void setlName(final String lName) {
this.lName = lName;
}
/**
* @param mName
* the mName to set
*/
public void setmName(final String mName) {
this.mName = mName;
}
/**
* @param phones
* the phones to set
*/
public void setPhones(final Set<Phone> phones) {
this.phones = phones;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return String.format("Student [id=%s, fname=%s, lname=%s, mname=%s, phones=%s]",
id,
fName, lName, mName, phones);
}
}
import java.io.Serializable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
@Entity
@SuppressWarnings("serial")
public class Phone implements Serializable {
@EmbeddedId
private PhonePK PK;
private String color;
/**
* @return the color
*/
public String getColor() {
return color;
}
public PhonePK getPK() {
return PK;
}
/**
* @param color
* the color to set
*/
public void setColor(final String color) {
this.color = color;
}
public void setPK(final PhonePK pK) {
PK = pK;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return String.format("Phone [PK=%s, color=%s]", PK, color);
}
}
import java.io.Serializable;
import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Embeddable
@SuppressWarnings({ "serial" })
public class PhonePK implements Serializable {
@ManyToOne
@JoinColumn(name = "id", insertable = false, updatable = false)
private Student student;
private String phoneNumber;
public String getPhoneNumber() {
return phoneNumber;
}
public Student getStudent() {
return student;
}
public void setPhoneNumber(final String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public void setStudent(final Student student) {
this.student = student;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return String.format("PhonePK [student=%s, phoneNumber=%s]", student, phoneNumber);
}
}
import java.util.LinkedHashSet;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class Main {
public static void main(final String args[]) {
Configuration configuration = new Configuration();
Transaction transaction = null;
configuration.addAnnotatedClass(Student.class);
configuration.addAnnotatedClass(Phone.class);
configuration.configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Student student = new Student();
student.setfName("Bob");
student.setlName("Buster");
Set<Phone> phones = new LinkedHashSet<Phone>();
Phone phone = new Phone();
phone.setColor("Black");
PhonePK phonePK = new PhonePK();
phonePK.setPhoneNumber("1111111111");
phonePK.setStudent(student); // Do not do this? But won't work (id cannot be null
error) if
// commented out??
phone.setPK(phonePK);
phones.add(phone);
student.setPhones(phones);
try {
transaction = session.beginTransaction();
System.out.println(student.toString()); // stackoverflow error!
session.save(student);
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}
import java.util.LinkedHashSet;
导入java.util.Set;
导入org.hibernate.hibernateeexception;
导入org.hibernate.Session;
导入org.hibernate.SessionFactory;
导入org.hibernate.Transaction;
导入org.hibernate.cfg.Configuration;
公共班机{
公共静态void main(最终字符串参数[]){
配置=新配置();
事务=空;
配置.addAnnotatedClass(Student.class);
configuration.addAnnotatedClass(Phone.class);
configure(“hibernate.cfg.xml”);
SessionFactory SessionFactory=configuration.buildSessionFactory();
Session Session=sessionFactory.openSession();
学生=新生();
student.setfName(“Bob”);
student.setlName(“Buster”);
Set phones=new LinkedHashSet();
电话=新电话();
手机。设置颜色(“黑色”);
PhonePK PhonePK=新的PhonePK();
电话号码(“1111111”);
phonePK.setStudent(student);//不这样做?但不起作用(id不能为null
错误)如果
//注释掉??
phone.setPK(phonePK);
电话。添加(电话);
学生电话;
试一试{
事务=session.beginTransaction();
System.out.println(student.toString());//堆栈溢出错误!
保存(学生);
commit();
}捕获(休眠异常e){
transaction.rollback();
e、 printStackTrace();
}最后{
session.close();
}
}
}
这是因为您定义toString()方法的方式
学生的
toString()
正在调用Phone的toString()
,后者正在调用PhonePK的toString()
,后者反过来调用学生的toString()
…导致无限循环。让我们详细看看它是如何发生的
在Student
toString()
中,因为其中包含phones
实例变量。它将遍历每个电话并调用电话toString()
在Phone
toString()
中,因为其中的PK
实例变量。它将调用PhonePKtoString()
在PhonePK
toString()
中,因为其中的phoneNumber
实例变量。它将调用PhonetoString()
好的,谢谢。。我纠正了它。已从PhonePK toString方法中删除学生实例变量。但是有没有一种方法可以避免循环引用?我不想同时做student.setPhones和phone.setStudent。hibernate不应该处理这个吗?