NHibernate Architecture and Business Logic - nhibernate

Just started developing a project using NHibernate and Fluent NHibernate for the mapping and I'm confused. Since the project is going to get more complex over the next months I would like to structure the code into logical layers such as Persistence Layer and Business Logic layer.
I have a business object called Patient that contains logic and validation.
Should Patient class be mapped with the Fluent NHibernate mapping class?
Or should the mapping class map to some Data Access Object, such as PatientDAO and Patient class somehow use PatientDAO?
If 1, isn't my Business logic layer and persistence layer the same?
If 2, having the two layer is separate projects, should I the BL project contain the Patient object and some IPatientDAO and the PL have the PatientDAO object?
Or am I doing it all wrong? :-)

You should map your entities using Fluent NHibernate, since that is where you map to/from your database structure to your object model.
As for DAO, this is a matter of personal taste. Generally folks like to use a DAO of some sort (even though folks like to call them Repositories these days). These classes will utilize the NHibernate ISession to read/write the data to and from the database. Generally the current means of working with these is to define a generic interface with Get<T>(int id), GetAll<T>(), 'Delete()type methods defined to handle CRUD ops, withT` being the entity type.
It is, however, also possible to use the ISession directly in your presentation code, since it is already providing an abstraction for reading/writing data. If you go this route then you are exposing NHibernate to the rest of your app, but your also removing one level of abstraction.
As for which layer is which, NHibernate is 95%-100% of your persistence layer. You can add some abstractions of your own on top of it to create an API that makes you happy, but that is totally up to you.

Related

Mapping Entity Framework auto generated entities to Data Transfer Objects?

Using Entity Framework 4.1 what is the best way to map an auto generated entity framework entity to an object suitable for Data Transfer?
What i'm working with looks like this:
WPF Application -> WCF Service -> Entity Framework (DAL) -> Database
The WPF application could be swapped out to an ASP.NET website at some point in addition to the WPF Application. Hence the use of a WCF service.
The WCF Service, Database and Entity Framework code will all sit on the same physical tier.
In previous versions of Entity Framework (Before 4.0) I believe you had to write your own mapping code for your classes. Is there a better way to do this now?
Also an additional question is would it be bad practice to include methods on the DTO's that performs business logic? Where would be the best place to apply business logic in this case?
The best way to map from EF entities to DTOs is to project. My example linked there uses view models rather than DTOs, but the idea is the same.
With most ORMs, EF included, there is a cost to materializing entities which you don't need to pay if you just need a DTO. The cost includes:
Fixup -- when two objects reference the same related object, make sure they point to the same instance.
Tracking -- overhead for tracking the instance in a context.
Unnecessary columns -- you might not need all properties for your DTOs.
Aggregates -- functions like .Count() are far more efficient in SQL than in object space.
If you use a L2E projection, you don't incur any of this cost. If you follow the common advice to use the AutoMapper hammer for every problem which looks like a nail, you pay all of it.
I do agree with #sternr about not putting methods on entities / DTOs. For a more detailed examination of this idea, read "At the Boundaries, Applications are Not Object-Oriented."
Use AutoMapper to map between simple DTO's and EF entities
[EDIT:] for your other questions:
For the mapping: you could either use the built in edmx designer which allows you to use an existing DB schema to generate your model entities, or the other way around (define your entities, and let EF create your DDL).
Newer versions (as of 4.1) you could simply code your entities and add DataAnnotations on the associated properties and EF will do the magic mapping (here's a good sample)
As for adding logic to DTO's, well DTO's by their definition are a data contact - the consumer will probably create it's own implementation of them (be them by the automatic proxy or other manual wrappers), so placing logic in them kinda makes no sense.

AutoMapper in the DAL: When to use Mapper.Reset()?

I'm using AutoMapper in a generated Data Access Layer. That works fine. It was a little confusing when using AutoMapper in another layer and realizing the mappings created in the DAL with Mapper.CreateMap<T1, T2>() were still present. I see Mapper.Reset() which will remove these however I'd rather not have to have the other layers worry about the DAL. Would the best practice be to put a Mapper.Reset() before and after my mapping operations in the DAL? Or is there a way to give these DAL mappings a non-default key to let them persist but not interfere with the use of AutoMapper in other layers?
Note: The use of AutoMapper in the DAL has some specific options such as a number of .ForMember(...) calls that my other layers should not use (without a Mapper.Reset() they would reuse these options).
AutoMapper works as a singleton/single instance. Does it really matter though?
EDIT : This may help you Using Profiles in Automapper to map the same types with different logic
If your other layers aren't worried so much about the DAL classes chances are they aren't going to be calling Map on an instance of the DAL class anyway.
If you call Reset() then your DAL classes will need to restate them when they next need to do some mapping which will add extra very unnecessary overhead.
EDIT : If you call Reset at the start of every DAL call then you can only have a single threaded Data Access strategy. If you call Reset in the middle of a mapping for another DAL project then you are going to obviously break this - so you will have to lock on every DAL method.
This is not the way to use Automapper so I would be leaning towards either looking into those profiles, or not using it all together.
ALSO : Can you post a sample code for what is wrong with having lots and lots of multiple mappings going on? Are there different mapping strategies between two types depending on where in the DAL they are being called from?

DDD: Where to put persistence logic, and when to use ORM mapping

We are taking a long, hard look at our (Java) web application patterns. In the past, we've suffered from an overly anaemic object model and overly procedural separation between controllers, services and DAOs, with simple value objects (basically just bags of data) travelling between them. We've used declarative (XML) managed ORM (Hibernate) for persistence. All entity management has taken place in DAOs.
In trying to move to a richer domain model, we find ourselves struggling with how best to design the persistence layer. I've spent a lot of time reading and thinking about Domain Driven Design patterns. However, I'd like some advice.
First, the things I'm more confident about:
We'll have "thin" controllers at the front that deal only with HTTP and HTML - processing forms, validation, UI logic.
We'll have a layer of stateless business logic services that implements common algorithms or logic, unaware of the UI, but very much aware of (and delegating to) the domain model.
We'll have a richer domain model which contains state, relationships, and logic inherent to the objects in that domain model.
The question comes around persistence. Previously, our services would be injected (via Spring) with DAOs, and would use DAO methods like find() and save() to perform persistence. However, a richer domain model would seem to imply that objects should know how to save and delete themselves, and perhaps that higher level services should know how to locate (query for) domain objects.
Here, a few questions and uncertainties arise:
Do we want to inject DAOs into domain objects, so that they can do "this.someDao.save(this)" in a save() method? This is a little awkward since domain objects are not singletons, so we'll need factories or post-construction setting of DAOs. When loading entities from a database, this gets messy. I know Spring AOP can be used for this, but I couldn't get it to work (using Play! framework, another line of experimentation) and it seems quite messy and magical.
Do we instead keep DAOs (repositories?) completely separate, on par with stateless business logic services? This can make some sense, but it means that if "save" or "delete" are inherent operations of a domain object, the domain object can't express those.
Do we just dispense with DAOs entirely and use JPA to let entities manage themselves.
Herein lies the next subtlety: It's quite convenient to map entities using JPA. The Play! framework gives us a nice entity base class, too, with operations like save() and delete(). However, this means that our domain model entities are quite closely tied to the database structure, and we are passing objects around with a large amount of persistence logic, perhaps all the way up to the view layer. If nothing else, this will make the domain model less re-usable in other contexts.
If we want to avoid this, then we'd need some kind of mapping DAO - either using simple JDBC (or at least Spring's JdbcTemplate), or using a parallel hierarchy of database entities and "business" entities, with DAOs forever copying information from one hierarchy to another.
What is the appropriate design choice here?
Martin
Your questions and doubts ring an interesting alarm here, I think you went a bit too far in your interpretation of a "rich domain model". Richness doesn't go as far as implying that persistence logic must be handled by the domain objects, in other words, no, they shouldn't know how to save and delete themselves (at least not explicitely, though Hibernate actually adds some persistence logic transparently). This is often referred to as persistence ignorance.
I suggest that you keep the existing DAO injection system (a nice thing to have for unit testing) and leave the persistence layer as is while trying to move some business logic to your entities where it's fit. A good starting point to do that is to identify Aggregates and establish your Aggregate Roots. They'll often contain more business logic than the other entities.
However, this is not to say domain objects should contain all logic (especially not logic needed by many other objects across the application, which often belongs in Services).
I am not a Java expert, but I use NHibernate in my .NET code so my experience should be directly translatable to the Java world.
When using ORM (like Hibernate you mentioned) to build Domain-Driven Design application, one of good (I won't say best) practices is to create so-called application services between the UI and the Domain. They are similar to stateless business objects you mentioned, but should contain almost no logic. They should look like this:
public void SayHello(int id, String helloString)
{
SomeDomainObject target = domainObjectRepository.findById(id); //This uses Hibernate to load the object.
target.sayHello(helloString); //There is a single domain object method invocation per application service method.
domainObjectRepository.Save(target); //This one is optional. Hibernate should already know that this object needs saving because it tracks changes.
}
Any changes to objects contained by DomainObject (also adding objects to collections) will be handled by Hibernate.
You will also need some kind of AOP to intercept application service method invocations and create Hibernate's session before the method executes and save changes after method finishes with no exceptions.
There is a really good sample how to do DDD in Java here. It is based on the sample problem from Eric Evans' 'Blue Book'. The application logic class sample code is here.

How can I gradually transition to NHibernate persistence logic from existing ADO.NET persistence logic?

The application uses ADO.NET to invoke sprocs for nearly every database operation. Some of these sprocs also contain a fair amount of domain logic. The data access logic for each domain entity resides in the domain class itself. ie, there is no decoupling between domain logic and data access logic.
I'm looking to accomplish the following:
decouple the domain logic from the data access logic
make the domain model persistence ignorant
implement the transition to NHibernate gradually across releases, refactoring individual portions of the DAL (if you can call it that) at a time
Here's my approach for transitioning a single class to NHibernate persistence
create a mapping for the domain class
create a repository for the domain class (basic CRUD operations inherited from a generic base repository)
create a method in the repository for each sproc used by the old DAL (doing some refactoring along the way to pull out the domain logic)
modify consumers to use the repository rather than the data access logic in the class itself
remove the old data access logic and the sprocs
The issues I have are with #1 and #4.
(#1) How can I map properties of a type with no NHibernate mapping?
Consider a Person class with an Address property (Address being a domain object without an NH mapping and Person being the class I'm mapping). How can I include Address in the Person mapping without creating an entire mapping for Address?
(#4) How should I manage the dependencies on old data access logic during the transition?
Classes in the domain model utilize the old data access logic that I'm looking to remove. Consider an Order class with a CustomerId property. When the Order needs info on the Customer it invokes the ADO.NET data access logic that resides in the Customer class. What options are there other than maintaining the old data access logic until the dependent classes are mapped themselves?
I would approach it like this:
Refactor and move the data access logic out of the domain classes into a data layer.
Refactor and move the domain logic out of the sprocs into a data layer. (This step is optional, but doing it will definitely make the transition smoother and easier.)
You don't need a repository, but you can certainly create one if you want.
Create a NHibernate mapping for every domain class (there are tools that do this).
Create a NHibernate oriented data access API that slowly replaces the sproc data layer.
Steps 1 & 2 are the hardest part as it sounds like you have tight coupling that ideally never would have happened. Neither of these first two steps involve NHibernate at all. You are strictly moving to a more maintainable architecture before trying to swap out your data layer.
While it may be possible to create NHibernate mappings one by one and utilize them without the full object graph being available, that seems like asking for unnecessary pain. You need to proceed very cautiously if you choose that path and I just wouldn't recommend it. To do so, you may leave a foreign key mapped as a plain int/guid instead of as a relation to another domain class, but you have to be very careful you don't corrupt your data by half committing to NHibernate in that way. Automated unit/integration tests are your friend.
Swapping out a data layer is hard. It is easier if you have a solid lowest common denominator data layer architecture, but I wouldn't actually recommend creating an architecture using a lowest common denominator approach. Loose coupling is good, but you can go too far.
search more on the internet for nhibernate e-books
Refactor and move the data access logic out of the domain classes into a data layer.
Refactor and move the domain logic out of the sprocs into a data layer. (This step is optional, but doing it will definitely make the transition smoother and easier.)
You don't need a repository, but you can certainly create one if you want.
Create a NHibernate mapping for every domain class (there are tools that do this).
Create a NHibernate oriented data access API that slowly replaces the sproc data layer

FluentNHibernate Unit Of Work / Repository Design Pattern Questions

I think I am at a impasse here. I have an application I built from scratch using FluentNHibernate (ORM) / SQLite (file db). I have decided to implement the Unit of Work and Repository Design pattern. I am at a point where I need to think about the end game, which will start as a WPF windows app (using MVVM) and eventually implement web services / ASP.Net as UI.
Now I already created domain objects (entities) for ORM. And now I don't know how should I use it outside of ORM. Questions about it include:
Should I use ORM entity objects directly as models in MVVM? If yes, do I put business logic (such as certain values must be positive and be greater than another Property) in those entity objects? It is certainly the simpler approach, and one I am leaning right now. However, will there be gotchas that would trash this plan?
If the answer above is no, do I then create a new set of classes to implement business logic and use those as Models in MVVM? How would I deal with the transition between model objects and entity objects? I guess a type converter implementation would work well here.
To answer the first part of your question, yes your business logic and validation should go in your entities. The point of NHibernate is to let you design your entities to be persistence ignorant. That means that you should, whenever possible, be designing your entities as you would if you didn't care about persistence. This isn't entirely feasible as you'll soon find out (you'll need to make your properties virtual in order to support lazy loading and if you want to use NHibernate Validator you'll be decorating your properties with validation attributes), but for the most part NHibernate does a good job of staying out of your way.
As for whether to use your entities as the models, you'll get mixed reviews on that. Ideally, you would create separate viewmodel classes and map from your entities to the viewmodel so that your views will only access to the bare minimum of information they need. This also goes a long way in preventing N+1 access issues. However, doing so is often a huge pain. Granted, there are tools like AutoMapper that will make it easier from transposing your entity properties to a viewmodel.