Copying NHibernate POCO to DTO without triggering lazy load or eager load - nhibernate

I need to create DTOs from NHibernate POCO objects. The problem is that the POCO objects contain dynamic proxies, which should not be copied to the DTO. I eager load all the collections and references I need to transfer in advance, I don't want NHibernate to start loading referenced collections which I did not load in advance.
Several similar questions on SO received answers which either:
Suggest Session.GetSessionImplementation().PersistenceContext.Unproxy();
Suggest turning off Lazy Loading.
In my case the first suggestion is irrelevant, as according to my understanding it causes eager loading to replace the proxies. In reality, it doesn't even work - it doesn't remove the proxies in my objects. (Any explanation why?)
The second suggestion, turning off lazy loading seems to cause all references and collections to eager load, basically loading the entire DB. My expectation was that if lazy loading is off, and I have not requested a collection, it will not be loaded. (Am I correct that NHibernate offers no such option?)
I am using NHibernate 3.3.1 with fluent configuration.
To reiterate my main question, I need to create DTOs clean of proxies, copied from POCOs which contain proxies, and I don't want to load the data behind those proxies.
Any helpful suggestion which includes example code and automates the process with ValueInjecter / AutoMapper will be immensely helpful.
Edit #1:
Following Roger Alsing's suggestion to use projections, I realized that what I'm actually looking for is a ValueInjecter-like convention based mapping. Here is why. Initially, my DTOs will be defined the same as the model's POCOs. This is due to a large code base which depends on the existing POCOs being transferred on the client-side project.
Using projections, I will have to specify which subset of fields have to be copied, and this subset may be different in each context (as, ideally, a DTO would differ). This will mean a lot of new code introduced to the server side, when there should be the second option.
Using ValueInjecter, I will be able to populate the DTOs by convention in one call, without writing specific projections, or having to maintain those into the future. That is, if I am able to have ValueInjecter ignore Proxy objects.
Given that using projections is a good but not ideal solution in my situation, is there a way to configure something like ValueInjecter to copy POCOs without copying proxies or triggering eager/lazy loads on copy?

I solve this by selecting DTO's as projections using Linq or whatever query language the O/R Mapper may have.
e.g.
return from c in customers
select new CustomerDTO
{
Name = c.Name ,
Orders = c.Orders.Select (o => new OrderDTO {...} )
};
This way, you don't need to resort to reflection magic or any other fancy stuff.
And the query fetches exactly what you need in one go, thus, this is usually much more efficient than fetching entities and then transforming them to DTO's in mem.
(it can be less efficient in some cases incase the resulting SQL query contains extra joins for whatever reason..)

I'm using the following ValueResolver with AutoMapper:
/// <summary>
/// ValueResolver that will set NHibernate proxy objects to null, instead of triggering a lazy load of the object
/// </summary>
public class IgnoreNHibernateProxyValueResolver : IValueResolver
{
public ResolutionResult Resolve(ResolutionResult source)
{
var prop = source.Type.GetProperty(source.Context.MemberName).GetValue(source.Value, null);
var proxy = prop as INHibernateProxy;
if (proxy != null && proxy.HibernateLazyInitializer.IsUninitialized)
{
return source.Ignore();
}
return source.New(prop);
}
}

for ValueInjecter solution I recommend using SmartConventionInjection (you need to copy the code from the linked page into your solution)
and after specify a convention that won't touch the proxy properties
here's a start:
public class MapPoco: SmartConventionInjection
{
protected override bool Match(SmartConventionInfo c)
{
return c.SourceProp.Name == c.TargetProp.Name;
}
}

Take a look on Projections in Introduction to QueryOver in NH 3.0
CatSummary summaryDto = null;
IList<CatSummary> catReport =
session.QueryOver<Cat>()
.SelectList(list => list
.SelectGroup(c => c.Name).WithAlias(() => summaryDto.Name)
.SelectAvg(c => c.Age).WithAlias(() => summaryDto.AverageAge))
.TransformUsing(Transformers.AliasToBean<CatSummary>())
.List<CatSummary>();

Related

Is protobuf-net suited for serializing arbitrary object/domain models?

I have been exploring the CQRS/DDD-principles and patterns for a while now and have started implementing a sample project where I have split my storage-model into a WriteModel and a ReadModel. The WriteModel will use a simple NoSQL-like database where aggregates are stored in a key-value style, with value being just a serialized version of the aggregate.
I am now looking at ProtoBuf-Net for serializing and deserializing my domain model aggregates in and out of storage. Other than this post I haven't found any guidance or tips for using ProtoBuf-Net in this area. The point is that the (ideal) requirements for serialization and deserialization of aggregates is that the domain model should have as little knowledge as possible about this infrastructural concern, which implies the following:
No attributes on the classes
No constructors, getters, setters or any other piece of code just for the sake of serialization.
Ability to use any (custom) type possible and have it serialized/deserialized.
Thus far I have implemented just the serialization of the first versions of my aggregates which works perfectly fine. I use the RuntimeTypeModel.Default-instance to configure the MetaModel at runtime and have UseConstructor = false everywhere, which enables me to completely separate the serialization mechanics from my domain-assembly. I have even implemented a custom post-deserialization mechanism that enables me to just-in-time initialize fields after ProtoBuf-Net has deserialized it into a valid instance. So suppose I have class AggregateA like so:
[Version(1)]
public sealed class AggregateA
{
private readonly int _x;
private readonly string _y;
...
}
Then in my serialization-library I have code something along the following lines:
var metaType = RuntimeTypeModel.Default.Add(typeof(AggregateA), false);
metaType.UseConstructor = false;
metaType.AddField(1, "_x");
metaType.AddField(2, "_y");
...
However, I realize that up to this point I have only implemented the basic scenario, and I am now starting to think about how to approach versioning of my model. I am particularly interested in larger refactoring-scenario's, where type A has been split into type A1 and A2, for example:
[Version(2)]
public sealed class AggregateA1
{
private readonly int _x;
...
}
[Version(2)]
public sealed class AggregateA2
{
private readonly string _y;
...
}
Suppose I have a serialized bunch of instances of AggregateA, but now my domain model knows only AggregateA1 and AggregateA2, how would you handle this scenario with ProtoBuf-Net?
A second question deals with point 3: is ProtoBuf-Net capable of handling arbitrary types if you're willing to put in some extra configuration-effort? I've read about exceptions raised when using the DateTimeOffset-type, which makes me think not all types can be serialized by the framework out-of-the-box, but can I serialize these types by registering them in the RuntimeTypeModel? Should I even want to go there? Or better to forget about serializing common .NET types other than the simple ones?
protobuf-net is intended to work with predictable known models. It is true that everything can be configured at runtime, but I have not put any thought as to how to handle your A1/A2 scenario, precisely because that is not a supported scenario (in my defense, I can't see that working nicely with most serializers). Thinking off the top of my head, if you have the configuration/mapping data somewhere, then you could simply deserialize twice; i.e. as long as we still tell it that AggregateA1._x maps to 1 and AggregateA2._y maps to 2, you can do:
object a1 = model.Deserialize(source, null, typeof(AggregateA1));
source.Position = 0; // rewind
object a2 = model.Deserialize(source, null, typeof(AggregateA2));
However, more complex tweaks would require additional thought.
Re "arbitrary types"... define "arbitrary" ;p In particular, there is support for "surrogate" types which can be useful for some transformations - but without a very specific "problem statement" it is hard to answer completely.
Summary:
protobuf-net has an intended usage, which includes both serialization-aware (attributed, etc) and non-aware scenarios (runtime configuration, etc) - but it also works for a range of more bespoke scenarios (letting you drop to the raw reader/writer API if you want to). It does not and cannot guarantee to be a direct fit for every serialization scenario imaginable, and how well it behaves will depend on how far from that scenario you are.

NHibernate DateTimeOffsetType proxy source?

I have an existing application using NHibernate to load some fairly complex objects from a database (SQL Server 2008 R2) that has been running for quite some time.
Today, I'm encountering the following error when trying to use JSON.Net to serialize my object:
Error getting value from 'DefaultValue' on 'NHibernate.Type.DateTimeOffsetType'.
None of the properties in my NHibernate mappings are using the DateTimeOffsetType, so I suspect that NHibernate is proxying my objects' properties to that somehow.
I have several Nullable DateTime values on my object, but nothing new to my current release.
Where should I be looking to figure out what properties NHibernate is trying use that type for?
What else might I be missing? The error comes when I attempt to serialize using this code:
var converter = new IsoDateTimeConverter();
x.Json = JsonConvert.SerializeObject(myObject, converter);
Again, that code has been in place for quite some time, it's just the problem that is new.
Not really the solution you will have been looking for perhaps, but a solution none the less - I encountered something similar.
In my case I had forgotten to return my DTO from a web api call and the default json serialiser kicking in did this.
Now I map my data object over to a DTO object which has data contract attributes and I serialize that.
Since my DTO is simple and doesn't get NHibernate Proxified this error no longer seems to occur.
Otherwise - I have done this for other Nullable Dates - where I want more control over the serialisation. Define a custom converter for it and do as you wish, but for this Nhibernate Type.
I'd prefer not serialising (or trying to) those proxy types at all though.
to get to know which properties have datetimeoffset as type
var propertiesWithDateTimeOffset = nhConfiguration.ClassMappings
.SelectMany(c => c.PropertyClosureIterator)
.Where(p => p.Type is DateTimeOffsetType)
.Select(p => p.PersistentClass.ClassName + "." + p.Name);
Note: the code doesn't handle components yet but it would be easy to add

domain design with nhibernate

In my domain I have something called Project which basically holds a lot of simple configuration propeties that describe what should happen when the project gets executed. When the Project gets executed it produces a huge amount of LogEntries. In my application I need to analyse these log entries for a given Project, so I need to be able to partially successively load a portion (time frame) of log entries from the database (Oracle). How would you model this relationship as DB tables and as objects?
I could have a Project table and ProjectLog table and have a foreign key to the primary key of Project and do the "same" thing at object level have class Project and a property
IEnumerable<LogEntry> LogEntries { get; }
and have NHibernate do all the mapping. But how would I design my ProjectRepository in this case? I could have a methods
void FillLog(Project projectToFill, DateTime start, DateTime end);
How can I tell NHibernate that it should not load the LogEntries until someone calls this method and how would I make NHibernate to load a specifc timeframe within that method?
I am pretty new to ORM, maybe that design is not optimal for NHibernate or in general? Maybe I shoul design it differently?
Instead of having a Project entity as an aggregate root, why not move the reference around and let LogEntry have a Product property and also act as an aggregate root.
public class LogEntry
{
public virtual Product Product { get; set; }
// ...other properties
}
public class Product
{
// remove the LogEntries property from Product
// public virtual IList<LogEntry> LogEntries { get; set; }
}
Now, since both of those entities are aggregate roots, you would have two different repositories: ProductRepository and LogEntryRepository. LogEntryRepository could have a method GetByProductAndTime:
IEnumerable<LogEntry> GetByProductAndTime(Project project, DateTime start, DateTime end);
The 'correct' way of loading partial / filtered / criteria-based lists under NHibernate is to use queries. There is lazy="extra" but it doesn't do what you want.
As you've already noted, that breaks the DDD model of Root Aggregate -> Children. I struggled with just this problem for an absolute age, because first of all I hated having what amounted to persistence concerns polluting my domain model, and I could never get the API surface to look 'right'. Filter methods on the owning entity class work but are far from pretty.
In the end I settled for extending my entity base class (all my entities inherit from it, which I know is slightly unfashionable these days but it does at least let me do this sort of thing consistently) with a protected method called Query<T>() that takes a LINQ expression defining the relationship and, under the hood in the repository, calls LINQ-to-NH and returns an IQueryable<T> that you can then query into as you require. I can then facade that call beneath a regular property.
The base class does this:
protected virtual IQueryable<TCollection> Query<TCollection>(Expression<Func<TCollection, bool>> selector)
where TCollection : class, IPersistent
{
return Repository.For<TCollection>().Where(selector);
}
(I should note here that my Repository implementation implements IQueryable<T> directly and then delegates the work down to the NH Session.Query<T>())
And the facading works like this:
public virtual IQueryable<Form> Forms
{
get
{
return Query<Form>(x => x.Account == this);
}
}
This defines the list relationship between Account and Form as the inverse of the actual mapped relationship (Form -> Account).
For 'infinite' collections - where there is a potentially unbounded number of objects in the set - this works OK, but it means you can't map the relationship directly in NHibernate and therefore can't use the property directly in NH queries, only indirectly.
What we really need is a replacement for NHibernate's generic bag, list and set implementations that knows how to use the LINQ provider to query into lists directly. One has been proposed as a patch (see https://nhibernate.jira.com/browse/NH-2319). As you can see the patch was not finished or accepted and from what I can see the proposer didn't re-package this as an extension - Diego Mijelshon is a user here on SO so perhaps he'll chime in... I have tested out his proposed code as a POC and it does work as advertised, but obviously it's not tested or guaranteed or necessarily complete, it might have side-effects, and without permission to use or publish it you couldn't use it anyway.
Until and unless the NH team get around to writing / accepting a patch that makes this happen, we'll have to keep resorting to workarounds. NH and DDD just have conflicting views of the world, here.

Spring.Net HibernateTemplate.Execute Clarification

I am taking over a project that was written by third party consultants who have already left.
I come from EF backgournd. One of the DAO class has the following which I find very hard to get my head around on details of what is exactly happening step by step. If anyone could kindly help me to understand this code section will be much appreciated.
return HibernateTemplate.Execute(
delegate(ISession hbSession) // <<--What is this code actually trying to do?
{
string queryText = "from {0} x where x.Code = :Code";
queryText = string.Format(queryText, typeof(Product));
IQuery query = hbSession.CreateQuery(queryText);
query.SetParameter("Code", productCode);
query.SetCacheable(true);
query.SetCacheRegion(CoreCacheConstants.ProductQueryCacheRegion); // <-- What is this code trying to do.
var fund = query.UniqueResult(); // <-- Is this similar to DISTINCT keyword in LINQ?
if (fund == null)
throw new ArgumentException(String.Format("No product found with productcode: {0}", productCode: ));
NHibernateUtil.Initialize(((Product)Product).Details); // <--What is this code trying to do. And where is the execute method for above queries.
return fund;
}
) as Product
Basically I am confused with delegate part and why delegate is being used instead of simple query to database. And what is the benefit of above approach.
Also I cant see any nHibernate ORM mapping xml. Does Spring.NET requires mapping files in order to pass data from/to data source?In order words how does ISession knows which database to connect to and which table to use etc
This is what in the spring documents is referred to as Classic Hibernate Usage. It is not the currently recommended approach to work with NHibernate, which is described in the chapter on object relational mappers.
The "convenient" usage of delegates here is basically done to provide the HibernateTemplate the means to manage a session and hand this managed session over to other custom methods (in this particular case an anonymous method). (I think it's an implementation of the visitor pattern, btw).
Using this approach, the classic HibernateTemplate can provide functionality to methods it doesn't "know of", such as opening and closing sessions correctly and participating in transactions.
The query is actually being executed by HibernateTemplate.Execute(myMethod); I imagine it creates and initializes a session for you, does transaction management, executes your method with the managed session and cleans everything up.
I've never used HibernateTemplate, but I'm sure it would require mapping files and a SessionFactory, so if this code is hit during execution and doesn't throw any exceptions, the configuration for those has to be there somewhere!
With respect to the questions (besides the delegate part) within your posted code: the use of NHibernateTemplate hasn't really got anything to do with it: you can just as well run this code in any piece of code where you've got hold of a valid ISession instance:
the session executes a HQL query; this query is added to the query cache. I've never used SetCacheRegion myself, but apparently it gives you "fine-grained control over query cache expiration policies".
query.UniqueResult
NHibernateUtil.Initialize

Ad hoc data and repository pattern

What is the recommended way to return ad hoc (custom case by case) data from repository which don't fit any model entities or which extend some?
The 101 example would be the ubiquitous hello word application: a blog system. Suppose you want to load a list of posts where post entry has some additional information which does not exists in the Post entity. Let’s say it is the number of comments and the date and time of the last comment. This would be highly trivial if one was using the plain old SQL and reading data directly from the database. How am I supposed to do it optimally using the repository pattern if I cannot afford loading the entire collections of Comments for each Post, and I want to do it in one database hit? Is there any commonly used pattern for this situation? Now imagine that you have moderately complex web application where each page needs a slightly different custom data, and loading full hierarchies is not possible (performance, memory requirements etc).
Some random ideas:
Add a list of properties to each model which could be populated by the custom data.
Subclass model entities case by case, and create custom readers for each subclass.
Use LINQ, compose ad hoc queries and read anonymous classes.
Note: I’ve asked a similar question recently, but it seemed to be too general and did not attract much attention.
Example:
Based on suggestions in answers below, I am adding a more concrete example. Here is the situation I was trying to describe:
IEnumarable<Post> posts = repository.GetPostsByPage(1);
foreach (Post post in posts)
{
// snip: push post title, content, etc. to view
// determine the post count and latest comment date
int commentCount = post.Comments.Count();
DateTime newestCommentDate = post.Comments.Max(c => c.Date);
// snip: push the count and date to view
}
If I don’t do anything extra and use an off the shelf ORM, this will result to n+1 queries or possibly one query loading all posts and comments. But optimally, I would like to be able to just execute one SQL which would return one row for each post including the post title, body etc. and the comment count and most recent comment date in the same. This is trivial in SQL. The problem is that my repository won’t be able to read and fit this type of data into the model. Where do the max dates and the counts go?
I’m not asking how to do that. You can always do it somehow: add extra methods to the repository, add new classes, special entities, use LINQ etc., but I guess my question is the following. How come the repository pattern and the proper model driven development are so widely accepted, but yet they don’t seem to address this seemingly very common and basic case.
There's a lot to this question. Are you needing this specific data for a reporting procedure? If so, then the proper solution is to have separate data access for reporting purposes. Flattened databases, views, ect.
Or is it an ad-hoc query need? If so, Ayende has a post on this very problem. http://ayende.com/Blog/archive/2006/12/07/ComplexSearchingQueryingWithNHibernate.aspx
He utilizes a "Finder" object. He's using NHibernate, so essentially what he's doing is creating a detached query.
I've done something similar in the past by creating a Query object that I can fill prior to handing it to a repository (some DDD purist will argue against it, but I find it elegant and easy to use).
The Query object implements a fluent interface, so I can write this and get the results back:
IQuery query = new PostQuery()
.WithPostId(postId)
.And()
.WithCommentCount()
.And()
.WithCommentsHavingDateLessThan(selectedDate);
Post post = _repository.Find(query);
However, in your specific case I have to wonder at your design. You are saying you can't load the comments with the post. Why? Are you just being overly worrisome about performance? Is this a case of premature optimization? (seems like it to me)
If I had a Post object it would be my aggregate root and it would come with the Comments attached. And then everything you want to do would work in every scenario.
Since we needed to urgently solve the issue I outlined in my original question, we resorted to the following solution. We added a property collection (a dictionary) to each model entity, and if the DAL needs to, it sticks custom data into to. In order to establish some kind of control, the property collection is keyed by instances of a designated class and it supports only simple data types (integers, dates, ...) which is all we need at movement, and mostly likely will ever need. A typical case which this solves is: loading an entity with counts for its subcollections instead of full populated collections. I suspect that this probably does not get any award for a software design, but it was the simplest and the most practical solution for our case.
Can't say I really see what the problem is, just firing in the air here:
Add a specific entity to encapsulate the info yo want
Add a property Comments to the Post. (I don't see why this would require you to fetch all comments - you can just fetch the comments for the particular post you're loading)
Use lazy loading to only fetch the comments when you access the property
I think you would have a greater chance of seeing your question answered if you would make platform, language and O/R mapper specific (seems to be .NET C# or VB, since you mentioned LINQ. LINQ 2 SQL? Entity framework? Something else?)
If you aren't locked into a RDBMs then a Database like CouchDB or Amazons SimpleDB might be something to look at. What you are describing is trivial in a CouchDB View. This probably doesn't really answer you specific question but sometimes it's good to look at radically different options.
For this I generally have a RepositoryStatus and a Status class that acts as my Data Transfer Object (DTO). The Status class is used in my application service layer (for the same reason) from which the RepositoryStatus inherits. Then with this class I can return error messages, response objects, etc. from the Repository layer. This class is generic in that it will accept any object in and cast it out for the receiver.
Here is the Status class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RanchBuddy.Core.Domain;
using StructureMap;
namespace RanchBuddy.Core.Services.Impl
{
[Pluggable("Default")]
public class Status : IStatus
{
public Status()
{
_messages = new List<string>();
_violations = new List<RuleViolation>();
}
public enum StatusTypes
{
Success,
Failure
}
private object _object;
public T GetObject<T>()
{
return (T)_object;
}
public void SetObject<T>(T Object)
{
_object = Object;
}
private List<string> _messages;
public void AddMessage(string Message)
{
_messages.Add(Message);
}
public List<string> GetMessages()
{
return _messages;
}
public void AddMessages(List<string> Messages)
{
_messages.AddRange(Messages);
}
private List<RuleViolation> _violations;
public void AddRuleViolation(RuleViolation violation)
{
_violations.Add(violation);
}
public void AddRuleViolations(List<RuleViolation> violations)
{
_violations.AddRange(violations);
}
public List<RuleViolation> GetRuleViolations()
{
return _violations;
}
public StatusTypes StatusType { get; set; }
}
}
And here is the RepositoryStatus:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RanchBuddy.Core.Services.Impl;
using StructureMap;
namespace RanchBuddy.Core.DataAccess.Impl
{
[Pluggable("DefaultRepositoryStatus")]
public class RepositoryStatus : Status, IRepositoryStatus
{
}
}
As you can see the RepositoryStatus doesn't yet do anything special and just relies on the Status objects utilities. But I wanted to reserve the right to extend at a later date!
I am sure that some of the die-hards out there will state that this should not be used if you are to be a prueist...however I know your pain in that sometimes you need to pass out more than just a returned object!