DDD, how to persist deletes on child entities with NHibernate?

nhibernate saveorupdate
nhibernate flush
nhibernate saveorupdate not updating
nhibernate documentation
nhibernate-mapping c#
nhibernate delete by id
nhibernate persistent class
nhibernate override session

Having an AggregateRoot and a list of child Entities, how do you persist the updated list of children after removing or updating one of them ?

This is an application layer service

  async Task HandleAsync(RemoveChildRequest request)
        {
            Aggregate aggregate = await _aggregateRepository.GetByIdAsync(request.AggregateId);

            aggregate.RemoveChild(request.ChildId);

            await _aggregateRepository.Update(aggregate);

            await _unitOfWork.CommitAsync();
        }

This is the Aggregate method of removing a child.

    public virtual void RemoveChild(Guid ChildId)
    {
        Child kid = _children.Single(item => item.Id == ChildId);

        _children.Remove(kid);
    }

And this is the repository The aggregate is as it should be, has same data but without the child it was removed from the collection.

Update(Aggregate aggregate)
{
      await Session.UpdateAsync(aggregate, aggregate.Id);
}

This is my NHibernate configuration

  mapping
      .HasMany<Children>(Reveal.Member<Aggregate>("Children"))
      .Not.Inverse()
      .Not.KeyNullable()
      .Not.KeyUpdate()
      .Cascade.Delete();

After the commit is done, there is no update done against the DB. Somehow i feel is normal because, I only remove an entry from the children collection and that's all.

The structure

Aggregate 
{
   private virtual IList<Child> _children;
   protected virtual List<Child> Children { get => _children; }
}

Child 
{

}

So only the parent holds a reference to the Child

I could do something like this in the Aggregate Repository

RemoveChild(Child kid) 
{
     Session.DeleteAsync(kid);
}

But as far as I know, Repositories should be Aggregates specific only.

I'm interested in how the code that will actually persist the changes to the data store looks like? How do you remove the child. The Repository.


Found my answer Here

nhibernate mapping: A collection with cascade="all-delete-orphan" was no longer referenced

and here

property Access strategies in nhibernate

NHibernate configuration

    mapping
        .HasMany<Child>(Reveal.Member<Order>("Children"))
        .Access.LowerCaseField(Prefix.Underscore)
        .Cascade.AllDeleteOrphan()
        .Not.KeyNullable()
        .Not.KeyUpdate();

DDD, how to persist deletes on child entities with NHibernate?, I'm interested in how the code that will actually persist the changes to the data store looks like? How do you remove the child. The Repository. nhibernate  DDD, how to persist deletes on child entities with NHibernate? 0


Here is the way it is done with ByCode mapping, important is colmap.Cascade(Cascade.All). I hope this helps.

public class Client
{
    public virtual int ClientId { get; protected set; }
    public virtual string ClientName { get; protected set; }
    public virtual IList<ClientLocation> ClientLocations { get; protected set; }

    protected Client()
    {
        this.ClientLocations = new List<ClientLocation>();
    }
}

public class ClientLocation
{
    public virtual int ClientLocationId { get; protected set; }
    public virtual Client Client { get; protected set; }
    public virtual string LocationName { get; protected set; }

    protected ClientBranch()
    {
    }
}

Mappings

public class ClientMap : ClassMapping<Client>
{        
    public ClientMap() {
    Lazy(true);

        Id(x => x.ClientId, map => map.Generator(Generators.Identity));
    Property(x => x.ClientName);

        Bag(x => x.ClientLocations, colmap => { colmap.Key(x => x.Column("CLIENTID")); colmap.Cascade(Cascade.All); }, map => { map.OneToMany(); });
    }
}


public class ClientLocationMap : ClassMapping<ClientLocation>
{
    public ClientLocationMap()
    {
    Lazy(true);

        Id(x => x.ClientLocationId, map => map.Generator(Generators.Identity));
    Property(x => x.LocationName);

        ManyToOne(x => x.Client, map => { map.Column("CLIENTID"); map.NotNullable(true); map.Cascade(Cascade.All); });
    }
}

Chapter 10. Manipulating Persistent Data, An object (entity instance) is either transient or persistent with respect to a particular ISession. If a parent is deleted, all children are passed to Delete(). When you activate it on the association, Hibernate removes a child entity when you remove its association to the parent entity. Let’s take a look at an example. In most online book stores, customers can review the offered books. You can model that with a Book and a Review entity and a one-to-many association between them.


If the children belong to the aggregate root (i.e. composition instead of association), the removal or addition of the child entity must happen through the AggregateRoot and not independently. Moreover, children should be Value Objects and not aggregates in their own right.

Therefore, you are right - the Repository would only fetch the parent. You would then have RemoveChild command that would act on that instance and post a ChildRemoved event which would take the child away from the list.

Relational Persistence for Idiomatic .NET, must be explicitly saved and deleted (except that saves and deletions may be cascaded from a parent entity to its children). You can tell Hibernate, and any other JPA implementation, to cascade certain operations you perform on an entity to its associated child entities. The only thing you have to do is to define the kind of operation you want to cascade to the child entities. The following code snippet shows an example in which I cascade the persist operation of the


Entity Framework 6 (7) vs NHibernate 4: a DDD perspective, Persistence ignorance is a prerequisite for isolating domain logic. Example 1: Deleting a child entity from an aggregate root. Let's look at code samples from real  ISession.Delete() will remove an object's state from the database. Of course, your application might still hold a reference to it. So it's best to think of Delete() as making a persistent instance transient. sess.Delete(cat); You may also delete many objects at once by passing a NHibernate query string to Delete().


EF Core 2.1 vs NHibernate 5.1: DDD perspective · Enterprise , Separation of concerns (also known as Persistence Ignorance and If the root entity has any children that are detached from the context, you are The score of #4: Deleting orphaned entities is: EF Core vs NHibernate - 1 : 1. One of the first things that new users want to do with NHibernate is to model a parent/child type relationship. There are two different approaches to this. The most convenient approach, especially for new users, is to model both Parent and Child as entity classes with a <one-to-many> association from Parent to Child.


Hierarchy of value objects · Enterprise Craftsmanship, The ubiquitous virtual keywords is due to the use of NHibernate. Meaning that if you delete the parent entity, the child one gets deleted with it. of differences, the best way to store value objects in the database is to include them into the parent's table. EF Core 2.1 vs NHibernate 5.1: DDD perspective At any rate, you are able to tell NHibernate to automatically traverse an entity's associations, and act according to the cascade option. For instance, adding an unsaved entity to a collection with save-update cascade will cause it to be saved along with its parent object, without any need for explicit instructions on our side.