-->
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.  [ 1 post ] 
Author Message
 Post subject: Ternary association using a map
PostPosted: Tue Jan 16, 2007 6:36 am 
Newbie

Joined: Tue Jan 16, 2007 5:27 am
Posts: 2
Hi all

I want to use a ternary assocation in combination with nhibernate. That means, i have three domain objects and four tables (one table per entity and one for the association).

I've read the user manual and several forum posts but i've found nowhere a detailed explanation about using and mapping ternary association in nhibernate.

The user manual only contains the following section:

--------------------------------------------------------------------------------
6.9. Ternary Associations

There are two possible approaches to mapping a ternary association. One approach is to use composite elements (discussed below). Another is to use a Map with an association as its index:

<map name="contracts" lazy="true">
<key column="employer_id"/>
<index-many-to-many column="employee_id" class="Employee"/>
<one-to-many column="contract_id" class="Contract"/>
</map>

<map name="connections" lazy="true">
<key column="node1_id"/>
<index-many-to-many column="node2_id" class="Node"/>
<many-to-many column="connection_id" class="Connection"/>
</map>
--------------------------------------------------------------------------------

With this few lines it's not completely clear how to work with a ternary association. For example how does the mapping know in which table to store the assocations?


In my case i've 3 entities:

Employee
BusinessLine
Right

In Employee i want to store a set of Right's which belongs to a specific BusinessLine. In the code i've the following:


Code:
....
private IDictionary m_businessLineRights;

public Employee() {
            m_businessLineRights = new Hashtable();
        }

public void AddRight(BusinessLine businessLine, Right right) {
            if (!m_businessLineRights.Contains(businessLine)) {
                m_businessLineRights.Add(businessLine, new HashedSet());
            }
            ((ISet)m_businessLineRights[businessLine]).Add(right);
        }

public ISet GetRightsByBusinessLine(BusinessLine businessLine) {
            if(m_businessLineRights.Contains(businessLine)){
                return ((ISet) m_businessLineRights[businessLine]);
            }
            return null;
        }
...




The mapping file looks like this:

...
<map name="BusinessLineRights" lazy="false">
<key column="EmployeeId"/>
<index-many-to-many
column="BusinessLineId"
class="Authorization.BusinessLine"/>
<many-to-many
column="RightId"
class="Authorization.Right"/>
</map>
...

--> For me it's not clear where to specify the assocation table. In my case it's called BusinessLineEmployeeRight and contains 3 foreign keys (EmployeeId, RightId, BusinessLineId)


The problem occurs in the flushing process:

...
Code:
BusinessLine businessLine = new BusinessLine("BL1");
Right right1 = new Right("Right1");
Right right2 = new Right("Right2);
employee.AddRight(businessLine, right1);
employee.AddRight(businessLine, right2);
session.Save(businessLine);
session.Save(right1);
session.Save(right2);
session.Save(employee);
session.Flush();

...

When i stepped through the nhibernate code with the debugger, i found out that the exception occurs in the class "NHibernate.Impl.Printer" in the method "ToString".

The whole exception stack trace looks like this:

at NHibernate.Property.BasicGetter.Get(Object target) in e:\VS_PROJECTS\ELCA\EL4NET\Public\1-Utilities\NHibernate\Property\BasicGetter.cs:line 45
at NHibernate.Persister.AbstractEntityPersister.GetIdentifier(Object obj) in e:\VS_PROJECTS\ELCA\EL4NET\Public\1-Utilities\NHibernate\Persister\AbstractEntityPersister.cs:line 304
at NHibernate.Proxy.NHibernateProxyHelper.GetIdentifier(Object obj, IClassPersister persister) in e:\VS_PROJECTS\ELCA\EL4NET\Public\1-Utilities\NHibernate\Proxy\NHibernateProxyHelper.cs:line 90
at NHibernate.Type.EntityType.ToString(Object value, ISessionFactoryImplementor factory) in e:\VS_PROJECTS\ELCA\EL4NET\Public\1-Utilities\NHibernate\Type\EntityType.cs:line 86
at NHibernate.Type.PersistentCollectionType.ToString(Object value, ISessionFactoryImplementor factory) in e:\VS_PROJECTS\ELCA\EL4NET\Public\1-Utilities\NHibernate\Type\PersistentCollectionType.cs:line 83
at NHibernate.Impl.Printer.ToString(Object entity) in e:\VS_PROJECTS\ELCA\EL4NET\Public\1-Utilities\NHibernate\Impl\Printer.cs:line 45
at NHibernate.Impl.Printer.ToString(IEnumerator enumerator) in e:\VS_PROJECTS\ELCA\EL4NET\Public\1-Utilities\NHibernate\Impl\Printer.cs:line 94
at NHibernate.Impl.SessionImpl.FlushEverything() in e:\VS_PROJECTS\ELCA\EL4NET\Public\1-Utilities\NHibernate\Impl\SessionImpl.cs:line 2890
at NHibernate.Impl.SessionImpl.Flush() in e:\VS_PROJECTS\ELCA\EL4NET\Public\1-Utilities\NHibernate\Impl\SessionImpl.cs:line 2843
at EL4Net.Transaction.NHibernate.NHTransactionScope.PreCompleteTransaction() in e:\VS_PROJECTS\ELCA\EL4NET\Public\2-Framework\EL4Net.Data.NHibernate\NHibernateTransactionScope.cs:line 90
at EL4Net.Transaction.LightweightTransactionScope.Complete() in e:\VS_PROJECTS\ELCA\EL4NET\Public\2-Framework\EL4Net.Data\Transaction\LightweightTransactionScope.cs:line 567
at TenderTracker.AuthorizationDataAccess.Save(Employee employee) in E:\VS_PROJECTS\ELCA\TenderTracker\TenderTracker.DataAccess\AuthorizationDataAccess.cs:line 99
at TenderTracker.AuthorizationDataAccessTest.TestSaveAndLoadEmployeeBusinessLineAndRight() in E:\VS_PROJECTS\ELCA\TenderTracker\TenderTracker.DataAccess.Tests\AuthorizationDataAccessTest.cs:line 109
--TargetException
at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
at NHibernate.Property.BasicGetter.Get(Object target) in e:\VS_PROJECTS\ELCA\EL4NET\Public\1-Utilities\NHibernate\Property\BasicGetter.cs:line 41


Could anyony help me with these issues? Thanks in advance.


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

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.