NHibernate Saving 0 to many-to-one column instead of null

I have a donation table that has a CampaignID column that refers to a campaign table. I need to insert 0 in the CampaignID column instead of Null if the Campaign is not used for this Donation.

My mappings from the Donations table are as follows:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true"> <class name="Donation,Entities" lazy="true" table="Donations" dynamic-update="true" > <id name="DonationID" column="PledgeID" type="Int64"> <generator class="native" /> </id> <many-to-one name="FundraisingCampaign" class="Campaign, Entities" column="CampaignID" lazy="proxy" not-found="ignore" cascade="none" /> 

Before I save the database, I check if the campaign object for my donation object is zero. If so, I set it for the new campaign object and set CampaignID = 0 like this.

  if (null == donation.FundraisingCampaign) { donation.FundraisingCampaign = new Campaign() {CampaignID = 0}; } 

The problem is that I get ErrorMessage "the object refers to an unsaved transient instance - saves the temporary instance before flushing." when trying to save.

I don’t understand why this excites anything in my Campaign object other than CampaignID, because I have cascade = "none", it should not try to save anything in the campaign table.

I force the current system to set 0 instead of Null instead, so saving Null is not an option.

+3
source share
2 answers

Try loading the campaign object whose database identifier is 0 from the database. This will be a fully permanent facility. Then you can install it and save the donation.

If this works, you need to change the display of the Campaign object's ID property. Nh cannot determine that your temporary campaign object is created here:

 new Campaign() {CampaignID = 0}; 

- actually a separate object. What you have to do is add an “unsaved value” to your display, for example -1. Now Nh can tell the difference between your actual standalone campaign with database id id 0 and transient new campaigns with id -1. Then remember to set the Id for the newly created campaigns to -1.

+3
source
  • NHibernate knows if an object has already been saved by checking the primary key. If it is 0, it is not saved. You can change this display behavior.
  • If you are trying to save an entity, all link objects must either be cascaded or already saved. It is important for NHibernate to use foreign keys. It cannot point to your memory with a foreign key; it must be in the database, so it must be saved. If this is not the case, you will receive an exception message.

With this information, you need to understand why you have a problem.

Is CampaignID with an automatic counter? Then it will not work. (You cannot set the identifier in the application.) If you did not save the Campaign with CampaignID = 0 (see below).

You can make CampaignID null int, and the unsaved default value is null.

Keep in mind that you get a Campaign with CampaignID = 0 in your database. This is a “null object”. You need to save it, for example, after setting up the database.

If you want to avoid a null object, you are having problems. NHibernate conceptually does not allow you to access foreign keys; it manages it for you. You can probably do some tricks (e.g. in the interceptor), but I think this is not worth the trouble. You should also make sure that there is no foreign key restriction, which is also not nice.

+2
source

Source: https://habr.com/ru/post/1336715/


All Articles