1 Reply Latest reply on Dec 23, 2009 6:05 AM by wolfgangknauf

    LazyInitializationException Problem and need your accurate help

      I'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.

        • 1. Re: LazyInitializationException Problem and need your accurate help
          wolfgangknauf

          Hi,

           

          I think this is quite easy to fix: change the code of "assignSpecializationToDoctor" to this:

           

          public void assignSpecializationToDoctor(Specialization spec, Doctor doctor, String certificateDegree) {
                  spec = em.merge(spec);
                  doctor = em.merge(doctor);
                  DoctorSpecializations docSpec = new DoctorSpecializations(certificateDegree, doctor ,spec);
                  em.persist(docSpec);
          }

           

          The reason for this: the parameters for "merge" are still detached after merging. Thus, you will receive the "LazyInitializationException" when accessing the relationship. To make them "attached", assign the return value of "merge" to them.

           

          Hope this helps

           

          Wolfgang