LazyInitializationException Problem and need your accurate help
daziplqa Dec 22, 2009 10:01 AMI've many to many relation ship with a column, So I choosed to add extra entity
I've a doctor , specialization of the doctor and a bridge entiy between the two entites contain the two primary keys plus a field named "certification"
Doctor entity:
@Entity @Table(name = "doctors", catalog = "hospital") @TableGenerator(name="doctors", pkColumnName="seq_name", valueColumnName="seq_count", table="sequence_table") public class Doctor implements java.io.Serializable { private int doctorId; private String username; private String password; private double sessionPrice; private double sessionLength; private Set<DoctorSpecializations> doctorSpecializations = new HashSet<DoctorSpecializations>(); public Doctor() { } public Doctor(String username, String password, double sessionPrice, double sessionLength) { this.username = username; this.password = password; this.sessionPrice = sessionPrice; this.sessionLength = sessionLength; } .......... ........ }
Specilization entity:
@Entity @Table(name = "specializations", catalog = "hospital") @TableGenerator(name="specializations", pkColumnName="seq_name", valueColumnName="seq_count", table="sequence_table") public class Specialization implements java.io.Serializable { private int specId; private String specName; private Set<DoctorSpecializations> doctorSpecializations = new HashSet<DoctorSpecializations>(); public Specialization() { } public Specialization(String specName) { this.specName = specName; } ....................... ....................... }
DoctorSpecializations entity:
@Entity @Table(name="doctors_specializations", catalog="hospital") public class DoctorSpecializations implements Serializable{ @Embeddable private static class Id implements Serializable { private int doctorId; private int specId; @Column(name="doctor_id") public int getDoctorId() { return doctorId; } public void setDoctorId(int doctorId) { this.doctorId = doctorId; } @Column(name="spec_id") public int getSpecId() { return specId; } public void setSpecId(int specId) { this.specId = specId; } public Id() { } public Id (int doctor_id, int spec_id) { this.doctorId = doctor_id; this.specId = spec_id; } public boolean equals(Object obj) { if( obj !=null && obj instanceof Id) { Id that = (Id) obj; return this.getDoctorId() == that.getDoctorId() && this.getSpecId() == that.getSpecId(); } return false; } public int hashCode() { return this.getDoctorId() + this.getSpecId(); } } private Id id = new Id(); private String certificateDegree; private Doctor doctor; private Specialization spec; public DoctorSpecializations() { } public DoctorSpecializations(String certificateDegree, Doctor doctor, Specialization specialization) { this.certificateDegree = certificateDegree; this.doctor = doctor; this.spec = specialization; // set identifier values this.getId().setDoctorId(this.getDoctor().getDoctorId()); this.getId().setSpecId(this.getSpec().getSpecId()); //Guarantee referential integrity this.doctor.getDoctorSpecializations().add(this); this.spec.getDoctorSpecializations().add(this); } @EmbeddedId public Id getId() { return id; } @SuppressWarnings("unused") private void setId(Id id) { this.id = id; } @Column(name="certificate_degree") public String getCertificateDegree() { return certificateDegree; } public void setCertificateDegree(String certificateDegree) { this.certificateDegree = certificateDegree; } @ManyToOne @JoinColumn(name="doctor_id", insertable=false, updatable=false) public Doctor getDoctor() { return doctor; } public void setDoctor(Doctor doctor) { this.doctor = doctor; } @ManyToOne @JoinColumn(name="spec_id", insertable=false, updatable=false) public Specialization getSpec() { return spec; } public void setSpec(Specialization spec) { this.spec = spec; } }
I've a bean method that update the doctor entiy and specialization entity and add a record in the bridge table:
public void assignSpecializationToDoctor(Specialization spec, Doctor doctor, String certificateDegree) { em.merge(spec); em.merge(doctor); DoctorSpecializations docSpec = new DoctorSpecializations(certificateDegree, doctor ,spec); em.persist(docSpec); }
but it throws an exception:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role:
when I try to invoke the assignSpecializationToDoctor method, I think that the problem in the Constructor of DoctorSpecializations the two lines :
this.doctor.getDoctorSpecializations().add(this); this.spec.getDoctorSpecializations().add(this);
the GetDoctorSpecializations() is called on a lazily initialized objects (doctor and spec) but in the assignSpecializationToDoctor I do update both entities before calling the collection getter method:
em.merge(spec); em.merge(doctor); DoctorSpecializations docSpec = new DoctorSpecializations(certificateDegree, doctor ,spec); em.persist(docSpec);
Please Help.
Thanks.