Retrieve all unsaved (detached) entities - entity

I am creating new entities but leaving them detached because I want to attach and save them later.
manager.createEntity("Employee", null, EntityState.Detached)
How can I retrieve all the added but detached entities from my entity manager? That is the entities I added that are in the cache but have not been saved?

You can't ask an EntityManager for detached entities because they are ... detached.
"Detached" means they don't belong to an EntityManager.
It is generally not a good idea to be modifying detached entities. You'll discover they don't behave like attached entities. For example, none of their navigation properties work ... for the simple reason that navigation properties look for related entities in the same EntityManager and this detached entity doesn't have an EntityManager.
I think you need to explain what motivated you to create these entities in a detached state. Why not leave them as "Added" (the default state)?
Perhaps you're worried about saving them prematurely? We can talk about how to guard against that.
Perhaps you're creating them but don't really want to save them until the user has made at least ONE change? We can talk about patterns to cover that.

Related

What is the use of entity's detach-method?

At the moment, I'm learning more about ORM and entity states and lifecycles.
I understand what a detached entity is and how an entity can get into detached state.
However, one thing I really don't understand:
What is the use of the detach()-method offered by an entity-manager?
I mean it's one thing for an entity to become detached e.g. after serialization/deserialization.
But why would one want an entity to become detached by explicitly calling the detach()-Method?
Does anyone have some examples of usefull scenarios?
It saves resources, so if you're going to have entities that are being used in a read only situation, you can detach them.

design pattern for managing object dependencies

I have to to find solution for the following problem :
I have a lot of model objects. Some model objects depend on other model objects. When the referenced model object changes dependents must be invalidated. I need to store list of my currently invalidated objects, so I can show it to the user and give him a chance to regenerate the objects if he wants to do that. The problem is how would I go with organizing and storing which dependencies an object has, and how to give and receive information when some object changes / become invalidated.
Someone can give idea , or maybe some similar pattern exists for this problem
Sounds like you need the Observer pattern:
The observer pattern (aka. Dependents, publish/subscribe) is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.

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: To-Many Relationship & Model

I'm considering using Core Data for an app I'm writing. However, after reading the docs I'm unsure how to model a particular relationship. Here's the basics:
I have an Entity called "ProjectFile" that has some basic string properties. (One of those is a path to a file on disk -- call it "File X" -- that my app is going to manipulate.) However, when the app manipulates file X, it may also need to manipulate OTHER files --- fileY and fileZ.
FileY and FileZ, like fileX, will be "ProjectFile" entities. So I need a way to tell Core Data "FileY and FileZ are associated with FileX." To do that, I created a relationship on the "ProjectFile" entity called "linkedFiles" and set the destination to "ProjectFile" and the inverse to "linkedFiles". I then set this as a "to-many" relationship, as each "ProjectFile" may have multiple linked files.
This seems recursive to me and I'm not sure I've done it correctly. The "linked" files (fileY and fileZ) need to exist on their own, just as fileX does. I need to be able to "delete" them from the "linkedFiles" relationship but still have them exist separately, if that makes sense. Essentially, I just need a weak relationship between separate objects in my model.
Have I done this correctly, or am I missing something? Thanks!
So, you have a data model that looks something like this:
ProjectFile{
path:string
infile<<-->>ProjectFile.infile
}
This will work because (1) Core Data relationships have directionality/cardinality and (2) each object is unique. Where you can get into trouble is with delete rules. You pretty much have to use No Action or Nullify in this circumstance or risk setting off a cascade delete. That in turn runs the risk creating orphaned objects that have no relationships and are hard to find and remove in the object graph.
A better model would encode more information in the relationships themselves. It appears that the real-world file objects you are modeling have two separate relationships to other file objects: (1) Each instance has other instances that it manipulates and (2) each instance has other instances that manipulate it. So, your model should reflect that:
ProjectFile{
path:string
toManipulateFiles<<-(nullify)->>ProjectFile.manipulatedByFiles
manipulatedByFiles<<-(nullify)->>ProjectFile.toManipulateFiles
}
This makes explicit the type relationship between the objects and lets you quickly and easily get the right objects for any particular operation. You can use Nullify on one relationship without orphaning the object on the other.
Although it isn't immediately obvious, relationships aren't just lines on a graphical model, they are actual live objects that can carry a lot of information. You need to design with this in mind.

NHibernate, DTOs and NonUniqueObjectException

We're using the DTO pattern to marshal our domain objects from the service layer into our repository, and then down to the database via NHibernate.
I've run into an issue whereby I pull a DTO out of the repository (e.g. CustomerDTO) and then convert it into the domain object (Customer) in my service layer. I then try and save a new object back (e.g. SalesOrder) which contains the same Customer object. This is in turn converted to a SalesOrderDTO (and CustomerDTO) for pushing into the repository.
NHibernate does not like this- it complains that the CustomerDTO is a duplicate record. I'm assuming that this is because it pulled out the first CustomerDTO in the same session and because the returning has been converted back and forth it cannot recognise this as the same object.
Am I stuck here or is there a way around this?
Thanks
James
You can re-attach an object to a session in NHibernate by using Lock - e.g.
_session.Lock(myDetachedObject, NHibernate.LockMode.None);
which may or may not help depending on exactly what is happening here. On a side note, using DTO's with NHibernate is not the most common practice, the fact that NHibernate (mostly) supports persistence ignorance means that typically DTO's aren't as widely used as with some other ORM frameworks.
It's really about how NHibernate session works. So if you within a session pull an instance of your CustomerDTO and then after a while you should get the same CustomerDTO (say by primary key) - you actually will get reference to the very same object like you did in your first retrieval.
So what you do is that you either merge the objects by calling session.Merge or you ask your session for the object by calling session.Get(primaryKey) do your updates and flush the session.
However as suggested by Steve - this is not usually what you do - you really want to get your domain object from the datastore and use DTOs (if neede) for transferring the data to UI, webservice whatever...
As others have noted, implementing Equals and GetHashCode is a step in the right direction. Also look into NHibernate's support for the "attach" OR/M idiom.
You also have the nosetter.camelcase option at your disposal: http://davybrion.com/blog/2009/03/entities-required-properties-and-properties-that-shouldnt-be-modified/
Furthermore, I'd like to encourage you not to be dissuaded by the lack of information out there online. It doesn't mean you're crazy, or doing things wrong. It just means you're working in an edge case. Unfortunately the biggest consumers of libraries like NHibernate are smallish in-house and/or web apps, where there exists the freedom to lean all your persistence needs against a single database. In reality, there are many exceptions to this rule.
For example, I'm currently working on a commercial desktop app where one of my domain objects has its data spread between a SQL CE database and image files on disk. Unfortunately NHibernate can only help me with the SQL CE persistence. I'm forced to use a sort of "Double Mapping" (see Martin Fowler's "Patterns of Enterprise Application Architecture") map my domain model through a repository layer that knows what data goes to NHibernate and what to disk.
It happens. It's a real need. Sometimes an apparent lack in a tool indicates you're taking a bad approach. But sometimes the truth is that you just truly are in an edge case, and need to build out some of these patterns for yourself to get it done.
I'm assuming that this is because it
pulled out the first CustomerDTO in
the same session and because the
returning has been converted back and
forth it cannot recognise this as the
same object.
You are right. Hibernate can't. Consider implementing Equals and Hashcode to fix this. I think a re-attach may only work if you haven't loaded the object within this session.