Reputation: 14897
I'm getting the following exceptions and I'm pretty sure it has something to do with the one-to-many relationship between category and product. What's wrong?
Nhibernate.Exceptions.GenericADOException {"could not execute batch command.[SQL: SQL not available]"}
InnerException: {"The INSERT statement conflicted with the FOREIGN KEY constraint \"FK1F94D86A1B57B09E\". The conflict occurred in database \"SimpleNhibernate\", table \"dbo.Category\", column 'Id'.\r\nThe statement has been terminated."}
Program.cs
class Program
{
private static ISessionFactory _sessionFactory;
private static Configuration _configuration;
static void Main(string[] args)
{
_configuration = new Configuration();
_configuration.Configure();
_configuration.AddAssembly(typeof(Product).Assembly);
_sessionFactory = _configuration.BuildSessionFactory();
var schema = new SchemaExport(_configuration);
schema.Drop(true, true);
schema.Create(true, true);
AddCategory(new Category("Phone"));
AddCategory(new Category("Smart Phone"));
using (ISession session = NHibernateHelper.OpenSession())
{
var categories = session.QueryOver<Category>().List();
foreach (var category in categories)
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Save(new Product("iPhone", category));
transaction.Commit();
}
}
}
}
private static void AddCategory(Category product)
{
using (ISession session = NHibernateHelper.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
session.Save(product);
transaction.Commit();
}
}
}
Category.cs
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Iesi.Collections.Generic;
namespace SimpleNhibernate
{
public class Category
{
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
public virtual ISet<Product> Products { get; set; }
public virtual bool Discontinued { get; set; }
public Category() { }
public Category(string name)
{
Name = name;
}
}
}
Category.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="SimpleNhibernate"
namespace="SimpleNhibernate">
<class name="Category">
<id name="Id">
<generator class="guid" />
</id>
<property name="Name" />
<set name="Products" inverse="true" >
<key column="Id" />
<one-to-many class="Product"/>
</set>
<property name="Discontinued" />
</class>
</hibernate-mapping>
Product.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="SimpleNhibernate"
namespace="SimpleNhibernate">
<class name="Product">
<id name="Id">
<generator class="guid" />
</id>
<property name="Name" />
<many-to-one name="Category" column="CategoryID"></many-to-one>
<property name="Discontinued" />
</class>
</hibernate-mapping>
Product.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SimpleNhibernate
{
public class Product
{
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
public virtual Category Category { get; set; }
public virtual bool Discontinued { get; set; }
public Product() { }
public Product(string name, Category category)
{
Name = name;
Category = category;
}
}
}
Upvotes: 1
Views: 991
Reputation: 123861
The column responsible for a mapping (both directions) is CategoryID
in Product table
So the set
should have the key as this
<class name="Category">
...
<set name="Products" inverse="true" >
<key column="CategoryID" /> // instead of Id
to be the same as in Product mapping
<many-to-one name="Category" column="CategoryID"></many-to-one>
Upvotes: 2