LLBLGEN / ERM / NHibernate e.t.c.

Posts   
 
    
Posts: 254
Joined: 16-Nov-2006
# Posted on: 04-Nov-2008 15:37:55   

Our company are evaluating ORM mappers to use for other products within the company even though LLBLGEN has been used for other projects it's not the defacto standard.

Other products being considered are Microsofts entity framework or even products such as NHibernate. Some individuals within the company are also very keen on POCO objects ( persistence ignorant design principle ).

Perhaps you can add some thoughts on how LLBLGEN can help and is better / worse than these products

jmeckley
User
Posts: 403
Joined: 05-Jul-2006
# Posted on: 04-Nov-2008 17:18:13   

I would be cautious of MS Entity Framework. it's a very new product and most reviews say the product is lacking as an enterprise level ORM. The xml used to define the objects is monstrous.

NH uses the poco model. it heavily relies on xml to define the factory configuration and entity to db mappings. Fluent NH is a new project which uses lambas and expressions to define the mappings in code rather than xml. This is good choice if you are using .net 3.5

Active Record is built on top of NHibernate. This framework uses Attributes to define the mappings instead of xml. A plus for some compile time checks. A minus as persistance logic begins to creep into the domain. For now lets consider AR and NH to be the same.

NH makes it possible to test the domain without requiring an actual database (domain drives the db design) There are multiple ways to query the database HQL, sql, criteria api. all are based on strings. With adequate unit tests this isn't a problem, but it requires more tests. because you control the mappings you can better encapsulate the domain entities.

LLBL does not use the poco model as all entities require the EntityBase implementation. This can make the entities noisy with persistence logic. LLBL has an excellent strongly typed predicate engine which allows for just about any sql statement. The support is also top noche. LLBL requires an existing database to generate the domain (although v3 may not require a db) . LLBL also uses wizards and code generators to create most of the entities for you. While this does reduce key strokes it can also expose functionality you may not want exposed (collections). This could be mediated by using interfaces on the entities and "hiding" the collctions. however at some point the object must be cast to an EntityBase so the object can be saved (using adaptor, shouldn't be an issue with SS)

both NH and LLBL allow you populate projections. NH uses ctor args, LLBL uses mutable properties. I favor NH's ctor args as this allows my value objects to be immutable.

both have an implementation of unit-of-work. NH uses the concept to manage changes and then persist when the session is flushed. LLBL's uow aligns closer to db transactions/modifications.

For me biggest difference between the 2 frameworks is NH is centered around the domain model and how the domain interacts with the database. LLBL is focused on mapping entities from the database. NH is also focused only on the domain/db interaction. there is no presentation logic in the framework. LLBL includes references to objects required for databinding and error reporting.

Both frameworks are mature and have there pros/cons. In my experience I have found that depending on the skills of the programmers and how the product is developed and/or tested will lend itself to toward either LLBL or NH.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 04-Nov-2008 18:07:54   

Matt, It's really a matter of how you want to work: if you start with poco's in code, and go from there, LLBLGen Pro gets in your way. If you start with a DB, nhibernate will give you a lot of extra work.

LLBLGen Pro has build in support for Linq, NH doesn't, which can be very important for your project if you want to utilize Linq. Another big advantage is that it's fully equiped to be used in a distributed system. This means that you don't have to fight the framework when entity objects come in from over the wire, the changes are already inside the entity and you can directly save them for example (in entity framework and NH you have to tell the session/context what was changed and if this entity is new or not)

I'll respond to some points jmeckley made below.

jmeckley wrote:

I would be cautious of MS Entity Framework. it's a very new product and most reviews say the product is lacking as an enterprise level ORM. The xml used to define the objects is monstrous.

100% agreed. Try to create a 200 table model, and you're in for a lot of fun simple_smile .

NH makes it possible to test the domain without requiring an actual database (domain drives the db design) There are multiple ways to query the database HQL, sql, criteria api. all are based on strings. With adequate unit tests this isn't a problem, but it requires more tests. because you control the mappings you can better encapsulate the domain entities.

With proper repositories this isn't really a concern at all with LLBLGen Pro as well, because: you should focus on testing your code. I don't mind if people write thousands of tests to test our code again, but for your project it's a bit overkill, we already run a truckload of tests on our framework.

LLBL does not use the poco model as all entities require the EntityBase implementation. This can make the entities noisy with persistence logic. LLBL has an excellent strongly typed predicate engine which allows for just about any sql statement. The support is also top noche. LLBL requires an existing database to generate the domain (although v3 may not require a db) . LLBL also uses wizards and code generators to create most of the entities for you. While this does reduce key strokes it can also expose functionality you may not want exposed (collections). This could be mediated by using interfaces on the entities and "hiding" the collctions. however at some point the object must be cast to an EntityBase so the object can be saved (using adaptor, shouldn't be an issue with SS)

One really has to think through if focussing on this is really important. for example, is it important if a collection is of a given type? Why would one hide collections in the code, is that really a big problem? If so, also consider that NH has lazy loading on collections, Adapter of LLBLGen Pro has not, which can be a reason this collection hiding isn't really necessary (as UI developers for example can't bypass BL by accessing collections to pull data from the DB)

both NH and LLBL allow you populate projections. NH uses ctor args, LLBL uses mutable properties. I favor NH's ctor args as this allows my value objects to be immutable.

You can easily change this with a custom projector class (which is really a couple of lines of code) based on one of the projection classes in the sourcecode. simple_smile In fact, in v2.6's custom class projector this is built in (as we needed it for Linq projections)

both have an implementation of unit-of-work. NH uses the concept to manage changes and then persist when the session is flushed. LLBL's uow aligns closer to db transactions/modifications.

LLBLGen Pro's unit of work also allows you to group actions in subgroups (with multiple unit of works) and add delegate calls if you want to.

For me biggest difference between the 2 frameworks is NH is centered around the domain model and how the domain interacts with the database. LLBL is focused on mapping entities from the database. NH is also focused only on the domain/db interaction. there is no presentation logic in the framework. LLBL includes references to objects required for databinding and error reporting.

Both frameworks are mature and have there pros/cons. In my experience I have found that depending on the skills of the programmers and how the product is developed and/or tested will lend itself to toward either LLBL or NH.

Agreed. Good points, Jason! simple_smile

Frans Bouma | Lead developer LLBLGen Pro
jmeckley
User
Posts: 403
Joined: 05-Jul-2006
# Posted on: 04-Nov-2008 19:07:25   

both NH and LLBL allow you populate projections. NH uses ctor args, LLBL uses mutable properties. I favor NH's ctor args as this allows my value objects to be immutable.

You can easily change this with a custom projector class (which is really a couple of lines of code) based on one of the projection classes in the sourcecode. In fact, in v2.6's custom class projector this is built in (as we needed it for Linq projections)

excellent, I overlooked that feature.

NH makes it possible to test the domain without requiring an actual database (domain drives the db design) There are multiple ways to query the database HQL, sql, criteria api. all are based on strings. With adequate unit tests this isn't a problem, but it requires more tests. because you control the mappings you can better encapsulate the domain entities.

With proper repositories this isn't really a concern at all with LLBLGen Pro as well, because: you should focus on testing your code. I don't mind if people write thousands of tests to test our code again, but for your project it's a bit overkill, we already run a truckload of tests on our framework.

true. I'm sloppy with this as sometimes I just access the DAL directly either adapter or session depending on the framework.

I also find it's good to write the tests so you know the sql produced is correct. however that requires a database and data so my point is pointless.

LLBL does not use the poco model as all entities require the EntityBase implementation. This can make the entities noisy with persistence logic. LLBL has an excellent strongly typed predicate engine which allows for just about any sql statement. The support is also top noche. LLBL requires an existing database to generate the domain (although v3 may not require a db) . LLBL also uses wizards and code generators to create most of the entities for you. While this does reduce key strokes it can also expose functionality you may not want exposed (collections). This could be mediated by using interfaces on the entities and "hiding" the collctions. however at some point the object must be cast to an EntityBase so the object can be saved (using adaptor, shouldn't be an issue with SS)

One really has to think through if focussing on this is really important. for example, is it important if a collection is of a given type? Why would one hide collections in the code, is that really a big problem? If so, also consider that NH has lazy loading on collections, Adapter of LLBLGen Pro has not, which can be a reason this collection hiding isn't really necessary (as UI developers for example can't bypass BL by accessing collections to pull data from the DB)

From the POV of expressive domains I find this important. For example

Customer customer = Repository.Find(id);
Appointment appointment = new Appointment();
appointment.Time = date;
appointment.With = someone;
customer.Appointments.Add(appointment);

works but it's clunky

Customer customer = Repository.Find(id);
customer.ScheduleAppointment.With(someone).On(date);

is more expressive and hides the implementation details.