NHibernate sets Foreign Key in secondary update rather than on initial insert violating Not-Null Constrain on key column

前端 未结 1 1319
青春惊慌失措
青春惊慌失措 2021-01-05 13:12

I am having a problem with what should be a fairly simple (I would think) NHibernate use case.

I have a classic Parent and a Child entity like so:

pu         


        
相关标签:
1条回答
  • 2021-01-05 13:33

    A few problems with your mapping... You have a bidirectional relationship and NHibernate needs to know which way to update it. In the OO world, references only go one way and there is no way for NHibernate to know that Parent->Children is the same FK as Child->Parent. Right now you have Child->Parent set to ReadOnly(). This is telling NHibernate not to update this property. So it tries to insert the Child (with a null parent) and then update the FK from the Parent side. This isn't working if you have a not null constraint on your FK. The usual way to map this is to use Inverse=true on the parent side and let the child worry about persistence. (It's your job in the OO model to ensure that the Parent->Children collection contains the same set of references as the set of Child->Parent relationships.)

    public class ParentMap : ClassMap<Parent>
    {
        public ParentMap()
        {
            Id(x => x.ParentId).GeneratedBy.Native();
            Map(x => x.Name);
            HasMany(x => x.Children).KeyColumn("ParentId").Inverse().Cascade.SaveUpdate();
        }
    }
    
    public class ChildMap : ClassMap<Child>
    {
        public ChildMap()
        {
            Id(x => x.ChildId).GeneratedBy.Native();
            Map(x => x.Name);
            References(x => x.Parent).Column("ParentId").Not.Nullable();  // Removed ReadOnly()
        }
    }
    

    The SQL statements sent to the database when saving are now:

    INSERT INTO [Parent]
               (Name)
    VALUES     ('P1' /* @p0 */)
    select SCOPE_IDENTITY()
    
    INSERT INTO [Child]
               (Name,
                ParentId)
    VALUES     ('C1' /* @p0 */,
                1 /* @p1 */)
    select SCOPE_IDENTITY()
    
    0 讨论(0)
提交回复
热议问题