1 Reply Latest reply on Aug 31, 2007 5:14 PM by Nic Holbrook

    Delete of joining entity in a oneToMany -> joinEntity <- one

    John Chesher Newbie

      I've read the FAQ and Hibernate docs on how to do this, but the examples are using Hibernate config files, whereas I am using EJB3 annotations, so I still have remaining problems/questions. I'm posting here instead of an EJB3 forum, as I suspect I am fundamentally misunderstanding how to use Hibernate in this situation. Appreciate any advise you can provide.

      I have a School entity, a Major entity (as in "Computer Science"), and a third entity, SchoolMajor, whose sole purpose is to manage the relationship between a school and the majors it offers. SchoolMajor also contains some boolean values to indicate what level of degree can be attained within that major at that school, so that is why an entity is needed for School Major.

      I can persist data with no problem. I want to delete the SchoolMajor entity whenever all of the six "degree level" booleans have been set to false, but haven't done this successfully yet.

      Other notes:
      1. I'm using Seam, EJB3, Hibernate and Oracle
      2. Major - has no reference to SchoolMajors (or any other entities). It just contains an id, name and description
      3. The code below produces the Oracle error "ORA-02292: integrity constraint (KEYFACT2.FKA146025AB6E4614A) violated - child record found"
      4. I've tried many things, but they either result in this error, or, if I just remove the line "entityManager.remove(sm);" below, no errors are produced, but the SchoolMajor is not actually deleted.
      From the documentation, I understand this is because, by default, the relationship must be managed from the "many" side of the relationship.
      However, I haven't found a way to annotate the inverse="false" option on the oneToMany relationship in School, IF that would solve the problem.
      Any ideas?
      Thanks!

      Here are the relevant code snippets:

      public String updateSchool() {
      
       School currentSchool = (School)currentInstitution;
      
       //remove all SchoolMajors from currentSchool that have no "level" checked.
       Set<SchoolMajor> temp = new HashSet<SchoolMajor>(currentSchool.getSchoolMajors());
      
       for (SchoolMajor sm : temp) {
       if (sm.getAssociates() || sm.getBachelors() || sm.getCertificates()
       || sm.getDiplomas() || sm.getMasters() || sm.getDoctorates()) {
       continue;
       }
       else {
       if (sm.getId() == null) {
       currentSchool.getSchoolMajors().remove(sm);
       }
       else {
       currentSchool.getSchoolMajors().remove(sm);
       entityManager.remove(sm);
       }
       }
       }
      
       currentSchool.setAllPossibleSchoolMajorsLoaded(false);
      
       //finally, persist the updated school
       try {
       entityManager.flush();
       facesMessages.addFromResourceBundle("schoolUpdateSuccess");
       }
       catch (OptimisticLockException e) {
       facesMessages.addFromResourceBundle("schoolOptimisticLock");
       redirect.captureCurrentView();
       return "optimisticLockException";
       }
      
       return "success";
       }


      @Entity
      @Name("school")
      public class School implements Serializable
      {
      ...
      ...
       private Set<SchoolMajor> schoolMajors;
      ...
      ...
      
       @OneToMany(cascade=CascadeType.ALL, mappedBy="school")
       public Set<SchoolMajor> getSchoolMajors()
       {
       return schoolMajors;
       }
       public void setSchoolMajors(Set<SchoolMajor> schoolMajors)
       {
       this.schoolMajors = schoolMajors;
       }
      }


      @Entity
      @Name("schoolMajor")
      @SequenceGenerator(name = "SchoolMajorSequenceGenerator", sequenceName = "KEYFACT2.SCHOOLMAJOR_SEQ", allocationSize = 1)
      public class SchoolMajor implements Serializable
      {
       private static final long serialVersionUID = 918223454065801L;
      
       private Integer id;
       private School school;
       private Major major;
       private Boolean certificates;
       private Boolean diplomas;
       private Boolean associates;
       private Boolean bachelors;
       private Boolean masters;
       private Boolean doctorates;
       private Long version;
      
       public SchoolMajor()
       {
       this.associates = false;
       this.bachelors = false;
       this.certificates = false;
       this.diplomas = false;
       this.masters = false;
       this.doctorates = false;
       }
      
       public SchoolMajor(Integer id, School school, Major major, Boolean certificates, Boolean diplomas, Boolean associates, Boolean bachelors, Boolean masters, Boolean doctorates)
       {
       super();
       this.id = id;
       this.school = school;
       this.major = major;
       this.certificates = certificates;
       this.diplomas = diplomas;
       this.associates = associates;
       this.bachelors = bachelors;
       this.masters = masters;
       this.doctorates = doctorates;
       }
      
       @NotNull
       public Boolean getAssociates()
       {
       return associates;
       }
       public void setAssociates(Boolean associate)
       {
       this.associates = associate;
       }
      
       @NotNull
       public Boolean getBachelors()
       {
       return bachelors;
       }
       public void setBachelors(Boolean bachelors)
       {
       this.bachelors = bachelors;
       }
      
       @NotNull
       public Boolean getCertificates()
       {
       return certificates;
       }
       public void setCertificates(Boolean certificate)
       {
       this.certificates = certificate;
       }
      
       @NotNull
       public Boolean getDiplomas()
       {
       return diplomas;
       }
       public void setDiplomas(Boolean diploma)
       {
       this.diplomas = diploma;
       }
      
       // @NotNull
       @ManyToOne(fetch=FetchType.LAZY)
       public Major getMajor()
       {
       return major;
       }
       public void setMajor(Major major)
       {
       this.major = major;
       }
      
       @NotNull
       public Boolean getMasters()
       {
       return masters;
       }
       public void setMasters(Boolean masters)
       {
       this.masters = masters;
       }
      
       @NotNull
       public Boolean getDoctorates()
       {
       return doctorates;
       }
       public void setDoctorates(Boolean doctorates)
       {
       this.doctorates = doctorates;
       }
      
      
       // @NotNull
       @ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
       // @JoinColumn(name="school_fk")
       public School getSchool()
       {
       return school;
       }
       public void setSchool(School school)
       {
       this.school = school;
       }
      
       @Id
       @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SchoolMajorSequenceGenerator")
       public Integer getId()
       {
       return id;
       }
       public void setId(Integer id)
       {
       this.id = id;
       }
      
       @Version
       public Long getVersion()
       {
       return version;
       }
       public void setVersion(Long version)
       {
       this.version = version;
       }
      
       @Override
       public int hashCode()
       {
       final int PRIME = 31;
       int result = 1;
       result = PRIME * result + ((associates == null) ? 0 : associates.hashCode());
       result = PRIME * result + ((bachelors == null) ? 0 : bachelors.hashCode());
       result = PRIME * result + ((certificates == null) ? 0 : certificates.hashCode());
       result = PRIME * result + ((diplomas == null) ? 0 : diplomas.hashCode());
       result = PRIME * result + ((doctorates == null) ? 0 : doctorates.hashCode());
       result = PRIME * result + ((id == null) ? 0 : id.hashCode());
       result = PRIME * result + ((major == null) ? 0 : major.hashCode());
       result = PRIME * result + ((masters == null) ? 0 : masters.hashCode());
       result = PRIME * result + ((school == null) ? 0 : school.hashCode());
       result = PRIME * result + ((version == null) ? 0 : version.hashCode());
       return result;
       }
      
       @Override
       public boolean equals(Object obj)
       {
       if (this == obj) return true;
       if (obj == null) return false;
       if (getClass() != obj.getClass()) return false;
       final SchoolMajor other = (SchoolMajor) obj;
       if (associates == null)
       {
       if (other.associates != null) return false;
       }
       else if (!associates.equals(other.associates)) return false;
       if (bachelors == null)
       {
       if (other.bachelors != null) return false;
       }
       else if (!bachelors.equals(other.bachelors)) return false;
       if (certificates == null)
       {
       if (other.certificates != null) return false;
       }
       else if (!certificates.equals(other.certificates)) return false;
       if (diplomas == null)
       {
       if (other.diplomas != null) return false;
       }
       else if (!diplomas.equals(other.diplomas)) return false;
       if (doctorates == null)
       {
       if (other.doctorates != null) return false;
       }
       else if (!doctorates.equals(other.doctorates)) return false;
       if (id == null)
       {
       if (other.id != null) return false;
       }
       else if (!id.equals(other.id)) return false;
       if (major == null)
       {
       if (other.major != null) return false;
       }
       else if (!major.equals(other.major)) return false;
       if (masters == null)
       {
       if (other.masters != null) return false;
       }
       else if (!masters.equals(other.masters)) return false;
       if (school == null)
       {
       if (other.school != null) return false;
       }
       else if (!school.equals(other.school)) return false;
       if (version == null)
       {
       if (other.version != null) return false;
       }
       else if (!version.equals(other.version)) return false;
       return true;
       }
      
      }