Map Hibernate classes with composite-id and joined-subclass

1

How can I map a class with composite-id and extend another class? I'm using the example in: http://www.javacodegeeks.com/2012/08/hibernate-composite-ids-with.html I have tried to change the code, but when I try to insert data using this mapping it returns the error: Column 'ID' cannot be null

Report.java

public class Report implements Serializable{

    private static final long serialVersionUID = 9146156921169669644L;

    private Integer id;
    private String name;
    private Set<ReportSummary> reportSummaryList  = new HashSet<ReportSummary>();

    public Integer getId() {
         return id;
    }
    public void setId(Integer id) {
         this.id = id;
    }
    public String getName() {
         return name;
    }
    public void setName(String name) {
         this.name = name;
    }
    public Set<ReportSummary> getReportSummaryList() {
         return reportSummaryList;
    }
    public void setReportSummaryList(Set<ReportSummary> reportSummaryList) {
         this.reportSummaryList = reportSummaryList;
    }
}

Report.hbm.xml

<hibernate-mapping>
    <class name="com.example.domain.Report" table="REPORT" >
         <id name="id" type="int" column="id" >
                 <generator class="native"/>
         </id>
         <property name="name">
               <column name="NAME" />
         </property>
         <set name="reportSummaryList" table="REPORT_SUMMARY" cascade="all" inverse="true">
             <key column="RPT_ID" not-null="true"></key>
             <one-to-many class="com.example.domain.ReportSummary"/>
         </set>
     </class>
</hibernate-mapping>

ReportSummary.java

public class ReportSummary implements Serializable {

private static final long serialVersionUID = 8052962961003467437L;

private ReportSummaryId id;
private String name;

public ReportSummaryId getId() {
    return id;
}
public void setId(ReportSummaryId id) {
    this.id = id;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    result = prime * result + ((name == null) ? 0 : name.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;
    ReportSummary other = (ReportSummary) obj;
    if (id == null) {
       if (other.id != null)
          return false;
       } else if (!id.equals(other.id))
          return false;
    if (name == null) {
       if (other.name != null)
          return false;
       } else if (!name.equals(other.name))
          return false;

   return true;
  }
}

ReportSummaryId.java

public class ReportSummaryId implements Serializable{

private static final long serialVersionUID = 6911616314813390449L;

private Integer id;
private Report report;

public Integer getId() {
   return id;
}
public void setId(Integer id) {
   this.id = id;
}
public Report getReport() {
   return report;
}
public void setReport(Report report) {
   this.report = report;
}
@Override
public int hashCode() {
   final int prime = 31;
   int result = 1;
   result = prime * result + ((id == null) ? 0 : id.hashCode());
   result = prime * result + ((report == null) ? 0 : report.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;
   ReportSummaryId other = (ReportSummaryId) obj;
   if (id == null) {
      if (other.id != null)
         return false;
      } else if (!id.equals(other.id))
         return false;
   if (report == null) {
      if (other.report != null)
         return false;
      } else if (!report.equals(other.report))
         return false;

   return true;
  }
}

ReportSummaryDetailed.java

public class ReportSummaryDetailed extends ReportSummary {

private static final long serialVersionUID = -7542202157126903815L;

private String detalhe;


public String getDetalhe() {
    return detalhe;
}
public void setDetalhe(String detalhe) {
    this.detalhe = detalhe;
}
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((super.getId() == null) ? 0 : super.getId().hashCode());
    result = prime * result + ((super.getName() == null) ? 0 : super.getName().hashCode());
    result = prime * result + ((detalhe == null) ? 0 : detalhe.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;
    ReportSummaryDetailed other = (ReportSummaryDetailed) obj;
    if (super.getId() == null) {
       if (other.getId() != null)
          return false;
       } else if (!super.getId().equals(other.getId()))
          return false;
    if (super.getName() == null) {
       if (other.getName() != null)
          return false;
       } else if (!super.getName().equals(other.getName()))
          return false;
    if (detalhe == null) {
        if (other.detalhe != null)
           return false;
        } else if (!detalhe.equals(other.detalhe))
           return false;

   return true;
  }
}

ReportSummary.hbm.xml

<hibernate-mapping>
    <class name="com.example.domain.ReportSummary" table="REPORT_SUMMARY" >
        <composite-id name="id" class="com.example.domain.ReportSummaryId">
             <key-property name="id" column="ID"></key-property>
             <key-many-to-one name="report" 
                              class="com.example.domain.Report"
                              column="RPT_ID"></key-many-to-one>
        </composite-id>
        <property name="name">
             <column name="NAME" />
        </property>

        <joined-subclass name="com.example.domain.ReportSummaryDetailed" extends="ReportSummary" table="REPORT_SUMMARY_DETAILED" >
            <key>
                <column name="ID" />
                <column name="RPT_ID" />
            </key>

            <property name="detalhe">
             <column name="DETALHE" />
        </property>

        </joined-subclass>


    </class>
</hibernate-mapping>
    
asked by anonymous 28.03.2014 / 14:31

1 answer

1

The problem is not that your class is extending another. The problem is that composite-id implies that you know the values beforehand, so the ID field used in the composite-id is not automatically generated. Try to manually setId() on your ReportSummaryId to verify this.

I imagine you are working with some legacy system, but for new systems, you would say that you should not use compound IDs, and you should use annotations instead of XML mappings. For high performance IDs, it is still better to use UUID, especially if the system is distributed. I know that these comments do not influence the resolution of your problem, but may help design a new system ;-)

    
28.03.2014 / 15:51