Thank-you very much for your reponse and assistance.
Quote:
(1) I *think* you should be using a collection where attribute instead of one of the <key> elements
Yes, that takes care of the problem (so far as I know at the moment) but I don't relish the "hardcoded" type=1 (et. al.) in the
where although since my values aren't going to change I can live with it. I'm curious though if there is a way to specify the value of a property in the mapping?
Quote:
(2) I suspect you should use a <bag> mapping instead of <list> ... don't think Hibernate will tolerate the <element> and <index> columns being the same - and certainly it seems semantically incorrect
I switched to Set; you are correct, they cannot be the same.
Quote:
I hope you are using 2.1 beta 2 in that case! :)
I am using 2.0.3 but I may switch in a couple minutes to see what will happen to the problem described below...
Now that my mapping seems to be correct (at least correct enough for the moment not to complain) I am getting the most peculiar results (I will post full mapping and code below...).
I have three classes, the first one has a one-to-many relationship with the second which has a one-to-many relationship with the third which is the one with the simplified snipit I had problems with mapping.
The strange thing is that the List of instances of the "middle" class held by the first class contains 19 null entries and 1 seemingly valid one at the end of the List. There is no data corellation that I can see for the 19 null records. Following is the code and the debugging output:
The mappings:
Code:
<hibernate-mapping>
<!-- WorksheetProduct -->
<class name="com.fgl.ina.costestimation.WorksheetProduct" table="worksheet_product">
<id name="ID" type="integer" column="worksheet_product_id">
<generator class="net.sf.hibernate.id.IncrementGenerator"/>
</id>
<!-- <many-to-one name="worksheetID" column="worksheet_id" not-null="true"/>-->
<property name="productID" column="ina_prod_id" type="long"/>
<property name="unitOfMeasureQuantity" column="uom_qty" type="float"/>
<list name="costFactors" table="worksheet_factor" lazy="false" cascade="all">
<key column="worksheet_product_id"/>
<index column="worksheet_factor_id"/>
<one-to-many class="com.fgl.ina.costestimation.WorksheetFactor"/>
</list>
</class>
<!-- WorksheetHeader -->
<class name="com.fgl.ina.costestimation.WorksheetHeader" table="worksheet_header">
<id name="worksheetID" type="integer" column="worksheet_id">
<generator class="net.sf.hibernate.id.IncrementGenerator"/>
</id>
<property name="description" column="description" type="string"/>
<property name="vendor" column="vendor_no" type="string" not-null="true"/>
<property name="status" column="status" type="short" not-null="true"/>
<property name="createdBy" column="created_by" type="string" not-null="true"/>
<property name="createdDate" column="created_date" type="timestamp" not-null="true"/>
<property name="revisedDate" column="last_revision_date" type="timestamp" not-null="true"/>
<property name="foreignStatus" column="foreign_status" type="short" not-null="true"/>
<property name="foreignContractNo" column="foreign_contract_no" type="long" not-null="true"/>
<property name="comments" column="comments" type="string"/>
<list name="products" table="worksheet_product" lazy="false" cascade="all">
<key column="worksheet_id"/>
<index column="worksheet_product_id"/>
<one-to-many class="com.fgl.ina.costestimation.WorksheetProduct"/>
</list>
</class>
<!-- WorksheetFactor -->
<class name="com.fgl.ina.costestimation.WorksheetFactor" table="worksheet_factor">
<id name="ID" type="integer" column="worksheet_factor_id">
<generator class="net.sf.hibernate.id.IncrementGenerator"/>
</id>
<!-- <many-to-one name="worksheetProductID" column="worksheet_product_id" />-->
<property name="costFactorID" column="cost_factor_id" type="integer"/>
<property name="calculatedType" column="calculated_type" type="short"/>
<set order-by="allowable_type" name="calculatedTypeOptions" table="cost_factor_values" lazy="false" cascade="none" where="type=1">
<key column="cost_factor_id"/>
<!-- <index column="allowable_type" type="short"/>-->
<element column="allowable_type" type="short"/>
</set>
<property name="costFactorValue" column="cost_factor_value" type="float"/>
<property name="foreignAmount" column="foreign_amount" type="float"/>
<property name="currencyType" column="currency_type" type="short"/>
<set order-by="allowable_type" name="currencyTypeOptions" table="cost_factor_values" lazy="false" cascade="none" where="type=2">
<key column="cost_factor_id"/>
<!-- <index column="allowable_type" type="short"/>-->
<element column="allowable_type" type="short"/>
</set>
<property name="exchangeRate" column="exchange_rate" type="float"/>
<property name="proratingType" column="prorating_type" type="short"/>
<set order-by="allowable_type" name="proratingTypeOptions" table="cost_factor_values" lazy="false" cascade="none" where="type=3">
<key column="cost_factor_id"/>
<!-- <index column="allowable_type" type="short"/>-->
<element column="allowable_type" type="short"/>
</set>
<!-- <property name="language" column="locale" type="string"/>-->
<!-- <property name="description" column="description" type="string"/>-->
</class>
</hibernate-mapping>
The method for retrieving instances:
Code:
/**
* Retrieves a persisted worksheet (i.e. {@link WorksheetHeader} instance) identified by the specified ID.
* @param worksheetID the ID of the worksheet to retrieve
* @return the <code>WorksheetHeader</code> instance.
* @throws Exception
*/
public static WorksheetHeader getWorksheetByID(int worksheetID) throws Exception {
Session session = DataAccessServiceHelper.getSession();
WorksheetHeader returnHeader = null;
try {
returnHeader = (WorksheetHeader)session.createCriteria(WorksheetHeader.class).add(
Expression.eq(WORKSHEET_ID, new Integer(worksheetID))).list().get(0);
} catch (Throwable t) {
LogFactory.getLog(WorksheetService.class).error("Could not load worksheet " + worksheetID, t);
} finally {
session.close();
}
return returnHeader;
}
The class WorksheetHeader:
Code:
package com.fgl.ina.costestimation;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
/**
* Bean containing the header level information for a worksheet as well as the <code>Collection</code>s of sub data.
* @author David Duffy
*/
public class WorksheetHeader {
private int worksheetID = 0;
private String description = null;
private String vendor = null;
private short status = 0;
private String createdBy = null;
private Date createdDate = null;
private Date revisedDate = null;
private short foreignStatus = 0;
private Long foreignContractNo = null;
private String comments = null;
private String vpn = null;
private List products = new ArrayList();
/**
* A lot of getters and setters follow...
*/
// ...
}
The debugging line:
Code:
System.out.println("\n\n*** worksheet.products = " + worksheet.getProducts() + "\n");
Prior to the above line running the variable
worksheet has been set to the return value of the
getWorksheetByID(...) method.
The
println(...) generates the following:
Code:
*** worksheet.products = [null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, com.fgl.ina.costesti
mation.WorksheetProduct@129b073]
Any ideas why this is occurring?
Thank-you again.
Sincerely,
David