I am taking over a project from a guy. They did a great job and claim that this coded worked. I can't get it to work and search through the forums trying to figure out how to fix it.
We are using SQL 2005 and NHibernate 1.2
AftermarketOption.HBM
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DT.S" namespace="DT.S.DomainModel">
<class name="AftermarketOption" table="AftermarketOptions">
<id name="Index" type="Int64" unsaved-value="0">
<column name="OptionIndex" length="8" sql-type="bigint" not-null="true" unique="true" index="PK_OptionIndex"/>
<generator class="native" />
</id>
<bag access="field" name="_products" cascade="all-delete-orphan" lazy="true">
<key column="AftermarketOptionIndex" />
<one-to-many class="AftermarketOptionProduct"/>
</bag>
<property name="Name" type="String">
<column name="OptionName" not-null="true" sql-type="varchar" length="50" />
</property>
<property name="Price" type="Decimal">
<column name="OptionPrice" sql-type="money" not-null="false" />
</property>
<property name="DisplayColor" type="string">
<column name="DisplayColor" sql-type="varchar" length="6" not-null="false" />
</property>
</class>
</hibernate-mapping>
AftermarketProduct.HBM
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DT.S" namespace="DT.S.DomainModel">
<class name="AftermarketProduct" table="AftermarketProducts" lazy="false">
<id name="Index" type="Int64" unsaved-value="0">
<column name="ProductIndex" length="8" sql-type="bigint" not-null="true" unique="true" index="PK_ProductIndex"/>
<generator class="native" />
</id>
<property name="ShortDescription" type="String">
<column name="ShortDesc" length="100" sql-type="varchar" not-null="false" />
</property>
<property name="LongDescription" type="String">
<column name="Details" sql-type="text" not-null="false" />
</property>
<property name="DisplayName" type="String">
<column name="Code" sql-type="varchar" length="10" not-null="false" />
</property>
<property name="Price" type="Decimal">
<column name="PriceAmount" sql-type="money" not-null="false" />
</property>
<property name="DealerCost" type="Decimal">
<column name="DealerCost" sql-type="money" not-null="false" />
</property>
</class>
</hibernate-mapping>
AftermarketOptionProduct.HBM
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" >
<joined-subclass name="AftermarketOptionProduct" extends="AftermarketProduct" table="AftermarketOptionProducts" lazy="true">
<key column="AftermarketProductIndex"/>
<property name="DisplayOrder" type="Int32">
<column name="DisplayOrder" sql-type="tinyint" not-null="false"/>
</property>
<many-to-one name="Option" class="AftermarketOption" cascade="all-delete-orphan">
<column name="AftermarketOptionIndex" sql-type="bigint" not-null="true"/>
</many-to-one>
</joined-subclass>
</hibernate-mapping>
The classes that these HBM files reference.
AftermarketOption.cs
Code:
public class AftermarketOption : DomainObject<Int64> {
private string _name;
private int _order;
private IList<AftermarketOptionProduct> _products;
private decimal _price;
private string _displayColor;
#region List Properties
public virtual List<AftermarketOptionProduct> xProducts {
get { return new List<AftermarketOptionProduct>(_products); }
set { _products = value; }
}
public virtual string DisplayColor {
get { return _displayColor; }
set { _displayColor = value; }
}
public virtual string Name {
get { return _name; }
set { _name = value; }
}
public virtual int DisplayOrder {
get { return _order; }
set { _order = value; }
}
public virtual IList<AftermarketOptionProduct> Products {
get { return _products; }
}
public virtual decimal Price {
get { return _price; }
set { _price = value; }
}
public AftermarketOption() {
_products = new List<AftermarketOptionProduct>();
}
}
AftermarketProduct.cs
Code:
public class AftermarketProduct : DomainObject<Int64>{
private string _displayName;
private string _longDescription;
private string _shortDescription;
private decimal _price;
private decimal _dealerCost;
public virtual decimal DealerCost {
get { return _dealerCost; }
set { _dealerCost = value; }
}
public virtual string DisplayName {
get { return _displayName; }
set { _displayName = value; }
}
public virtual string LongDescription {
get { return _longDescription; }
set { _longDescription = value; }
}
public virtual decimal Price {
get { return _price; }
set { _price = value; }
}
public virtual string ShortDescription {
get { return _shortDescription; }
set { _shortDescription = value; }
}
}
AftermarketOptionProduct.cs
Code:
public class AftermarketOptionProduct : AftermarketProduct {
private int _displayOrder;
private AftermarketOption _option;
public virtual int DisplayOrder {
get { return _displayOrder; }
set { _displayOrder = value; }
}
public virtual AftermarketOption Option {
get { return _option; }
set { _option = value; }
}
public AftermarketOptionProduct() { }
public AftermarketOptionProduct(AftermarketProduct ap) {
this.DealerCost = ap.DealerCost;
this.DisplayName = ap.DisplayName;
this.LongDescription = ap.LongDescription;
this.Price = ap.Price;
this.ShortDescription = ap.ShortDescription;
}
public AftermarketOptionProduct(AftermarketProduct ap, int displayOrder): this(ap) {
this._displayOrder = displayOrder;
}
}
Here is the test code I am using to test the mappings.
Code:
IList<AftermarketProduct> products = DaoFactory.GetAftermarketProduct().GetAll();
AftermarketOption ao = new AftermarketOption();
ao.DisplayColor = "Blue";
ao.DisplayOrder = 1;
ao.Name = "AftermarketOption 1";
ao.Price = 1234;
for (int i = 0; i < products.Count; i++) {
AftermarketOptionProduct aop = new AftermarketOptionProduct(products[i], i+1);
aop.Option = ao;
aop.Index = products[i].Index;
ao.Products.Add(aop);
}
DaoFactory.GetAftermarketOptionDao().SaveOrUpdate(ap);
Here is the tables that I have that I am using:
Code:
CREATE TABLE AftermarketProducts
(
ProductIndex bigint NOT NULL IDENTITY (1, 1),
Code varchar(10) NULL,
ShortDesc varchar(100) NULL,
Details text NULL,
PriceAmount money NULL,
DealerCost money NULL
) ON [PRIMARY]
go
ALTER TABLE AftermarketProducts ADD CONSTRAINT
PK_ProductIndex PRIMARY KEY CLUSTERED
(
ProductIndex
) WITH( PAD_INDEX = OFF, FILLFACTOR = 90, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
go
CREATE TABLE AftermarketOptions
(
OptionIndex bigint NOT NULL IDENTITY (1, 1),
OptionName varchar(50) NOT NULL,
OptionPrice money NULL,
DisplayOrder bigint NULL,
DisplayColor varchar(6) NULL
) ON [PRIMARY]
go
ALTER TABLE AftermarketOptions ADD CONSTRAINT
PK_OptionIndex PRIMARY KEY CLUSTERED
(
OptionIndex
) WITH( PAD_INDEX = OFF, FILLFACTOR = 90, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
go
CREATE TABLE AftermarketOptionProducts
(
AftermarketOptionIndex bigint NOT NULL,
AftermarketProductIndex bigint NOT NULL,
DisplayOrder bigint NULL
) ON [PRIMARY]
go
ALTER TABLE AftermarketOptionProducts ADD CONSTRAINT
FK_AftermarketOptionProducts_AftermarketOptionIndex FOREIGN KEY
(
AftermarketOptionIndex
) REFERENCES AftermarketOptions
(
OptionIndex
) ON UPDATE NO ACTION
ON DELETE NO ACTION
go
ALTER TABLE AftermarketOptionProducts ADD CONSTRAINT
FK_AftermarketOptionProducts_AftermarketProductIndex FOREIGN KEY
(
AftermarketProductIndex
) REFERENCES AftermarketProducts
(
ProductIndex
) ON UPDATE NO ACTION
ON DELETE NO ACTION
go
ALTER TABLE AftermarketOptionProducts ADD CONSTRAINT
PK_AftermarketOptionProducts PRIMARY KEY CLUSTERED
(
AftermarketProductIndex,
AftermarketOptionIndex
) WITH( PAD_INDEX = OFF, FILLFACTOR = 90, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
go
This issue I am having is that the AftermarketOption has a list of products that are extended AftermarketProducts only with an order. I will continue to look into this but I haven't found anything that helps yet. I am hoping there is someone in the communitiy that can help.
For a while I was getting that NonUniqueObjectExecption error because I was getting a list of the products first. The products have already been created and are going to be in multiple AftermarketOptions. I solved that by clearing the session. In the log it saves the AftermarketOption correctly but as soon as it tries to add the products it dies and rolls back.
Am I missing something obvious or is this even possible?
Thanks for all the help in advance.
I am willing to do whatever it takes to get this to work.