-->
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.  [ 6 posts ] 
Author Message
 Post subject: Problem with Map and IDictionary
PostPosted: Sun Jun 26, 2005 3:15 am 
This is my first time with NHibernate, but I've been playing with this for a number of hours and can't seem to find anything in either the docs or on the board archives. I'm having a problem getting a one-to-many association working with a Map/IDictionary. Here's my domain:

- A patient has a collection of phone numbers. Each number has a type (home, work, etc.) I would like to have Patient expose a "PhoneNumbers" collection, indexable by type.

I have defined a Patient class and a PhoneNumber class. For patient, I have the following in the hb.xml to define the 1..* relationship:

<map name="PhoneNumbers" table="PhoneNumber" cascade="all" access="nosetter.camelcase-underscore">
<key column="Type"/>
<index column="PhoneNumberKey" type="Int32" />
<one-to-many class="PhoneNumber, MyAssembly" />
</map>

And in the PhoneNumber hb.xml I have:

<many-to-one name="PatientKey" column="PatientKey" class="Patient, MyAssembly" cascade="none" />

Originally I had intended to index the IDictionary by an enum of PhoneNumberType (work, home, etc.) When I encountered this exception:

>>
NHibernate.ADOException : Could not save object
----> NHibernate.ADOException : Could not save object
----> System.ArgumentException : There is a problem with your mappings. You are probably trying to map a System.ValueType to a <class> which NHibernate does not allow or you are incorrectly using the IDictionary that is mapped to a <set>.

A ValueType can not be used with IdentityKey. The thread at google has a good description about what happens with boxing and unboxing ValueTypes and why they can not be used as an IdentityKey: http://groups.google.com/groups?hl=en&l ... 26tab%3Dwg
Parameter name: key
<<

I figured the <key/> element was the problem. I updated the schema for the phone number type to be an nvarchar and retried with no success. I haven't found many examples of using the map element anywhere, so I'm likely overlooking something.

Tomorrow I'll try using IList instead as there are more examples of this, but I'd like the indexer lookup if possible in my model. Any help is appreciated.

Thanks!


Top
  
 
 Post subject:
PostPosted: Sun Sep 25, 2005 4:36 pm 
Newbie

Joined: Sun Sep 25, 2005 4:35 pm
Posts: 3
I'm having the same issue. Did you ever resolve this?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 25, 2005 5:00 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Post your class declarations and mappings, we'll have a look.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 25, 2005 6:40 pm 
Newbie

Joined: Sun Sep 25, 2005 4:35 pm
Posts: 3
My mapping is as follows:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" namespace="myNamespace"
assembly="myAssembly">

<class name="SampleAccount" table="SampleAccount">
<id name="AccountKey" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="assigned"/>
</id>
<version name="Version" unsaved-value="0"/>
<property name="AccountName" not-null="true"/>
<map name="Opportunities" table="SampleOpportunity"
cascade="all-delete-orphan" lazy="false" inverse="true">
<key column="AccountKey"/>
<index column="OpportunityName" type="System.String"/>
<one-to-many class="SampleOpportunity"/>
</map>
</class>

<class name="SampleOpportunity" table="SampleOpportunity">
<id name="OpportunityKey" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="assigned"/>
</id>
<version name="Version" unsaved-value="0"/>
<many-to-one name="AccountKey" class="SampleAccount" column="AccountKey" not-null="true">
</many-to-one>
<property name="OpportunityName" not-null="true"/>
</class>
</hibernate-mapping>

Here are my classes (I've ripped out all the impertinent code):

[Serializable]
public class SampleAccount : ADomainEntity, IDomainEntity, ISampleAccount
{
private string accountName = "";
private Guid accountKey;
private ISampleOpportunityCollection opportunities;
private IDictionary opportunitiesShadow = null;

public SampleAccount() : base()
{
opportunities = (ISampleOpportunityCollection) new SampleOpportunityCollection
}

public virtual string AccountName
{
get { return accountName; }
set
{
accountName = value;
}
}

public virtual Guid AccountKey
{
get { return accountKey; }
set
{
accountKey = value;
}
}



public virtual ISampleOpportunityCollection Opportunities
{
get { return opportunities; }
set
{
this.opportunitiesShadow = null;
opportunities = value;
}
}

private IDictionary OpportunitiesShadow
{
get
{
if (this.opportunitiesShadow == null)
return this.opportunities;
else
return this.opportunitiesShadow;
}
set { this.opportunitiesShadow = value; }
}

}

[Serializable]
public class SampleOpportunity : ADomainEntity, IDomainEntity, ISampleOpportunity
{
private string opportunityName = "";
private Guid opportunityKey;
private Guid accountKey;

public SampleOpportunity() : base()
{
this.ResetDirtyFlags();
}

public virtual string OpportunityName
{
get { return opportunityName; }
set
{
opportunityName = value;
}
}


public virtual Guid OpportunityKey
{
get { return opportunityKey; }
set
{
opportunityKey = value;
}
}


public virtual Guid AccountKey
{
get { return accountKey; }
set
{
accountKey = value;
}
}

}


My collection ISampleOpportunityCollection is a strongly-typed class derived from DictionaryBase. I'm using a shadow copy (an IDictionary) to map with NHibernate.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 25, 2005 7:13 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Well, the Opportunities property is specified as this in the mapping:
Code:
<map name="Opportunities" ...>...</map>

This means you should have an Opportunities property of type IDictionary. But you have Opportunities of your own type, and that's probably what is causing the problem. I don't really understand what you're doing with the shadow property, but you probably should use that property in the mappings instead of Opportunities.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 25, 2005 8:02 pm 
Newbie

Joined: Sun Sep 25, 2005 4:35 pm
Posts: 3
Sorry, I do have it set to the shadow property. I just copied it into the reply incorrectly.

<map name="OpportunitiesShadow" table="SampleOpportunity"
cascade="all-delete-orphan" lazy="false" inverse="true">
<key column="AccountKey"/>
<index column="OpportunityName" type="System.String"/>
<one-to-many class="SampleOpportunity"/>


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