How to cascade save and delete of a non-collection entity? - sql

I have an entity A who has entity B.
Class Entity A
{
public EntityB;
}
Class Entity B
{
public Entity A;
}
Entity B has one to one relationship with A. I am trying to use cascade save,delete when entity A is saved so that I don't have to manually save entity B. It should be done automatically.
My mapping for entity B looks like:
<many-to-one name="EntityA" cascade="save-update"
column="EntityASomeProperty" class="EntityA" />
I not able to save entity B automatically when A is saved.

It looks like you have a cascade defined from B to A, so that when you save EntityB, EntityA should be saved.
If you want EntityB saved when you save EntityA, you'll need to have that configuration reversed. Note that you should pick a direction in which you want to manage this relationship and always work from that direction. You can map both directions, but make one inverse so that hibernate knows which direction you intend to manage it from.
I'd also suggest you use a OneToOne mapping, if that is what it really is.

Related

Configuring a N:N relationship with a lookup of source entity type on target entity

I'm trying to configure an N:N relationship from EntityA to EntityB. On EntityB, I have a lookup field of type EntityA.
Now, when I go back to an entity of type EntityA (say, named My Entity A) and add an existing EntityB in the subgrid, the look up field on EntityB is updated with My Entity A. Which is clearly not what I want.
I simply want to be able to tie any number of EntityB's to EntityA and I want EntityB to be able to point to any other EntityA on its look up field.
Is this possible ?
If you have a reference to entity A on Entity B then that is a N:1 relationship, not an N:N relationship. Check that you don't have more than on relationship between the entities, and it is defined as a N:N.

Get ID for a lazy many-to-one object withot database acces?

I wonder if this is possible,
i have a Class A with Id property of class B connected with lazy many-to-one relation.
And i want to get A.B.ID without connecting to database(For sure without loading whole B entity). Is is possible in NhibernatE?
A is many and b is One :)
Thx.
Yes this is the default behavior. If you retrieve A from the database then access A.B.Id this will not hit the database. If you access any other property besides the Id field it will cause NHibernate to retrieve B from the database.

Skip properties when calling session.Merge in NHibernate

I want to support cascade update of "truncated graphs" in NHibernate.
Say I have a Student entity and a Class entity which has a Students collection. The Students collection is mapped with "cascade all". Now, suppose that in the client only the a class entity was changed, so I want the client to be able to send only the class entity without the contained students. My approach is to let the client send the class entity with the Students property nullified and let the DAL understand that the Students collection should be ignored.
Unfortunately, when NHibernate gets null property class.Students when given to session.Merge, it disconnects the child students from the parent class by setting their FKs to null and/or deleting them (depending on the specific cascade option).
I would expect NHibernate to behave like that only when getting an empty collection and not when the collection is nullified.
Is there a way to workaround this? E.g. by telling NHibernate somehow to skip the nullified properties during merge?
You can set the inverse = "true" for the Student collection in the Class entity, so that it will not clear the FK.

Specifying the Table on a HasMany() relationship mapping in FluentNHibernate

I have a mapping in FluentNHibernate for a HasMany relationship and I'd like to specify a Table on it to override the default Table that nHibernate will look in to find those objects that I have many of. Does that make sense?
So lets say I have a table for Invoices and a table for InvoiceItems and lets say I have table called InvoiceItemsTwo.
I have a class for Invoice and a Class for InvoiceItems as well, and their mappings are pretty straight forward. I'd like to specify in my mapping for Invoice, that it should look for it's items in InvoiceItemsTwo instead of the default InvoiceItems.
So my mapping of that relationship looks like this
HasMany(c => c.InvoiceItems).Cascade.SaveUpdate().Table("InvoiceItemsTwo");
But this doesn't work. I keep getting an error from my website at runtime that says Invalid object name 'InvoiceItems'.
Why is it ignoring the fact that I am explicitly specifying the Table in my mapping on the relationship?
I tried dumping the mapping at run time and it's being setup something like this
<bag cascade="save-update" table="InvoiceItemsTwo">
Any ideas?
The table attribute applies only to many-to-many relationships, not one-to-many.
you can't specify a different table in your mapping class. Fluent NHibernate uses the class mapped on the property list (InvoiceItems).
If yoy want to use another class to map your details table you must create a InvoceItemsTwo class and map it in your master table class.
You could map the list as composite-element instead of a one-to-many relation and then map it to another table. But it is not a good idea. Consider that NH needs to know where to store an object which is in memory. So it may happen that the object is stored in the wrong table.
Either store all the InvoiceItems in separate tables using composite-element instead of one-to-many and components instead of many-to-one (however this is called in Fluent).
Or store all the InvoiceItems in the same table and use regular references.

Entity Framework 4, POCO, WCF, Updating Many-To-Many

I've got a many-to-many relationship mapped in my Entity Framework POCO classes. In the database it's a join table with a composite key, and the POCO properties are generated fine.
When I load an entity from the context, I can remove an item from the many-to-many collection and the database is updated when I save changes.
For Example:
var item = context.Items.First();
item.OtherItems.Remove(item.OtherItems[0]);
context.SaveChanges();
However, when the detached object graph comes back from WCF, I attach it to the context and mark it as modified. But the changes are not persisted.
Example:
// this happens on the silverlight client
item.OtherItems.Remove(item.OtherItems[0]);
// and on the server
context.Items.Attach(item);
context.ObjectStateManager.ChangeObjectState(item, EntityState.Modified);
context.SaveChanges();
In this case the record is not removed from the join table in the database. Any ideas how I can get this to work? Thanks very much in advance.
Changing object state marks your entity modified. You need to use ChangeRelationshipState to mark modified relation between two entities - this will perform DB modification on your join table. You will need to set relation's state as Added or Deleted.