Hello,

I have a simple relational schema with two tables :
[code]
mysql> describe customers;
+-------+---------+------+-----+---------+----------------+
| Field | Type    | Null | Key | Default | Extra          |
+-------+---------+------+-----+---------+----------------+
| id    | int(11) | NO   | PRI | NULL    | auto_increment |
| name  | text    | YES  |     | NULL    |                |
+-------+---------+------+-----+---------+----------------+
2 rows in set (0.03 sec)

mysql> describe invoices;
+-------------+---------------+------+-----+---------+----------------
+
| Field       | Type          | Null | Key | Default | Extra
|
+-------------+---------------+------+-----+---------+----------------
+
| id          | int(11)       | NO   | PRI | NULL    | auto_increment
|
| date        | datetime      | YES  |     | NULL    |
|
| amount      | decimal(10,0) | YES  |     | NULL    |
|
| customer_id | int(11)       | NO   | MUL | NULL    |
|
+-------------+---------------+------+-----+---------+----------------
+
4 rows in set (0.02 sec)
[/code]

And a simple object model :
[code]
using System;
using System.Collections.Generic;

namespace CRM
{
        public class Customer
        {
                public virtual int Id
                {
                        get;
                        set;
                }

                public virtual string Name
                {
                        get;
                        set;
                }

                public virtual IList<Invoice> Invoices
                {
                        get;
                        set;
                }
        }

        public class Invoice
        {
                public virtual int Id
                {
                        get;
                        set;
                }

                public virtual DateTime Date
                {
                        get;
                        set;
                }

                public virtual decimal Amount
                {
                        get;
                        set;
                }
        }
}
[/code]

I'd like to create a one-to-many relationship between "Customer" and
"Invoice" to be able to navigate by using the "Customer.Invoices"
property.

So I've tried the following mapping :
[code]
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping      xmlns="urn:nhibernate-mapping-2.2"
                                        assembly="Business"
                                        namespace="CRM">
        <class name="Customer" table="customers">
                <id name="Id" column="id">
                        <generator class="native" />
                </id>
                <property name="Name" column="name" />

                <bag name="Invoices" cascade="all">
                        <key column="customer_id" />
                        <one-to-many class="Invoice" />
                </bag>
        </class>
        <class name="Invoice" table="invoices">
                <id name="Id" column="id">
                        <generator class="native" />
                </id>
                <property name="Date" column="date" />
                <property name="Amount" column="amount" />
        </class>
</hibernate-mapping>
[/code]

But this code :
[code]
using System; // Console
using System.Collections.Generic; // IList&lt;>, Dictionary&lt;,>
using System.Linq; // ToList()

using NHibernate; // ISessionFactory, ISession, ITransaction
using NHibernate.Criterion;
using NHibernate.Cfg; // Configuration

using CRM; // Customer, Invoice


namespace TestNHibernate
{
    class Program
    {
        static void Main(string[] args)
        {
                        try
                        {
            Configuration configuration = new Configuration();

                        configuration.AddProperties
                        (
                                new Dictionary<string, string>
                                {
                                        { "dialect", 
"NHibernate.Dialect.MySQLDialect" }
                                }
                        );

                        configuration.AddFile("CRM.hbm.xml");

                        configuration.Configure();

            ISessionFactory sessionFactory =
configuration.BuildSessionFactory();

            ISession session = sessionFactory.OpenSession();

            ITransaction transaction = session.BeginTransaction();

                        Customer John = new Customer { Name="John" };

                        Invoice invoice1 = new Invoice
                        {
                                Date = DateTime.Now.AddDays(-1),
                                Amount = 100
                        };
                        Invoice invoice2 = new Invoice
                        {
                                Date = DateTime.Now,
                                Amount = 200
                        };

                        John.Invoices = new List<Invoice>{invoice1, invoice2};

                        session.Save(John);

            transaction.Commit();

            transaction.Dispose();

                        session.Dispose();

                        sessionFactory.Dispose();
                        }
                        catch(Exception e)
                        {
                                Console.WriteLine(e);
                        }
        }
    }
}
[/code]

fails with the following exception :
[code]
NHibernate.Exceptions.GenericADOException: could not insert:
[CRM.Invoice][SQL:
INSERT INTO invoices (date, amount) VALUES (?, ?)] --->
MySql.Data.MySqlClient.M
ySqlException: Field 'customer_id' doesn't have a default value
[/code]

So apparently NHibernate ignores the one-to-many relationship and
tries to persist the invoices before the customer, which fails because
the "customer_id" field has no default value, and particularly cannot
be null.

Of course when I remove the "not null" constraint on the foreign key
"customer_id" all is working fine because NHibernate :
- persists the invoices assigning them a null "customer_id",
- persists the customer and assign the right "customer_id" to the
invoices
or something like that.
But I can't change the legacy relational model.


1) Does it exist, in the mapping file, a way to make NHibernate taking
into account the relationship when persisting a Customer ?
2) If not is there a programmatic way of doing so ?

Thanks in advance.

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to