-->
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.  [ 8 posts ] 
Author Message
 Post subject: Mapping a hierarchical relation
PostPosted: Sun May 14, 2006 5:50 pm 
Newbie

Joined: Sun May 14, 2006 5:20 pm
Posts: 6
Hello everyone!

I am building a small application and I have encountered a problem that I cannot overcome.

Lets see some SQL:
Code:
CREATE TABLE [dbo].[Categories](
   [Id] [bigint] IDENTITY(1,1) NOT NULL,
   [Name] [varchar](50) COLLATE Polish_CI_AS NOT NULL,
   [Description] [varchar](255) COLLATE Polish_CI_AS NULL,
CONSTRAINT [PK_Categories] PRIMARY KEY CLUSTERED
(
   [Id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[CategoriesTree](
   [CategoryId] [bigint] NOT NULL,
   [ParentCategoryId] [bigint] NOT NULL,
CONSTRAINT [PK_CategoriesTree] PRIMARY KEY CLUSTERED
(
   [CategoryId] ASC,
   [ParentCategoryId] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

ALTER TABLE [dbo].[CategoriesTree]  WITH CHECK ADD  CONSTRAINT [FK_CategoriesTree_Categories] FOREIGN KEY([CategoryId])
REFERENCES [dbo].[Categories] ([Id])
GO
ALTER TABLE [dbo].[CategoriesTree]  WITH CHECK ADD  CONSTRAINT [FK_CategoriesTree_Categories1] FOREIGN KEY([ParentCategoryId])
REFERENCES [dbo].[Categories] ([Id])

CREATE TABLE [dbo].[Products](
   [Id] [bigint] IDENTITY(1,1) NOT NULL,
   [ProducerId] [bigint] NOT NULL,
   [CategoryId] [bigint] NOT NULL,
   [Name] [varchar](50) COLLATE Polish_CI_AS NOT NULL,
   [Description] [text] COLLATE Polish_CI_AS NULL,
   [Price] [decimal](9, 2) NOT NULL,
   [Amount] [int] NOT NULL,
   [FromDate] [smalldatetime] NOT NULL,
CONSTRAINT [PK_Products] PRIMARY KEY CLUSTERED
(
   [Id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

ALTER TABLE [dbo].[Products]  WITH CHECK ADD  CONSTRAINT [FK_Products_Categories] FOREIGN KEY([CategoryId])
REFERENCES [dbo].[Categories] ([Id])
GO
ALTER TABLE [dbo].[Products]  WITH CHECK ADD  CONSTRAINT [FK_Products_Producers] FOREIGN KEY([ProducerId])
REFERENCES [dbo].[Producers] ([Id])


So, we have a categories tree (every category can have one parent and every category can have several children). Also every product has its category and a category has a list of products.

I created the following mapping:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" assembly="NCommercePersistence" namespace="NCommerce.Persistence">
   <class name="Category" table="CategoriesV">
      <id name="Id" column="Id" type="Int64">
         <generator class="identity"/>
      </id>
      <property name="Name" column="Name" type="String" length="50"/>
      <property name="Description" column="Description" type="String"/>
      <set name="Products" table="Products">
         <key column="CategoryId"/>
         <one-to-many class="Product"/>
      </set>
      <set name="ChildrenCategories" table="CategoriesTree">
         <key column="ParentCategoryId"/>
         <many-to-many column="CategoryId"  class="Category"/>
      </set>
      <many-to-one name="ParentCategory" column="ParentCategoryId"  class="Category"/>
   </class>
</hibernate-mapping>


CategoriesV is a view that returns a list of Id, Name, Description and ParentCategoryId. With that mapping file I am able to get data from the database without problems, but unfortunately I am unable to insert/update/delete because of the view (there is a JOIN inside). I tried to create an INSTEAD OF INSERT trigger for that view, but there is something wrong with my mapping and I am still unable to insert new records. I am sure that I did something wrong. And the worst thing is that I do not know what to change...
I can redesign the database schema, I can change classes and mapping file. I just need to get it working. Could any of you, please, help me with that? I spent long hours trying to correct it, but my experience with NHibernate is not enough to do it.
Well, I am not sure, but something tells me that this kind of hierarchical relation is unable to be mapped, when both ends of association are related to one class - Category. Could anyone, please, confirm or deny that? If it is true...what is the best way to solve this problem?

I would really apprieciate any help - all hints are welcome.

Hibernate version: 1.02

Name and version of the database you are using: MS SQL 2005 Developer

Thanks in advance.

Regards,
snake_net


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 14, 2006 6:47 pm 
Regular
Regular

Joined: Fri Jul 29, 2005 9:46 am
Posts: 101
Quote:
CategoriesV is a view that returns a list of Id, Name, Description and ParentCategoryId. [


Alright, first question: why did you just map you classes directly to the tables? I mean a class mapped to CategoriesTree would give you what you need...

I just don't see a need for a View here...


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 14, 2006 7:19 pm 
Newbie

Joined: Sun May 14, 2006 5:20 pm
Posts: 6
luxspes wrote:
Alright, first question: why did you just map you classes directly to the tables? I mean a class mapped to CategoriesTree would give you what you need...


Well, the answer is really simple. I am quite new to the NHibernate and OR mapping in general, therefore sometimes I try to do something just as newbie does - in a very uncommon way...

So, should I map my Category class not to the Categories table, but to the CategoriesTree?

Are there any tools helping with creating mapping files? I do not need a tool to generate SQL DDL or classes, but rather something to generate a mapping file when I have both tables and classes.

I also noticed a problem with using lazy collections. I get an error that the collection could not be lazily initialized. I will try to solve this by myself, because I am sure that there is a lot of people who had the same problem. For sure there are some posts on this forum... But if any of you could provide a sample code or link to it (how to use lazy collections) I would be really grateful.

Thanks for a very fast reply, luxspes.

Regards,
snake_net


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 14, 2006 10:10 pm 
Regular
Regular

Joined: Fri Jul 29, 2005 9:46 am
Posts: 101
Quote:
So, should I map my Category class not to the Categories table, but to the CategoriesTree?


IMHO you should map each of your tables to a particular class.

It seems to me that you want to use a "CategoriesV" to avoid joins and make things easier.. but with an O/R Mapper that is unnecesary because:

In CategoriesV you have:
Name, Description, Products, ChildrenCategories, ParentCategory

But, if you map each of your tables to its corresponden class then you can get all that data without a view:

CategoriesTree ct = this.Factories.CategoriesFactory.Get(0);
ct.Category.Name
ct.Category.Description
ct.Category.Products
ct.Parent.Category
ct.Children


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 15, 2006 12:56 am 
Regular
Regular

Joined: Tue Feb 21, 2006 9:50 am
Posts: 107
under performance considerations i prefer to use views if i have a join because they are in general precompiled and faster than dynamic SQL. But Views i strictly use readonly. Nevertheless i map all my tables to classes and use table mapping for inserts and updates.

If you want to generate table mappings and classes take a look at MyGeneration (http://www.mygeneration.com). This is a template based generator and it's freeware. There are predefined templates to generate NHibernate mappings and classes.

Regards
Klaus


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 15, 2006 5:51 am 
Newbie

Joined: Sun May 14, 2006 5:20 pm
Posts: 6
luxspes wrote:
IMHO you should map each of your tables to a particular class.


Well, I am not sure if this is possible. I cannot map Categories and CategoriesTree to their corresponding classes, because I need a situation, when one category has all its child categories, and each category points to its parent.
So, it is possible to have such tree:
|-computers
| |- new
| | |- notebooks
| | |- desktops
| |- used
|- PDAs

If I correctly understood your hint, I think that I would not be able to easily traverse tree both up (to the root) and down (to the leaves). I will just have a list of children categories and a parent category for every possible node in my hierarchy, but I would not be able to traverse the tree in the way I wrote above. Or, of course, I can be wrong.

luxspes wrote:
It seems to me that you want to use a "CategoriesV" to avoid joins and make things easier.. but with an O/R Mapper that is unnecesary because:


Well, not exactly. I just want to map my hierarchy to Category class or make it in other way, but I just need to be able to traverse the categories tree in both sides. I used a view only because I was unable, due to my lack of experience with NHibernate, to make it in other way.

luxspes wrote:
But, if you map each of your tables to its corresponden class then you can get all that data without a view:

CategoriesTree ct = this.Factories.CategoriesFactory.Get(0);
ct.Category.Name
ct.Category.Description
ct.Category.Products
ct.Parent.Category
ct.Children


There is something I am not sure about. If I made it as you wrote above, then I will have a list of children categories and, of course, a parent category. But both parent category and children categories will be of Category class so they will not have its parent and child categories. Am I right?
Or maybe you meant that I should make Children a CategoriesTree, and a Parent should only have a reference to its parent (not also to children)?

Anyway, thank you very much for your help.

Regards,
snake_net


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 15, 2006 5:58 am 
Newbie

Joined: Sun May 14, 2006 5:20 pm
Posts: 6
luedi wrote:
If you want to generate table mappings and classes take a look at MyGeneration (http://www.mygeneration.com). This is a template based generator and it's freeware. There are predefined templates to generate NHibernate mappings and classes.


I found their website -> http://www.mygenerationsoftware.com/.

Thank you very much for the link, I will check that tool. I think that this is what I looked for.

Regards,
snake_net


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 15, 2006 2:25 pm 
Newbie

Joined: Sun May 14, 2006 5:20 pm
Posts: 6
I think that I solved the problem. I need to test it in some particular situations, but for now I think that everything is ok.

Thanks once again for your help.

Best regards,
snake_net


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 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.