-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: Can this mapping be done with (Fluent) NHibernate?
PostPosted: Sat Nov 29, 2008 6:32 pm 
Newbie

Joined: Sat Nov 29, 2008 6:30 pm
Posts: 8
I have an Events table whose goal is to store actions done by web site users. An action basically alters or create a new row in a table X. This will allow me to store an history of all actions done by a user. As such, Events contains:

* a primary key column
* a text to describe the event (ex: "posted a comment")
* a discrimator column if needed
* a foreign key column to another table A
* a foreign key column to another table B
* ....
* a foreign key column to another table N

A row in the Events table will have only one of the foreign key columns set, all others will be null (so they are all nullable). The table behaves like an indirection table to the actual table concerned by the event. I don't know if a discriminator is needed since all the information is contained in the foreign key columns. Tables A to N can be anything. Their domain model class can have a common interface if necessary (IEventRecordable).

My question is: Is a mapping possible between the Events table and an Event class? Is it especially feasible with fluent nhibernate? Can it be done without having to create many derived classes of Event (I don't want to create so many empty subclasses)? The Event class would ideally be as follows:

public class Event
{
public virtual int Id { get; set; }
public virtual IEventRecordable ActualEvent { get; set; }
public virtual string EventDescription { get; set; }
DateTime EventDateTime { get; set; }
}

Many classes among the domain model classes could implement IEventRecordable (which is mainly an empty interface). It could be the User table or a BlogComment table...

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 29, 2008 7:46 pm 
Newbie

Joined: Sat Nov 29, 2008 6:59 pm
Posts: 19
Location: Burlington, VT
I would create a view that returned the type (or table name) that is linked from your Events table. Map the view to the Event class and create a method to return the linked entity now that you know its type and id.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 29, 2008 8:22 pm 
Newbie

Joined: Sat Nov 29, 2008 6:30 pm
Posts: 8
Thanks for your answer. However I'm new to all those things and your explanation is like chinese to me. Can you elaborate, give some details? Thank you.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 01, 2008 4:00 pm 
Newbie

Joined: Sat Nov 29, 2008 6:59 pm
Posts: 19
Location: Burlington, VT
Create a view that uses a case statement to return the table name and id for the foreign key column in use:

Code:
select id,
case
   when ColA is not null then 'TableA'
   when ColB is not null then 'TableB'
   -- etc.
end as TableName,
case
   when ColA is not null then ColA
   when ColB is not null then ColB
   -- etc.
end as EntityId
from Events


Map that to your Event class. Create a method on your event class to load the IEventRecordable:

Code:
public virtual IEventRecordable GetEventRecordable()
{
switch (TableName)
{
case "TableA":
   session.Get(typeof(EntityA), EntityId);
  break;
case "TableB":
  session.Get(typeof(EntityB), EntityId);
  break;
// etc.
}
}


It's ugly but any solution will be ugly due to the structure of your events table. If it's a new application, I would structure your Events table to store TableName, ForeignKey instead of N columns. I wouldn't worry about enforcing foreign keys on an audit table.

Hope this helps.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 01, 2008 4:18 pm 
Newbie

Joined: Sat Nov 29, 2008 6:30 pm
Posts: 8
Thank you, I understand what you mean now.
But what about the session in the "Event" domain model class? I have no session there. No way to do otherwise?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 04, 2008 11:16 am 
Newbie

Joined: Sat Nov 29, 2008 6:59 pm
Posts: 19
Location: Burlington, VT
I thought you might ask about that. I would map the TableName in your Event class and create a read-only property that returned Type using a switch statement. Then your UI code or a repository could load the referenced object using the type and id from your Event class.

There might be a better way: Use the view to turn your FK columns into a discriminator. You can map an interface in NHibernate and use the discriminator to return the object. I haven't tried this but it might work.


Top
 Profile  
 
 Post subject: Re:
PostPosted: Mon Jun 27, 2011 8:55 am 
Newbie

Joined: Wed Jun 15, 2011 5:18 am
Posts: 2
greenmtboy wrote:
Create a view that uses a case statement to return the table name and id for the foreign key column in use:

...

It's ugly but any solution will be ugly due to the structure of your events table. If it's a new application, I would structure your Events table to store TableName, ForeignKey instead of N columns. I wouldn't worry about enforcing foreign keys on an audit table.

Hope this helps.


hi sorry if this thread is too old, but i am interested on how to the mapping like quoted above. how do i define mapping for events table that is related to many tables (hence many entities), and is discriminated by the column "TableName".


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.