实体在创建后不会持久化

Entities are not persisted after creation

免责声明:这是我使用 NHibernate 的第一个项目,我可能会遗漏一些东西 "obvious"。

我的问题如下。我有一个创建订单的命令:

public void Handle(BuyOneProductCommand command)
{
    var product = _uow.Query<Product>().Single(p => p.Name == command.ProductName);
    var order = new Order(product, 1);
    _uow.SaveOrUpdate(order);
    _uow.Commit();
}

命令接收新创建的 UnitOfWork。但是在 Commit() 之后,我的更改永远不会保存到数据库中,也不会抛出任何异常。有什么想法吗?

订单

public class Order : AggregateRoot
{
    public virtual Product Product { get; }
    public virtual int Quantity { get; }
    public virtual DateTime Date { get; }

    public Order(Product product, int quantity) : this()
    {
        Product = product;
        Quantity = quantity;
        Date = DateTime.Now;
        AddDomainEvent(new OrderCreatedEvent(this));
    }

    protected Order() { }
}

订单图

public class OrderMap : ClassMap<Order>
{
    public OrderMap()
    {
        Id(x => x.Id);
        References(o => o.Product);
        Map(x => x.Quantity);
        Map(x => x.Date);
    }
}

工作单位

public sealed class UnitOfWork : IUnitOfWork
{
    private readonly ISession _session;
    private readonly ITransaction _transaction;
    private bool _isAlive = true;

    public UnitOfWork()
    {
        _session = SessionFactory.OpenSession();
        _transaction = _session.BeginTransaction(IsolationLevel.ReadCommitted);
    }

    public void Commit()
    {
        if (!_isAlive)
            return;

        try
        {
            _transaction.Commit();
        }
        finally
        {
            _isAlive = false;
            _transaction.Dispose();
            _session.Dispose();
        }
    }

    public T Get<T>(long id) where T : class
    {
        return _session.Get<T>(id);
    }

    public void SaveOrUpdate<T>(T entity)
    {
        _session.SaveOrUpdate(entity);
    }

    public IQueryable<T> Query<T>()
    {
        return _session.Query<T>();
    }
}

会话工厂

public static class SessionFactory
{
    private static ISessionFactory _factory;

    public static void Init(string connectionString)
    {
        _factory = BuildSessionFactory(connectionString);
    }

    public static ISession OpenSession()
    {
        return _factory.OpenSession();
    }

    private static ISessionFactory BuildSessionFactory(string connectionString)
    {
        return Fluently.Configure()
            .Database(SQLiteConfiguration.Standard.ConnectionString(connectionString).ShowSql())
            .Mappings(m => m.FluentMappings
                .AddFromAssembly(Assembly.GetExecutingAssembly())
                .Conventions.Add(
                    ForeignKey.EndsWith("Id"),
                    ConventionBuilder.Property.When(criteria => criteria.Expect(x => x.Nullable, Is.Not.Set), x => x.Not.Nullable()))
                .Conventions.Add<OtherConventions>()
                .Conventions.Add<IncrementConvention>()
            )
            .ExposeConfiguration(x =>
            {
                x.EventListeners.PreUpdateEventListeners = new IPreUpdateEventListener[] { new DomainEventsListener() };
                x.EventListeners.PreInsertEventListeners = new IPreInsertEventListener[] { new DomainEventsListener() };
                x.EventListeners.PreDeleteEventListeners = new IPreDeleteEventListener[] { new DomainEventsListener() };
                x.EventListeners.PreCollectionUpdateEventListeners = new IPreCollectionUpdateEventListener[] { new DomainEventsListener() };
                x.EventListeners.PostCommitUpdateEventListeners = new IPostUpdateEventListener[] { new IntegrationEventsListener() };
                x.EventListeners.PostCommitInsertEventListeners = new IPostInsertEventListener[] { new IntegrationEventsListener() };
                x.EventListeners.PostCommitDeleteEventListeners = new IPostDeleteEventListener[] { new IntegrationEventsListener() };
                x.EventListeners.PostCollectionUpdateEventListeners = new IPostCollectionUpdateEventListener[] { new IntegrationEventsListener() };
                new SchemaUpdate(x).Execute(true, true);
            })
            .BuildSessionFactory();
    }

    private class OtherConventions : IHasManyConvention, IReferenceConvention
    {
        public void Apply(IOneToManyCollectionInstance instance)
        {
            instance.LazyLoad();
            instance.AsBag();
            instance.Cascade.SaveUpdate();
            instance.Inverse();
        }

        public void Apply(IManyToOneInstance instance)
        {
            instance.LazyLoad(Laziness.Proxy);
            instance.Cascade.None();
            instance.Not.Nullable();
        }
    }

    private class IncrementConvention : IIdConvention
    {
        public void Apply(IIdentityInstance instance)
        {
            instance.Column("Id");
            instance.GeneratedBy.Increment();
        }
    }
}

IPreInsertEventListener

public bool OnPreInsert(PreInsertEvent @event)
{
    var aggregateRoot = @event.Entity as AggregateRoot;
    if (aggregateRoot == null)
        return true;

    foreach (IEvent domainEvent in aggregateRoot.DomainEvents)
    {
        DomainEvents.Dispatch(domainEvent);
    }

    aggregateRoot.ClearDomainEvents();

    return true;
}

正如 Roman Artiukhin 指出的那样,我的 IPreInsertEventListener 总是通过 returning true.

不断否决插入内容

棘手的是,我 认为 此侦听器中的 return 值表示 success/failure 而它是为了表示否决权

因此我不得不改为总是return false,意思是无否决权