I can think of two "types" of object you're going to be associating:

1) items that "belong to" the item being archived
typical example could be Customer->Address (one-to-many)
The address belongs to the customer and no other Customer references
that address object

2) higher level "shared" items such as Customer->Branch (many-to-one)
multiple customers reference the same branch object.

Type 1 is fairly straight forward.
when you archive a Customer to create a CustomerAudit, manually run
through the list of addresses and create and attach corresponding
AddressAudit objects.
When you want to restore, again manually run through the list and
create corresponding Address objects for each AddressAudit. You're
creating new objects in both directions.

Type 2 is trickier and will very much depend on your use case. You
obviously don't want to keep overwriting your shared Branch object
every time you retrive an archived Customer version.

If all you need to to is reference the same Branch object and it
doesn't matter if it has changed, (maybe the branch address has
changed but the customer will still belong to that branch) then you
don't need to achive the Branch just retreive the id.

If you need to know what some value under Branch was at a particular
time (ie. Branch.NewCustomerDiscountRate) that will be more diffcult.
You could start archiving that Branch object to a BranchAudit but then
after retrieving from archive  you can no longer ask questions like
"does this customer belong to branch with id 16?" as you've had to
create a new branch object for that particular version/snapshot. You'd
have to check some property other than the id. You could quickly end
up effectively backing up the entire database every time you create a
new Customer version
Your other option is to extend customer to contain the fields you'll
need to archive.
>From my made-up example: NewCustomerDiscountRate is a property of
Branch but when you create a customer and assign it to a branch, copy
that value to Customer.NewCustomerDiscountRate. You can then change
Branch.NewCustomerDiscountRate  and this will be used for subsequent
new customers but any customer will retain the value as it was when
the Customer was created.

I personally do archiving/audit via SQL triggers to backup tables
(completely independently of NHibernate) but the archive is for
developer / CYA purposes only and I don't provide any user-level
features to restore from this archive.

Hope this helps,

Brendan Richards


On May 4, 4:05pm, thecubical <[email protected]> wrote:
> Hi guys,
>
> Started on an existing project at a new job and they use nhibernate.
> They want to implement versioning into the system which I'm having a
> bit of a nightmare trying to find a good way to do this.
>
> The idea is that users can create "ammendment packages" to various
> entities and after a review process the elements in a package will be
> applied to the live system at which point a new "system version" is
> created. The complexity comes in because the user is able to run the
> system at various versions as business rules state that versions of
> the system are still able to be used for up to 2 years after.
>
> I have come up with a workable database schema that should be able to
> hold the version data etc however the one thing that is doing my head
> in is figuring out how to version relationships or do it in such a way
> that we dont have to introduce extra queries everywhere in the app.
>
> For example take class A
>
> public class A : BaseObject
> {
>     public virtual string Title {get;set;}
>     public virtual string Description {get;set;}
>     public virtual B B {get;set;}
>
> }
>
> public class B: BaseObject
> {
>     public virtual string Title {get;set;}
>     public virtual string Description {get;set;}
>
> }
>
> In the database table A (model class A) has a one-to-many foreign key
> to table B (model class B).
>
> The way I've headed down so far is that for every entity/table that
> needs auditing we have a separate table "{name}Audit" that contains
> all of the same fields as {name} and a few more about various meta
> data we need to store about a version.
>
> When a user asks for a specific version we query the version table and
> return a {name}Audit object that inherits from the {name} entity and
> then convert it to a new {name} object by just newing up an instance
> of {name} and assigning the common properties across but not doing
> anything with the associations)
>
> The problem comes in with how we map the associations so that we only
> retrieve the associations as they were at a particular version and not
> how they currently are now. I have had a look at Envers and initially
> it looked quite good but unfortunately our model works differently
> where not every save must be audited as a new row, for instance an
> ammendment can go through several updates before being accepted (and
> we don't care about the inbetween audits of the ammendment itself),
> also it doesn't currently support collections of components.
>
> So ultimately (if the pile of drivel about made no sense) I'm looking
> for some advice on how to handle associations in the context of a
> version of an entity without having to only ever return ids of
> associations and constantly ask for what that association was a X
> explicitly.

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to