Nhibernate to many-to-one task

I had a problem with many-to-one mapping in the following code:

...

<property name ="CustomerID"/> <!-- Many-to-one mapping: Customer --> <many-to-one name="Customer" class="Customer" column="CustomerID" insert="false" update="false"/> <property name="Date" /> 

...

You may notice that I have mapped two CustomerID tables to Customer. The reason I do this is because when I want to create an order, I simply assign the value CustomerID and other fields to require, and then save it. many-to-one, I just want to get the details of each client identifier.

But the problem is that: after I updated the Order and Executre SaveOrUpdate client ID with Session.Flush () as well (I use HibernateTemplate), I still got the old number when accessing Order.Customer. i.e:

Order = getOderByID (1);
Order.CustomerID = 3 // Suppose CustomerId is 1. Now I have changed to 3
SaveOrUpdate (order);
Print (Order.Customer.CustomerID) // returns 1, which is incorrect. It should be 3

Help Pls ...

Thanks,

+1
source share
3 answers

I would suggest you look at this problem from the perspective of NHibernate. And not from a relational database view. Let me begin with what I feel like you should do.

 var customer = session.Load<Customer>(3); var order = session.Load<Order>(1); order.Customer = customer; //assuming this is a one directional mapping. otherwise you might //have to do some more steps to disassociate the order from the old //customers collection and add it to the new customers collection session.SaveOrUpdate(order); 

Now order.Customer.CustomerID will return 3.

As suggested by Serkan, it is better and more advisable to work with objects instead of primary keys.

In addition, there really should not be any impact on performance. Nhibernate can proxy many associations if classes have virtual public methods. Because of this, as long as you request only the client Id, it will not generate a separate SQL query. An identifier already exists with the proxy object.

Regarding the initial question, I have a hunch. NHibernate dynamically generates an SQL query to update and insert. This case has an update here. You have explicitly set the CustomerID property to 3. But the Customer property of the order object still points to the customer object with Id 1. Thus, when NHibernate generates an SQL query, it tries to set the value first to 1, as you requested it to. Then it also sees that the Client is still pointing to the old object, so the reset property of the CustomerId is 1. I think NHibernate gets confused with double mappings.

There are two things you can do. First enable the show_sql property in your NHibernate configuration.

 <nhibernate> ... <add key="hibernate.show_sql" value="true" /> </nhibernate> 

Verify that sql is generated when the order is saved. This will better explain the situation.

Secondly, after saving the order, session.Refresh(order); You can read about the Refresh () method here . Its end to the end of section 9.2. It will reload the order object with the new values ​​from the database. Calling order.CustomerID should show what value you saved in the database.

+3
source

I think that in the long run you will feel much happier if you try to forget about the identifier of entities as soon as you are done with the OR mapping. You are on a different level, which you should only think about in objects. If I were you, I would completely destroy the CustomerId property.

If you have performance problems, try to solve them using NHibernate, caching, etc.

+1
source

Two things to try

  • Flushing a session with Session.Dispose if NH 2.x uses Flush()
  • Assign your customer ID.

NHibernate will create identifiers for you and try to manage them unless you specifically report it.

0
source

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


All Articles