Nhibernate: One-To-Many mapping problem - Cannot cascade delete without inverse. Set NULL error

Posted by KnaveT on Stack Overflow See other posts from Stack Overflow or by KnaveT
Published on 2010-04-29T02:59:34Z Indexed on 2010/04/29 3:07 UTC
Read the original article Hit count: 586

Hi,

I have the current scenario whereby an Article has only 1 Outcome each. Each Article may or may not have an Outcome.

In theory, this is a one-to-one mapping, but since NHibernate does not really support one-to-one, I used a One-To-Many to substitute. My Primary Key on the child table is actually the ArticleID (FK).

So I have the following setup:

Classes

public class Article
{
    public virtual Int32 ID { get;set;}
    private ICollection<ArticleOutcome> _Outcomes {get;set;}

    public virtual ArticleOutcome Outcome
    {
        get {
            if( this._Outcomes !=null && this._Outcomes.Count > 0 )
                return this._Outcomes.First();
            return null;
        }
        set {
            if( value == null ) {
                if( this._Outcomes !=null && this._Outcomes.Count > 0 )
                    this._Outcomes.Clear();
            }
            else {
                if( this._Outcomes == null )
                    this._Outcomes = new HashSet<ArticleOutcome>();
                else if ( this._Outcomes.Count >= 1 )
                    this._Outcomes.Clear();
                this._Outcomes.Add( value );
            }
        }
    }
}

public class ArticleOutcome
{
    public virtual Int32 ID { get;set; }
    public virtual Article ParentArticle { get;set;}
}

Mappings

public class ArticleMap : ClassMap<Article> 
{
    public ArticleMap() {
        this.Id( x=> x.ID ).GeneratedBy.Identity();

        this.HasMany<ArticleOutcome>( Reveal.Property<Article>("_Outcomes") )
            .AsSet().KeyColumn("ArticleID")
            .Cascade.AllDeleteOrphan() //Cascade.All() doesn't work too.
            .LazyLoad()
            .Fetch.Select();
    }
}

public class ArticleOutcomeMap : ClassMap<ArticleOutcome>
{
    public ArticleOutcomeMap(){
       this.Id( x=> x.ID, "ArticleID").GeneratedBy.Foreign("ParentArticle");

       this.HasOne( x=> x.ParentArticle ).Constrained ();

       //This do not work also.
       //this.References( x=> x.ParentArticle, "ArticleID" ).Not.Nullable(); 
    }
}

Now my problem is this:

It works when I do an insert/update of the Outcome. e.g.

var article = new Article();
article.Outcome = new ArticleOutcome { xxx = "something" };
session.Save( article );

However, I encounter SQL errors when attempting to delete via the Article itself.

var article = session.Get( 123 );
session.Delete( article ); //throws SQL error.

The error is something to the like of Cannot insert NULL into ArticleID in ArticleOutcome table.

The deletion works if I place Inverse() to the Article's HasMany() mapping, but insertion will fail.

Does anyone have a solution for this? Or do I really have to add a surrogate key to the ArticleOutcome table?

© Stack Overflow or respective owner

Related posts about nhibernate

Related posts about fluent-nhibernate