For our test fixtures we use NHibernate to generate a database schema. We have a slight strange case in which an entity references a another entity but we don't wish to have a foreign key constraint (it should be possible to delete the referenced entity so a foreign key cannot be used).
Is it possible to specify that the generated schema does not have a foreign key for a particular relationship?
Jay-
If you're using Fluent NHibernate, you can set this in either your implementation of IHasManyConvention or IReferenceConvention (if using conventions).
Cascade.SaveUpdate() should propagate the saves and updates, but leave the orphaned child objects when the parents are deleted.
In standard NHibernate HBM files, I believe the tag for a bag should look like:
<bag cascade="save-update" name="EntityName"> ... </bag>
UPDATE: Here's an informational post by Ayende on the topic of orphaning child objects and the differences with the cascade values.
Related
Is there a way to map property with database column with custom column, that IS NOT a FK, just a candidate key ( it is unique for table )?
If not, what is my options here? (need to restrict select results with joined table restrictions)
NHibernate supports feature called property-ref. It is documented here: 5.1.10. many-to-one. Some extract:
The property-ref attribute should only be used for mapping legacy data
where a foreign key refers to a unique key of the associated table
other than the primary key. This is an ugly relational model. For
example, suppose the Product class had a unique serial number, that is
not the primary key. (The unique attribute controls NHibernate's DDL
generation with the SchemaExport tool.)
So, if the child table contains for example Guid, which is the same as in the target parent table... this could solve the issue. Example mapping:
<many-to-one name="Parent" property-ref="ParentGuid" column="THE_GUID_COLUMN"/>
Using the fluent syntax, it could look like this:
References(x => x.Parent)
...
.PropertyRef("ParentGuid")
.Column("THE_GUID_COLUMN");
Anyhow, this is not ideal and should be used mostly for solving legacy stuff.
Suppose I have a class Foo. I also have a view on Foo called Foo_Foo that lists a many-to-many association between Foos. I mapped this association as a simple immutable set on each Foo, with cascade="none":
<set name="association" table="Foo_Foo" cascade="none" mutable="false">
<key column="ParentFoo" />
<many-to-many class="Foo, MyAssembly" column="BaseFoo" />
</set>
However, when I try to delete a Foo, NHibernate tries and rightly fails to delete the Foo.association.
How can I prevent NHibernate from trying to delete the association to a view?
The collection belongs to Foo. You can't share the collection, so there is no need to keep it in the database. Cascade is used to tell NH if the referenced Foos should be also deleted or not.
Why do you want the Foo_Foo records to keep in the database? If this should be a bidirectional many-to-many self reference, it doesn't work like this.
Edit, after understanding the question.
Cascade doesn't work in your case, because it affects only the referenced Foos.
To avoid inserts / updates and deletes of the collection table, you may try one of the following:
First obvious attempt is mutable="false", which you already tried. I don't really understand why it isn't working. You may ask in the Nhibernate user group.
Less obvious, but promising is inverse="true". Inverse tells NH that the collection is mapped somewhere else and doesn't need to be stored from here. So it just omits inserts, but I don't know about deletes.
If this doesn't work, you need to explore more complex solutions. You could map it as a one-to-many of an intermediate entity which references the Foos. The intermediate entity is a mapping to the view. It is immutable (which still may lead to delete statements). In this case, cascade="false" will work (because it is the referenced entity). It will also work configure insert, update and delete sql statements (which are empty), but this is most probably not even necessary.
I define my data model using Fluent nHibernate POCO classes + mappings. I'm also using nHiberate schema to create database schema.
All is working fine but there is one unpleasent fact.
When I use many-to-one reference referece is named by something similair to GUID instead of any descriptive name.
Here's a piece of SQL:
alter table [Odbiorca]
add constraint FK291D244B5D9E8115
foreign key (Adr_IdKraj)
references [Kraj]
I want nHiberate to generate something like Sql Studio does like [FK_Odbiorca_Kraj].
Is it doable by overridding mappings or by creating any convention?
I don't know Fluent, but with regular XML mapping you just can use the foreign-key attribute:
<many-to-one
name="Kraj"
class="Kraj"
column="Adr_IdKraj"
foreign-key="FK_Odbiorca_Kraj"/>
I'm having a problem with a pretty simple setup in NHibernate. (I'm using Fluent Nhibernate)
I have two objects as follows, setup with a bi-directional many-to-many mapping.
Project
-- Categories (IList)
Category
-- Projects (IList) -- Inverse = True
This models as expected in the db.
If I try to delete a project NHibernate performs the delete in the many-to-many table then deletes the project as expected.
However, if I try to delete a category NHibernate throws an exception that it would violate a foreign key constraint.
I've experimentet with inverse="true" on both sides but the exception is thrown either when I try to delete a Project or a Category (depending on where inverse="true" is).If I remove inverse="true" from both sides the delete works as expected on either end. But this causes double entries when saving and updating.
Can anyone tell me where I am going wrong?
Is it possible that you're not synching up your entire object graph? The schema you show suggests that Project has a collection of Categories, and Category has a collection of Projects. Hibernate expects you to keep the associations in synch within your object graph. In order to delete a Category (for example), try first clearing its projects collection, and removing that category from the "categories" collections of any projects it was associated with.
I have some database tables named Project, Employee and Branch. An employee can work simultaneously on more than one project. Similarly, in a project, there are multiple employees. Also, a project is conducted at a particular branch. To maintain all these relationships, I am using a project_employee_branch table, which will store the related primary keys of the above three tables. As an example, this project_employee_branch table may contain a row like (1,2,3), which means the project whose primary key is 1, is conducted at branch whose primary key is 3, and one of its project member is an employee whose primary key is 2.
How can I map all these associations in NHibernate? I have mapped many-to-one association using foreign key concept, but I don't know how to map these types of associations, where an intermediate table is involved.
First point I'd make is that your database schema and your description don't match, so please take any advice below in the light of that initial caveat. You say that
a project is conducted at a particular branch
which implies there should be a simple foreign key relationship from project to branch. And of course, if this is what the schema looked like, you would have a two-way many-to-many link table and your life would be much easier.
Anyway, with the three-way combination you have, you need to have a collection of components, where the components have many-to-one properties for the other two object types. There is an example in section 7.2 of the NHibernate documentation, but I think it would look something like this in the mapping for Product:
<set name="BranchEmployees" table="product_employee_branch" lazy="true">
<key column="product_id">
<composite-element class="Purchase">
<many-to-one name="Branch" class="Branch" />
<many-to-one name="Employee" class="Employee"/>
</composite-element>
</set>