Reputation: 6742
I have a very similar situation to what's described in this question:
Engineer
and Manager
both inherit from Contact
, and Engineer
can be promoted (or demoted, depending on your perspective) to Manager
.
difference is- I log all orders submitted by a contact.
meaning- my Contact
class has a IList<Order> Orders
property, which can consist of 100,000s of orders. (before you ask- obviously this property isn't ever loaded into memory, it's just the opposite end of the Contact OrderSubmitter
property of Order
).
I like the idea of a 'copy constructor' of sort, suggested by @Jamie Ide.
the question is- can I change the referemce of the Order
objects without loading them to memory?
[EDIT]
yes, I can- using HQL update.
However, this creates a different problem- I'm trying to create an entity and have other entities referencing it in the same transaction. meaning:
Manager manager = new Manager(engineer);
session.Save(manager);
session.CreateQuery("update Order set OrderSubmitter = :manager where OrderSubmitter = :engineer")
.SetParameter("manager",manager)
.SetParameter("engineer",engineer)
.ExecuteUpdate();
session.Transaction.Commit();
however- the ExecuteUpdate occurs immidiately, whereas the Manager
entity is only saved on 'commit'.
This, of course, results in a foreign key exception.
I can get around it by explicitly calling session.Flush()
right after the Save(manager)
call, but that doesn't seem very good practice.
any ideas?
Upvotes: 0
Views: 279
Reputation: 31
The real problem is that your modeling is incorrect. In OO an object does not change its type. The Manager/Engineer should be modeled as One-To-One relationship. You can have a job class as a component property of Employee. Than when an employee is promoted from engineer to manager, you only have to replace the component. Also - you won't have to update the orders table, as the submitter remains the same. The only difference is its job component
Upvotes: 1
Reputation: 49261
As you stated, the problem is that ExecuteUpdate() occurs immediately and isn't issued after the new manager is inserted. I think that calling session.Flush() immediately is the right solution. You should also delete the original engineer object in the same transaction.
See also the answer to this question.
Upvotes: 0