NHibernate & Temporal relationships enforced by the database - nhibernate

This must be a situation that other people have come across, so I thought I'd ask the question. Have people implemented good generic solutions to the problem of representing temporal relationships within nHibernate. This problem exists within a database over which I have no control, so please don't tell me the DB model is incorrect. I can't change it.
We have a simple Parent:Child relationship, where the child's Valid Time must fall within the parent's Valid Time. Put simply Parent.ValidFrom <= Child.ValidFrom && Parent.ValidTo >= Child.ValidTo. This rule is enforced in the database, meaning I can't issue an UPDATE statement that will cause the records to violate it. That is non negotiable.
Importantly it means that affects the order in which I write changes to the DB.
Expanding the child = 2 UPDATEs.
i. Expand Parent.
ii. Expand Child.
Contracting the parent = 2 UPDATEs.
i. Contract the Child.
ii. Contract the Parent.
Moving parent and child to date in future = 3 UPDATEs.
i. Change Parent ValidTo.
ii. Move Child.
iii. Move Parent.ValidFrom.
Moving parent and child to date in past = 3 UPDATEs.
i. Change Parent ValidFrom.
ii. Move Child.
iii. Move Parent.ValidTo.
So, we can see that the order in which the updates occur is very important. We can't just rely on nHibernate's default updates. Also, in some cases we need to do two UPDATEs on a single entity, where nHibernate would normally do one.
So, I want to get to the point where I can express a generic temporal Parent:Child in my domain model (probably using [attribute] decorated classes), and have some code do the hard work for me.
Has anyone run into this problem, and could anyone give any advice?
Please, again, bear in mind that I have no control over my DB schema and I'd like to write something generic that can be applied to my whole model. The only caveat is that I only care about commiting objects that I have amended in memory. So I'm not expecting to write some code to decide what the correct ValidFrom/ValidTo dates are.

Since you have no control over the order in which NH issues update statements, the best course of action is probably to use IStatelessSession to do the updates "manually".
You essentially give up change tracking; you'll need to tell NH which object to update.

Related

Is it OK to compose an aggregate with immutable data from another aggregate?

If an aggregate needs some read-only data that doesn't belong to itself to performs an operation, is there any negative consequence to let the repository query some data from another aggregate to create the aggregate?
In detail:
I have a BC with two aggregates, say A and B. B needs a bit of data from A to perform some operation but won't modify it in any way. The data fits better on A since there are the rules to modify it.
Reading IDDD and PPP of DDD it seems that it is acceptable to pass a transient reference of an aggregate (or sub entity of it) to another one, or pass a read-only view as a value object to the other aggregate.
In my example, B doesn't need the whole A aggregate but only some specific data, so a value object seems like a good approach in this case. A could create the VO acting as a factory, the VO will conform to the UL and B doesn't need to be aware of A at all. A business use case in the application layer can reconstitute A and B from repositories, tell A to create the VO and performs operation on B passing VO.
Lets suppose now that reconstitution of A is expensive or there is another reason for what is not desirable to load the whole A to create the VO with just a bit of information (maybe the data is not from one instance of A but is aggregated from a list of them or whatever). Here a simple solution could be let the repository of A create the VO directly from the data store. I feel comfortable with this and seems it is a common pattern.
But now I'm thinking in a case when the operation on B is performed many times, or maybe is part of a bigger calculation on B that many other operations need. I could have a reference to the VO with the data needed (as a private, read-only property of B or somewhere in its graph) and let the repository of B take the data needed to create the VO and reconstitute B with it. Now B will always have the data locally to performs its operations. The data taken from A cannot be modified; saving B through its repository will just discard that data (maybe it could use it to detect a conflicting concurrent update), A and B will not be consistent at all times but that's OK, and reload B from repository will query the data again to update the view inside B in case of a conflict.
This approach seems OK to me since, as I understand, the domain model is unrelated to the data model, with the repository acting as a sort of ACL between the two. Also there is a single source of truth for the data inside A since the copy inside B is immutable and eventually consistent. The drawbacks I see are that repository will have more logic (but not business logic) and that it could be unclear where exactly the data is coming from since the dependency from B to A is now hidden inside infrastructural code.
So the questions are:
Is this a not-so-good approach after all?
Is there another drawback I am not seeing?
Did you or someone do something like this so I can learn from that experience?
I know the example is very poor since in DDD everything is about context. But this is a question I came up many times in different situations. I know as well that a valid concern is if aggregate boundaries are well defined, but let say they look good for the problem at hand.
is it acceptable to let the repository query some data from another aggregate to create the aggregate?
Acceptable is kind of weakly defined. A better question to ask might be "are there negative consequences?"
In this example, the usual consideration is whether or not the system becomes harder to change. Take a look at Adam Ralph's talk on service boundaries to get a sense for what happens when you don't control the coupling between components.
These days, if B needs a copy of A's data, then we usually introduce into our design of B a cache of A's data. Store the copy of the data with B, and work out explicitly how and when updates to A are communicated to B. The cache becomes part of B's data model.
See also Pat Helland's paper: Data on the Outside versus Data on the Inside..

nHibernate: determine property value before save

we are currently evaluating whether nHibernate supports the requirements for our project. We share the database with another application so that we are not completely free as regards changes to the schema.
Some columns are filled with unique and consecutive numbers (e.g. for invoices). The next number is determined by a stored procedure that also implements a locking algorithm so that the numbers are guaranteed to be consecutive.
On the one hand we could define a trigger on the respective tables that sets the value for the column when an empty or special value is provided. This would require changing the existing database definition - though it might be the most reliable way to implement this.
In order to avoid the change of the database definition we are trying to solve this in the nHibernate ORM. We've first tried to implement a user type that calls the stored procedure in NullSafeSet if an empty value is provided. Unfortunately, the connection and transaction of the provided command are not set yet when NullSafeSet is called.
How can we solve this with nHibernate?
Thanks in advance,
Markus
If you decide to go with trigger route, then you'll need to add generated attribute to your property mapping.
Generated properties are properties which have their values generated
by the database. Typically, NHibernate applications needed to Refresh
objects which contain any properties for which the database was
generating values. Marking properties as generated, however, lets the
application delegate this responsibility to NHibernate. Essentially,
whenever NHibernate issues an SQL INSERT or UPDATE for an entity which
has defined generated properties, it immediately issues a select
afterwards to retrieve the generated values.
Aside from that, I'm not quite sure how would you call stored procedure from NHibernate issued INSERT, without adding a trigger or default constraint on column.
Edit
Looks like NHibernate has a notion of class persisters, through the interface IEntityPersister. Maybe you could hack something out from that.
The persister attribute lets you customize the persistence strategy
used for the class. You may, for example, specify your own subclass of
NHibernate.Persister.EntityPersister or you might even provide a
completely new implementation of the interface
NHibernate.Persister.IClassPersister that implements persistence via,
for example, stored procedure calls, serialization to flat files or
LDAP. See NHibernate.DomainModel.CustomPersister for a simple example
(of "persistence" to a Hashtable).
You could start from NHibernate's source.
If you have the ability to add triggers to database, that would probably be the best, straightforward way, without investing too much time to fight with NHibernate's internals.

NHibernate: removing from collection vs association and cascading styles

I'm having trouble understanding how NHibernate knows anything about objects removed from association (and then execute cascading style like delete-orphant). I mean, at a database level if I wanted to remove an association I'd have to physically log on and remove some FK. How does this happen in NH world? Do I remap my classes, remove previously established parent/child association (relationship), NH does comparative analysis, digs that something has been changed and then takes appropriate action? In this post Ayende talks about different cascading styles and delete-orphat is described as "... In addition to that, when an object is removed from the assoication and not assoicated with another object (orphaned), also delete it ..." How does this removal happen?
NHibernate watches all the mapped collections mapped that are owned by objects in the NHibernate session. As you make changes (adding/removing) NHibernate marks them as dirty. When it is time to flush the changes it compares the elements in the dirty collections and is able to identify what items have been added and removed. Depending on the cascade options for the collection NHibernate might then persist those changes to the database.
This is why you should always declare collection properties using interfaces (IList, ISet, etc.) and never replace a collection property on an object that has been loaded using NHibernate.
Additional info requested in comments:
There is a useful discussion by Fabio Maulo (NHibernate lead developer) of collection mapping here which I would strongly recommend to read. But to try and provide a brief answer to your questions:
But how does NH know that association between objects has been removed?
Generally when working in the OO model with many associations we manage relationships at the parent. That is, a child is considered to be associated with the parent when it is in a parent's collection. E.g.
child.Parent = parent;
parent.Children.Add(child); // This is the critical bit
session.Save(parent); // to have an INSERT generated here
Similarly removing an item from a collection breaks the association (assuming correct mapping attributes have used)
child.Parent = null;
parent.Children.Remove(child); // This is critical bit
session.Save(parent); // To have DELETE or UPDATE statement generated depending on cascade settings.
This is the opposite of how things work in the relational world where we manage the relationship at the child via the foreign key on the child row.
For a more detailed understanding there is nothing like downloading the NHibernate source code, creating a simple test case and then stepping through in the debugger.
What's the reason behind the "This is why..."
There are a number of things NHibernate takes care of in managing in association collections. It does this by using its own collection classes that keep track of whether they are dirty, what state they were in when they were loaded from the db and a number of other cool things. If you replace those objects then NHibernate loses that capability. So, for instance if you want to get rid of all the items in a collection you should do:
parent.Children.Clear(); // The collection object is preserved and NHibernate knows you want them all deleted.
You should NEVER do:
parent.Children = new List<X>(); // NHibernate will not track changes to this collection.
For further reading you might also want to take a look at this.

Core Data: force one attribute to load before others

I have some transient attributes in my Entity that are derived from one other transient attribute (call is X). When I do a fetch, it seems to try to load all attributes in no particular order, so if X is taking some time to calculate, the other derived attributes try to use X and it's null so it causes issues.
Is there any way to force Core Data to ensure loading one attribute before other attributes can read from it? Or force the other attributes to reload once attribute X has done loading? Any other technique anyone would recommend? I'm using this in an iOS tableView backed by an NSFetchedResultsController.
No you can't force attributes to "load" in order because attributes don't load. You are initializing objects here and not reading cells in a procedural database.
I'm going to guess that your trying to calculate some value based on the attributes or counts of external objects. If so, then you can get serious slow downs while the other objects are faulted in so that their values can be accessed.
If so, then you've got a data model design problem. I've never seen a transient value so complex that its calculation impaired operation. You probably need to break it apart or even move it to its own object.
E.g Suppose you've got a data model that simulates a group of people with Person objects. You want some behavior of each Person object to change depending on how many people their are. So, when there are less than five each person does "X" if there are 6 to 10 you do "Y" and so on.
In that circumstance, it would be best to create a second entity related to all the Person objects that tracks the number of Person objects total. Then getting the count of all Person objects or the collective sum of one of the Person entity attributes becomes fast and trivial.

DDD: Should everything fit into either Entity or Value Object?

I'm trying to follow DDD, or a least my limited understanding of it.
I'm having trouble fitting a few things into the DDD boxes though.
An example: I have a User Entity. This user Entity has a reference to a UserPreferencesInfo object - this is just a class which contains a bunch of properties regarding user preferences. These properties are fairly unrelated, other than the fact that they are all user preferences (unlike say an Address VO, where all the properties form a meaningful whole).
Question is - what is this UserPreferencesInfo object?
1) Obviously it's not an Entity (I'm just storing it as 'component' in fluent nhibernate speak (i.e. in the same DB table as the User entity).
2) VO? I understand that Value Object are supposed to be Immutable (so you cant cange them, just new them up). This makes complete sense when the object is an address for instance (the address properties form a meaningful 'whole'). But in the case of UserPreferencesInfo I don't think it makes sense. There could be 100 properties (Realistically) There could be maybe 20 properties on this object - why would I want to discard an recreate the object whenever I needed to change one property?
I feel like I need to break the rules here to get what I need, but I don't really like the idea of that (it's a slippery slope!). Am I missing something here?
Thanks
Answer 1 (the practical one)
I'm a huge proponent of DDD, but don't force it. You've already recognised that immutable VOs add more work than is required. DDD is designed to harness complexity, but in this case there is very little complexity to manage.
I would simply treat UserPreferencesInfo as an Entity, and reference it from the User aggregate. Whether you store it as a Component or in a separate table is your choice.
IMHO, the whole Entity vs VO debate can be rendered moot. It's highly unlikely that in 6 months time, another developer will look at your code and say "WTF! He's not using immutable VOs! What the heck was he thinking!!".
Answer 2 (the DDD purist)
Is UserPreferencesInfo actually part of the business domain? Others have mentioned disecting this object. But if you stick to pure DDD, you might need to determine which preferences belong to which Bounded Context.
This in turn could lead to adding Service Layers, and before you know it, you've over-engineered the solution for a very simple problem...
Here's my two cents. Short answer: UserPreferenceInfo is a value object because it describes the characteristics of an object. It's not an entity because there's no need to track an object instance over time.
Longer answer: an object with 100+ properties which are not related is not very DDD-ish. Try to group related properties together to form new VOs or you might discover new entities as well.
Another DDD smell is to have a lot of set properties in the first place. Try to find the essence of the action instead of only setting the value. Example:
// not ddd
employee.Salary = newSalary;
// more ddd
employee.GiveRaise(newSalary);
On the other hand you may very well have legitimate reasons to have a bunch of properties that are no more than getters and setters. But then there's probably simpler methods than DDD to solve the problem. There's nothing wrong with taking the best patterns and ideas from DDD but relax a little of all the "rules", especially for simpler domains.
I'd say a UserPreferenceInfo is actually a part of the User aggregate root. It should be the responsibility of the UserRepository to persist the User Aggregate Root.
Value objects only need to be newed up (in your object model) when their values are shared. A sample scenario for that would be if you check for a similar UserPreferenceInfo and associate the User with that instead of Inserting a new one everytime. Sharing Value Objects make sense if value object tables would get to large and raise speed/storage concerns. The price for sharing is paid on Insert.
It is reasonable to abstract this procedure in the DAL.
If you are not shraing value objects, there is nothing against updating.
As far as I understand, UserPreferenceInfo is a part of User entity. Ergo User entity is an Aggregate root which is retrieved or saved using UserRepository as a whole, along with UserPreferenceInfo and other objects.
Personally, I think that UserPreferenceInfo is entity type, since it has identity - it can be changed, saved and retrieved from repository and still be regarded as the same object (i.e. has identity). But it depends on your usage of it.
It doesn't matter IMHO how object is represented in the DAL - is it stored in a separate table or part of other table. One of the benefits of DDD is persistence ignorance and is ususally a good thing.
Of course, I may be wrong, I am new to DDD too.
Question is - what is this UserPreferencesInfo object?
I don't know how this case is supported by NHibernate, but some ORMs support special concepts for them. For example DataObjects.Net include Structures concept. It seems that you need something like this in NH.
First time ever posting on a blog. Hope I do it right.
Anyway, since you haven't showed us the UserPreferencesInfo object, I am not sure how it's constructed such that you can have a variable number of things in it.
If it were me, I'd make a single class called UserPreference, with id, userid, key, value, displaytype, and whatever other fields you may need in it. This is an entity. it has an id and is tied to a certain user.
Then in your user entity (the root I am assuming), have an ISet.
100 properties sounds like a lot.
Try breaking UserPreferenceInfo up into smaller (more cohesive) types, which likely/hopefully are manageable as VOs.