-->
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.  [ 3 posts ] 
Author Message
 Post subject: Help with mapping a M:M on a legacy database
PostPosted: Thu May 31, 2007 7:40 pm 
Newbie

Joined: Thu May 31, 2007 6:52 pm
Posts: 6
Hibernate version: 1.2.0

Database: SQL Server 2005

I'm attempting to build out a business layer for a legacy application with a database running on SQL Server 2005. Unfortunately I cannot change any of the broken Database design concepts mentioned below. I just want to know if what I'm trying to do is possible?

I have a M:M relationship between 2 tables, and an associated table between them, defined like so.

Group
ID (GUID) PK
GroupID (char)

User
Login (char) PK
Name (char)

GroupMembers
ID (GUID) PK
GroupRef (GUID) FK
Login (char) FK

I'm trying to build a mapper file to map this into the following object representation in C#

Group
ID
GroupID
UserMemberships

User
Login
Name
GroupMemberships

The Mapper files look like this:

Group Mapper File:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
   <class name="Appframe.Business.System.Group, Appframe.Business" table="stbv_System_Groups">
      <id name="ID" column="ID" type="System.Guid" unsaved-value="00000000-0000-0000-0000-000000000000">
         <generator class="guid" />
      </id>
      <property name="GroupID" column="GroupID" not-null="true" />
      <bag name="UserMemberships" table="stbv_System_GroupsMembers" cascade="none" lazy="true">
         <key column="GroupRef" />
         <many-to-many column="Login" class="Appframe.Business.System.User, Appframe.Business" />
      </bag>
   </class>
</hibernate-mapping>


User Mapper File:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
   <class name="Appframe.Business.System.User, Appframe.Business" table="stbv_System_Users">
      <id name="Login" column="Login" type="string" unsaved-value="">
         <generator class="assigned" />
      </id>
      <property name="Name" column="Name" not-null="true" />
      <bag name="GroupMemberships" table="stbv_System_GroupsMembers" cascade="none" lazy="true">
         <key column="Login" />
         <many-to-many column="GroupRef" class="Appframe.Business.System.Group, Appframe.Business" />
      </bag>
   </class>
</hibernate-mapping>


The declaration of the UserMemberships property is like so:
Code:
      private IList<User> userMemberships = new List<User>();
      public virtual IList<User> UserMemberships
      {
         get { return new List<User>(userMemberships).AsReadOnly(); }
         protected set { userMemberships = value; }
      }


I'm following the example by Billy McCafferty posted on the Code Project as the bases for my business layer. So session handling is tied to the HTTP context etc...

I'm getting an error when I'm trying to bind my generic list of Groups to a datagrid like so:

Code:
      // Get a reference to the Data Access Object(DAO) factory
      ISystemDao systemDao = new SystemDao();
      // Using the DAO factory, get an instance to a new DAO for the Group object
      IGroupsDao groupsDao = systemDao.GetGroupsDao();
      
      // Use the Group DAO to call the database and retreive a list of Groups
      grdGroups.DataSource = groupsDao.GetAll();
      grdGroups.DataBind();



The above code produces the following error:

"Cannot insert duplicate key row in object 'dbo.stbl_System_GroupsMembers' with unique index 'IX_stbl_System_GroupsMembers'.
The statement has been terminated."

Is is possible the PrimaryKey column (ID) in the GroupMembers table is causing the issue?

Can anyone help me? Have I done something wrong, or do I need to structure my objects like they are in the database, with an association object between them?

Thanks in advance!


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 31, 2007 8:41 pm 
Regular
Regular

Joined: Sun Jan 21, 2007 4:33 pm
Posts: 65
Download MyGeneration Code Software (Google it), download the Gustavo Template (inside of MyGeneration), and let it look at your DB to create your mappings and classes. If it works, you'll know how your DB 'appears' to be mapped.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 01, 2007 4:06 pm 
Newbie

Joined: Thu May 31, 2007 6:52 pm
Posts: 6
As is the case most of the time, I think I solved my own problem... It seems that I need to define an "inverse" relationship, essentially one side of the Many-to-Many needs to own the relationship.

Also to answer my question about the fact that I have 2 foreign keys, and a GUID primary key on my association table, I discovered a <idbag> collection, where you can define an id column for the collection. So my original mapper files changed from this:
Code:
      <bag name="GroupMemberships" table="stbv_System_GroupsMembers" lazy="true" cascade="none" >
         <key column="Login"/>
         <many-to-many column="GroupRef" class="Appframe.Business.System.Group, Appframe.Business" />
      </bag>


To this:
Code:
      <idbag name="GroupMemberships" table="stbv_System_GroupsMembers" lazy="true" cascade="none" inverse="true" >
         <collection-id column="PrimKey" type="System.Guid">
            <generator class="guid" />
         </collection-id>
         <key column="Login"/>
         <many-to-many column="GroupRef" class="Appframe.Business.System.Group, Appframe.Business" />
      </idbag>


I still haven't tried to figure out the creates, updates, or deletes... but at least I have the reads working now.


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