NHibernate strange behavior inside POCO's virtual method (Very simple case) - nhibernate

I was coding a very simple case with 2 classes: Parent and Child. Parent has n children, and children has 1 Parent. I set up a bidirectional relationship between them.
I was trying to add a business rule to my parent, that rule checked for equality between the child's parent and the instance handling the call. It returned false when it should have returned true. So I simplified everything to get to the root of the problem. So I tested the same equality outside the POCO and it returned true:
Parent parent0 = session.Load<Parent>(0);
Child child = session.Load<Child>(0);
bool externalTest = parent0 == child.Parent;
I then coded a method for my Parent to test the exact same thing:
bool internalTest = parent0.IsRelated(child);
... Parent Class code
public virtual bool IsRelated(Child child)
{
return child.Parent == this;
}
...
And it returns false... I just don't get it. It's the exact same code.
More info:
So to get more info, I modified my test:
Parent parent0 = session.Load<Parent>(0);
Child child = session.Load<Child>(0);
bool externalTest = parent0 == child.Parent;
System.Diagnostics.Debug.WriteLine("outside parent: " + externalTest);
System.Diagnostics.Debug.WriteLine("Number of parent instances before call to IsRelated:" + Parent.NumberOfInstances);
parent0.IsRelated(child, parent0);
System.Diagnostics.Debug.WriteLine("Number of parent instances after call to IsRelated:" + Parent.NumberOfInstances);
... Parent Class code
public virtual void IsRelated(Child child, Parent sameAsThis)
{
bool internalTest = child.Parent == this;
System.Diagnostics.Debug.WriteLine("inside parent:" + internalTest);
bool sameTest = sameAsThis == this;
System.Diagnostics.Debug.WriteLine("this should equal sameAsThis:" + sameTest);
}
...
I passed the parent instance directly to itself and verify it was the same instance. Well it's not, I get another instance created when I enter the IsRelatedMethod.
Here are my test results:
outside parent: True
Number of parent instances before call to IsRelated:1
inside parent:False
this should equal sameAsThis:False
Number of parent instances after call to IsRelated:2
What am I doing wrong ?
For detailed mapping files and pocos, see (http://stackoverflow.com/questions/13253459/relationships-fixup-in-entityframework-vs-nhibernate)

This is because of the proxy that Nhibernate uses to lazy load entities. In your case the child's parent is a proxy instance.
To solve you problem simply change .Load to .Get
.load does not actually hit the database and populate the entity. See this blog post by Ayende for more info

Related

Where and how do the ViewLocator-generated Views get their DataContexts assigned (in Avalonia's Todo tutorial application)?

In the completed Avalonia tutorial Todo application --- where and how do TodoListView and AddItemView acquire their DataContexts to be equal to TodoListViewModel and AddItemViewModel respectively ???
I mean their parent control MainWindow's DataContext is a MainWindowViewModel instance (as assigned in App.xaml.cs file) --- while MainWindow's Content attribute is bound to MainWindowViewModel's Content property (which does get assigned instances of the viewmodels during execution). I just cannot trace the source wherefrom TodoListView and AddItemView acquire their DataContexts. Do they get it while:
Being created by the ViewLocator at runtime ? -- but that's not possible as the DataContext property of the newly instantiated View is still NULL just before the ViewLocator returns the View instance -- as shown by the output of following code in the completed application (the code in the if block is modified by me to produce required output):
public IControl Build(object data)
{
var name = data.GetType().FullName.Replace("ViewModel", "View");
var type = Type.GetType(name);
if (type != null)
{
var viewInstance = (Control)Activator.CreateInstance(type);
// the following always evaluates to true --- i.e. DataContext is always NULL before viewInstance is returned.
if(viewInstance.DataContext == null)
Console.WriteLine($"DataContext property of the newly created View instance of {name} in ViewLocator is NULL just before returning! ");
return viewInstance ;
}
else
{
return new TextBlock { Text = "Not Found: " + name };
}
}
OR they get their DataContext assigned by the parent Window ? --- but the parent window's own DataContext is MainWindowViewModel ----- how do we get to TodoListViewModel or AddItemViewModel from MainWindowViewModel ???
In short , I am unclear about where the Views generated at runtime via ViewLocator are getting their DataContext properties assigned.
Summarizing what I understood from the answer and some search and play:
If a ContentControl's (in this case Window's) Content property is a Control then the Control simply inherits the DataContext from the parent ContentControl. But if the ContentControl's Content property is a non-Control then the ContentPresenter of the ContentControl first finds a data template for the non-Control so that a child View can be generated and then sets its own DataContext to the non-Control. This newly assigned DataContext then gets inherited by the newly generated child View. Phewwwwww!
DataContext is inherited from ContentPresenter which is asking IDataTemplate.Build for a new view instance. When Content isn't a control, ContentPresenter sets its own DataContext to the value of Content which gets inherited by the child view.
ContentPresenter is used internally by the Window to display its Content property.
Same happens with ListBox items.

Automapper DTO to entity object mapping fails with child Collection

I have set lazy loading for child collections.
I want to post my object with child object, but at the time of mapping,it convert null child object into empty child object.For that i used,
e.g.
.ForMember(d => d.Taxes,
opt => opt.Condition(d => d.Taxes != null));
Its not working well.
then use ConstructUsing method for set child object to null when dto child object is null and also get full model by id when dto child object comes only with ID property.
for Construct Child object
e.g.
.ConstructUsing((Func<ResolutionContext, dao.TaxRate>)(rc=>
AutoMapperNHibernateFactory<dto.TaxRate, dao.TaxRate>.Create(rc)))
Construct method:
public class AutoMapperNHibernateFactory<dto, dao>
where dto : Dinerware.WebService.Public.DTO.Model
where dao : Dyno.DAO.Model, new()
{
public static dao Create(ResolutionContext rc)
{
Int64? Id = ((dto)rc.SourceValue).Id;
if (Id.HasValue && Id.Value > 0)
return DinerwareDaoController<dao>.GetModelById(((dto)rc.SourceValue).Id.Value);
return new dao();
}
}
It works well for dto child object null but not work with dto child object comes only with ID. Above method returns full object but not mapp properly. Thats why resulting child object only with ID.
Thanks in advance please suggest me what to do for,
SaveOrUpdate parent with child collection only when child is not null and Pass child with full model even child comes with only ID property.
You need to configure null destination values:
Mapper.AllowNullDestinationValues = true;
It will map nulls as null.

How to properly create two entities with cyclic dependency?

If I have two entities, Parent and Child, Parent needs to know about all of its Child children, and every Child instance needs to know about its parent Parent instance, how do I do this properly (in terms of DDD etc)?
The easy way would be to do parent.addChild(new Child(parent)), but this seems ugly - as well as:
parent.addChild(new Child()); // Then call some setParent method on child, which needs to be public
Do I need to use a factory here? And if so, how?
Thanks
One option would be to have a relevant instance method on the Parent class. A static Factory is probably not necessary here since you are operating on existing objects and simply need to connect object with another.
public class Parent {
// ...
public Child createChild() {
Child c = new Child(this);
this.addChild(c);
return c;
}
protected void addChild(c) {
// ...
}
// ...
}
public class Child {
public Child(Parent p) {
// ...
this.addParent(p);
}
protected addParent(Parent p) {
// ...
}
}
If the Child constructor needs arguments, you can pass those to the createChild method.
You are not limited to a single one approach. You should use the approach that fits you.
In SWT the child is linked to parent in constructor:
new Label(parentComposite, SWT.NONE);
After that parentComposite knows its child.
Note: SWT requires parent on creation which limits some functionality - you can't create child without specifying a child. This is limitation of the SWT.
In Swing you can create child widget and then add it to the parent.
Those above just the examples. Your personal solution will be based on your needs.
I would consider to use less methods, more consistency (don't leave your childs unlinked from parent)
Talking about code I would use following method:
Parent {
addChild(Child child) {
children.add(child);
child.setParent(this);
}
}
Hope that helps. Happy designing!
How about to do something like this:
public class Child {
Child (Parent parent) {
...
this.parent = parent;
parent.addChild(this);
}
}
So you can set parent to Child only while creating child.

NHibernate : Root collection with an root object

I want to track a list of root objects which are not contained by any element. I want the following pseudo code to work:
using (session1 = [...]) {
IList<FavoriteItem>list = session1.Linq<FavoriteItem>().ToList();
}
list.Add(item1);
list.Add(item2);
list.Remove(item3);
list.Remove(item4);
var item5 = list.First(i => i.Name = "Foo");
item5.Name = "Bar";
using (session2 = [...]) {
session2.Save(list);
}
This should automatically insert item1 and item2, delete item3 and item3 and update item5 (i.e. I don't want to call sesssion.SaveOrUpdate() for all items separately.
Is it possible to define a pseudo entity that is not associated with a table? For example I want to define the class Favorites and map 2 collection properties of it and than I want to write code like this:
using (session1 = [...]) {
var favs = session1.Linq<Favorites>();
}
favs.FavoriteColors.Add(new FavoriteColor(...));
favs.FavoriteMovies.Add(new FavoriteMovie(...));
using (session2 = [...]) {
session.SaveOrUpdate(favs);
}
FavoriteColors and FavoriteMovies are the only properties of the Favorites class and are of type IList and IList. I do only want to persist the these two collection properties but not the Favorites class.
Actually I want a IPersistentCollection object that tracks adds and removes that belongs to no parent entity and stands for itself (the same stuff that happens to collection properties of entities, only in my case I have no parent entity). This works perfectly well if the collections belong to an entity in which case I can add and remove items between two sessions.
Any help is much appreciated.
A simpler solution than a pseudo entity would be to wrap the list in an object that manages the things you want.
public class FavoriteList : IEnumerable
{
private List<FavoriteItem> list;
private ISession session;
public FavoriteList(ISession session)
{
list = session.Linq<FavoriteItem>().ToList();
this.session = session;
}
public void Add(FavoriteItem item)
{
session.SaveOrUpdate(item);
list.Add(item);
}
public void Remove(FavoriteItem item)
{
session.Delete(item); //or something like that
list.Remove(item);
}
public IEnumerator GetEnumerator()
{
return (list as IEnumerable).GetEnumerator();
}
}
I still have not found a real solution to this problem. My work around so far is that I have added the collection as a child collection property to another entity from which only one instance exists so far. But this solution breaks if there will be more instances of this entity and it has the disadvantage that the version of it is incremented every time a item is added or removed.
The other work around would have been to create a pseudo entity with no properties/columns (except an ID).
The third alternative I could think of is recreating the whole collection every time which is quite slow and does not work if other entities are referencing one of the items.
The last alternative would be to reimplement the dirty checking functionality myself but this would add some complexity and code duplication.
If somebody knows better alternatives I would be glad for any comments.

Nhibernate - how to delete children?

I'm working on a project with NHibernate that classes similar to the following:
public class Parent {
public IList Children {get;set;}
// ...
}
public class Child {
// ...
}
I've got the Children property set to cascade all / delete orphan. Since I'm using the aggregate pattern and instances of Child class will only ever be referenced in the context of a Parent, I don't have a ChildRepository to delete the children directly - only a ParentRepository. However, when I retrieve the Parent object and call Parent.Children.Clear(), the children from the database are never deleted. How can I achieve this?
Deleting child entities is this easy - just remove them from the collection and then save the parent entity. The collection should be mapped with all-delete-orphans.
parent.Children.Clear();
session.Save( parent );
// or
parent.Children.RemoveAt(0);
session.Save( parent );
You can do this without Save() calls as well, unless your FlushMode is Never.
session.BeginTransaction();
parent.Children.Clear();
session.Transaction.Commit();
Using #Chris's UnitOfWork abstractionm this could look like:
using (var uow = new UnitOfWork()) {
parent.Children.Clear();
}