Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component That References Another Entity Can Cause Foreign Key Exception #1616

Open
rmabraham opened this issue Mar 15, 2018 · 1 comment
Open

Comments

@rmabraham
Copy link

After updating to Nhibernate 5.0 from Nhibernate 3.1.0.4 and Fluent Nhibernate 2.1.0 from Fluent Nhibernate 1.2.0.712 the following issue started occurring.

I have an object Container which contains a list of Parents. Parents contains a COMPONENT object with a reference to another StringObject object.
There are the following tables:

Container
Parent - Contains the Component as well.
StringObject
If I create a Container with two parents and the first parent has a Component and the second doesn't everything works. But If the first has not component and the second doesn't I get a foreign key exception.

Nhibernate doesn't work properly with components. If it isn't a component but a regular domain mapped class to it's own table everything works.

@rmabraham
Copy link
Author

Here is Console APP that shows the issue:


using System;
using System.Collections.Generic;
using FluentNHibernate.Mapping;
using NHibernate;
using NHibernate.Tool.hbm2ddl;

namespace NhibernateReplicateForeignKeyBug
{
    class Program
    {
        private static string connectionString = string.Empty; //PUT YOUR CONNECTIONSTRING

        static void Main(string[] args)
        {
            ISessionFactory sessionFactory = CreateTables();
            var session = sessionFactory.OpenSession();

            using (ITransaction transaction = session.BeginTransaction())
            {
                try
                {
                    var EmptyParent = new Parent();
                    var ParentWithComponentWithObjectRef = new Parent
                    {
                        ComponentWithObjectRef = new ComponentWithObjectRef
                        {
                            StringObjectRef = new StringObject
                            {
                                Name = "TestName"
                            }
                        }
                    };
                    Container containerThatBreaks = new Container
                    {
                        Parents = new List<Parent> { EmptyParent, ParentWithComponentWithObjectRef}
                    };
                    Container containerThatWorks = new Container
                    {
                        Parents = new List<Parent> { ParentWithComponentWithObjectRef, EmptyParent}
                    };
                    session.Save(containerThatBreaks);
                    transaction.Commit();
                    Console.Out.WriteLine("Works!");
                }
                catch(Exception e)
                {
                    transaction.Rollback();
                    Console.Out.WriteLine("BROKEN!");
                    Console.Out.WriteLine(e);
                }
                Console.ReadLine();
            }
        }
        public static ISessionFactory CreateTables()
        {
            ISessionFactory sessionFactory;
            sessionFactory = FluentNHibernate.Cfg.Fluently.Configure()
                .Database(
                    FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2008
                        .ConnectionString(connectionString)
                )
                .Mappings(m =>
                {
                    m.FluentMappings.AddFromAssemblyOf<ParentMap>();
                })
                .ExposeConfiguration(cfg => new SchemaExport(cfg).Create(true, true))
                .BuildSessionFactory();
            return sessionFactory;

        }
    }

    #region Domain

    public class Container
    {
        public virtual Guid Id { get; set; }

        public virtual IList<Parent> Parents { get; set; }
    }

    public class Parent
    {
        public virtual Guid Id { get; set; }

        public virtual ComponentWithObjectRef ComponentWithObjectRef { get; set; }

    }


    public class ComponentWithObjectRef
    {
        public virtual StringObject StringObjectRef { get; set; }
    }

    public class StringObject
    {
        public virtual Guid Id { get; set; }
        public virtual string Name { get; set; }
    }


    #endregion

    #region Mappings

    public class ContainerMap : ClassMap<Container>
    {
        public ContainerMap()
        {
            Id(x => x.Id);
            HasMany(x => x.Parents)
                .Cascade.All();
        }
    }

    public class ParentMap : ClassMap<Parent>
    {
        public ParentMap()
        {
            Id(x => x.Id);
            Component(x => x.ComponentWithObjectRef, c =>
            {
                c.References(y => y.StringObjectRef)
                    .ForeignKey()
                    .Cascade.All();
            });
        }
    }

    public class StringObjectMap : ClassMap<StringObject>
    {
        public StringObjectMap()
        {
            Id(x => x.Id);
            Map(x => x.Name);
          
         //   ComponentWithObjectRef(x => x.ComponentWithObjectRef, c =>
         //   {
         //       c.References(y => y.StringObjectRef)
         //           .ForeignKey()
         //           .Cascade.All();
         //   });
        }
    }

    #endregion
}

`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant