I'm building a MultiLingual application, with some dynamic translations in it. Therefor I've chosen to make separate tables for the products, that include the translations.
No I'm having trouble to insert the translations, they are a part of the product. Which is inserted.
<class name="Product" table="Product">
<id name="Id">
<generator class="native" />
</id>
<property name="SomeOtherStuff" column="SomeOtherStuff" />
<set name="NaamTranslations" cascade="all">
<key column="ProductId" not-null="true" />
<one-to-many class="ProductTranslation" />
</set>
</class>
<class name="ProductTranslation"
table="ProductTranslation" lazy="false">
<id name="Id">
<generator class="native" />
</id>
<many-to-one name="Product" column="ProductId" not-null="true"
index="UQ_ProductTranslation" class="Product"
cascade="all-delete-orphan" />
<property name="CultureCode" column="LanguageCode"
not-null="true" index="UQ_ProductTranslation" />
<property name="Name" column="Name" not-null="true" />
</class>
My guess is that the problem is somewhere in the configuration of NHibernate. As I can follow the creation of the product throughout the code. Also I've put the show_sql on, and it is showing the creation of the Product, but it is lacking the inserts of the ProductTranslations.
INSERT INTO dbo.Product (SomeOtherStuff) VALUES (@p0);
select SCOPE_IDENTITY(); @p) = 'Hello this is a test' [Type: String (4000)]
The above mapping should be working. It will just generate not always wanted SQL statements.
ProductTranslation
, without reference to Product table (the ProductId
column must be nullable)ProductId
referenceSo, this a bit complicated SQL statements will work even for this kind of C# assignment
var p = new Product();
var tr1 = new ProductTranslation();
var tr2 = new ProductTranslation();
p.NaamTranslations.Add(tr1);
p.NaamTranslations.Add(tr2);
session.Save(p);
To avoid those inserts and updates, and have just one INSERT, we can use inverse
mapping. That would be just like this
<class name="Product" table="Product">
...
<set name="NaamTranslations" cascade="all" inverse="true">
but now we have to set both sides of the reference in C#
var p = new Product();
var tr1 = new ProductTranslation();
var tr2 = new ProductTranslation();
p.NaamTranslations.Add(tr1);
p.NaamTranslations.Add(tr2);
// too soon - relation back to product is missing
//session.Save(p);
// assign reference
tr1.Product = p;
tr2.Product = p;
// now cascade will work
session.Save(p);
NHibernate will now: