views:

1998

answers:

4

I have 2 entities Person and Address, Person has one Address.

EDIT: The Address already exists, Im just wanting to save the foreign key.

When I do this:

  PersonDTO person = new PersonDTO();
    person.Age = "Bob";
    person.Address = new AddressDTO {Key = 123};
    Save(person);

I get this exception:

Cannot insert the value NULL into column 'Key', table 'Address'; column does not allow nulls. INSERT fails.The statement has been terminated.

Mapping file fragment from Person

<class name="PersonDTO" table="Person" xmlns="urn:nhibernate-mapping-2.2">
    <id name="Key" column="PersonKey" type="Guid">
      <generator class="guid" />
    </id>
    <one-to-one name="Address" class="AddressDTOl" />
  </class>

I don't understand why this happens, im giving Address Key a value. Is my approach flawed?

A: 

You should save the address before saving the person. Depending on the generator you may have to use the save overload that passes in the ID.

If you need the save to be implicit you should set the cascade of address property in the person.

Graham Ambrose
Sorry I wasnt clear the address already exists, I just want to save Person's link to an address.
Dan
Did you get the address with the same session that you are using to do the save? If not you need to join the address to the saving session.
Graham Ambrose
? Im not getting the address, in the example above I instantiate a new address with a know key. I also switched it so that it gets the full address object from the same session but i get the same error.
Dan
A: 

How did you map the Address in your person entity ? Did you specify cascading and the inverse attribute ?

On a side note: is Address an entity, or can you map the Address as a component ?

Frederik Gheysels
+1  A: 

You need to do this

AddressDTO add = new AddressDTO {Key = 123};
Save(add);

PersonDTO person = new PersonDTO();
person.Age = "Bob";
person.Address = add;
Save(person);

Or modify your mapping if you don't want to explicitly save Address :

<many-to-one name="Address" column="..." class="AddressDTO" cascade="save-update" />

If the address already exists, you need to get it from database :

PersonDTO person = new PersonDTO();
person.Age = "Bob";
person.Address = GetAddressDTO( 123 );
Save(person);
mathieu
Sorry I wasnt clear the address already exists, I just want to save Person's link to an address
Dan
A: 

Fixed it!

I changed my fluent nhibernate mapping, I used a References Relationship instead of HasOne.

This resulted in changing the mapping to this:

<many-to-one name="Address" column="AddressKey" />
Dan