2016-11-17 3 views
0

я прочитал через много потоков на StackOverflow примерно тем же исключением, но я не нашел ничего, что на самом деле помогает мне, поэтому я здесь:PersistenceException: отдельностоящий объект передается упорствовать

У меня 2 классов сущностей:

класс Учитель:

@Entity 
@Table(name="teachers") 
public class Teacher extends Model{ 

public Teacher() 

@Id 
@GeneratedValue(strategy=GenerationType.IDENTITY) 
private int id; 

@OneToMany(fetch=FetchType.LAZY, mappedBy="teacher") 
private List<Student> students; 

//getter and setter 
} 

класс Student:

@Entity 
@Table(name="students") 
public class Student extends Model{ 

public Student(){} 
public Student(Teacher teacher){this.teacher = teacher;} 

@Id 
@GeneratedValue(strategy=GenerationType.IDENTITY) 
private int id; 

@ManyToOne(fetch=FetchType.LAZY, cascade={CascadeType.ALL}) 
@JoinColumn(name="teacher_id") 
private Teacher teacher; 

//getter and setter 
} 

Модель класса:

public abstract class Model implements Serializable { 

public void save() { 
EntityManager entityManager = HibernateUtil.getEntityManagerFactory().createEntityManager(); 
entityManager.getTransaction().begin(); 
entityManager.persist(this); 
entityManager.getTransaction().commit(); 
entityManager.close(); 
} 

public void merge(){ 
EntityManager entityManager = HibernateUtil.getEntityManagerFactory().createEntityManager(); 
entityManager.getTransaction().begin(); 
entityManager.merge(this); 
entityManager.getTransaction().commit(); 
entityManager.close(); 
} 
} 

Я создал класс Test, чтобы вставить несколько значений в БД:

public class TestClass{ 

Teacher teacher; 
teacher = new Teacher(); 

Student student_1; 
Student student_2; 

student_1 = new Student(teacher); 
student_1.save(); 

student_2 = new Student(teacher); 
student_2.save(); 

} 

student_2.save() бросает исключение (учитель отдельностоящий организация). Но почему? Я понимаю, что учитель уже сохраняется и транзакция закончена, но CascadeType.ALL включает в себя также слияние, которое должно позаботиться об этом (или, очевидно, нет. Возможно, здесь и не так), но затем работает:

student_2 .merge() вместо student_2.save() работает, хотя ~

Другим решением было бы удалить cascadeType.ALL и продолжить учитель перед тем, как продолжить студент, но это не то, что я хочу.

ответ

0

Каскад отличается от того, что вы думаете. Он вызывает ту же функцию для связанных объектов. Поэтому, если вы вызовете em.persist (ученик), он будет называть упор на учителя.

Я думаю, вы, вероятно, не хотите каскадировать что-либо от ученика до учителя. Если вы продолжаете учитель в транзакции, а затем связываете его только со студентами в других транзакциях, у вас нет каскадов для учителя.

+0

О, я вижу. Причина, по которой я использую каскад, состоит в том, что класс Student может иметь список . Что делать, если я создаю нового ученика без учителя и потом назначу учителю и субъектам, - тогда я также просто хотел бы продолжить Студент, не делая ничего другого, и для этого требуется CascadeType.ALL (и в основном показывает, почему мне нужно заставить его работать в моей исходной папке) – M4V3N

+0

Вы можете добавить учителя позже к ученику и обновить ученика без каскада, и это сэкономит штраф. Обратите внимание, что если вы находитесь в транзакции, вы можете настроить реквизит на объект, и он будет обновляться до БД (нет необходимости вызывать слияние ..) – Gerhard

+0

Для ссылки на объекты вам нужен каскад. В противном случае вам нужно вызвать сохранение отдельных предметов, если они новы. – Gerhard

Смежные вопросы