problem mapping entities that have ID of type String.

1,098 views
Skip to first unread message

John

unread,
May 27, 2009, 4:40:36 PM5/27/09
to Fluent NHibernate
Hi i'm having a problem mapping entities that references other
entities that have a ID of type string.

The schemas for 3 tables, school references school system and that
references county:

School (
School_Id INTEGER primary key,
Name TEXT,
SchoolSystem_id INTEGER not null foreign key
)

SchoolSystem(
SchoolSystem_Id INTEGER primary key,
County_Name TEXT not null foreign key,
)

County (
County_Name TEXT not null primary key,
County_Number INTEGER not null,
)

-------------------------------------------------------------

Mapping classes:

public class CountyMap : ClassMap<County>
{
public CountyMap()
{
WithTable("County");
Id(x => x.Name, "County_Name");
Map(x => x.Number, "County_Number").Not.Nullable();
}
}

public class SchoolSystemMap : ClassMap<SchoolSystem>
{
public SchoolSystemMap()
{
WithTable("SchoolSystem");
Id(x => x.Id, "School_System_ID");
References(x => x.County, "County_Name").Not.Nullable()
.WithForeignKey("County_Name").FetchType.Join
().Cascade.All();
}
}

public class SchoolMap : ClassMap<School>
{
public SchoolMap()
{
WithTable("School");
Id(x => x.Id, "School_ID");
Map(x => x.Name, "School_Name");
References(x => x.SchoolSystem, "School_System_ID").Not.Nullable
()
.WithForeignKey("School_System_ID").FetchType.Join
().Cascade.All();
}
}

-----------------------------------------------------------------------------

And the entities:

public class County
{
public virtual string Name { get; set; }
public virtual int Number { get; set; }
}
public class SchoolSystem
{
public virtual int Id { get; set; }
public virtual County County { get; set; }
}
public class School
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual SchoolSystem SchoolSystem { get; set; }
}

---------------------------------------------------------------

Testing the mappings for County works:

new PersistenceSpecification<County>(session)
.CheckProperty(s => s.Name, "Thurston")
.CheckProperty(s => s.Number, 10)
.VerifyTheMappings();

Testing mapping for SchoolSystem fails:

new PersistenceSpecification<SchoolSystem>(session)
.CheckProperty(p => p.County, new County {Name = "SomeCounty",
Number = 10})
.VerifyTheMappings();

It throws an error. And it looks like it is because it is expecting
an insert instead of an update on County so it throws an exception:

INSERT INTO SchoolSystem (County_Name) VALUES (@p0); select
last_insert_rowid();
UPDATE luCounty SET County_Number = @p0 WHERE County_Name = @p1;

NHibernate.StaleStateException: Unexpected row count: 0; expected: 1.

---------------------------------------------------------------
Here are a few things i've tried.

I removed the county name from the test to try to get an insert.

new PersistenceSpecification<SchoolSystem>(session)
.CheckProperty(p => p.County, new County { Number = 10})
.VerifyTheMappings();

and get the exception:

NHibernate.Id.IdentifierGenerationException: ids for this class
must be manually assigned before calling save

So I tried to change the mapping of the CountyMap Id to be
GeneratedBy.Assigned and GeneratedBy.Identity but couldn't get my
mapping test to pass either. It works ok if i do not have the id as
type string but it is a string in the database so i dont think that
helps me any.

I'm out of ideas, am i doing something wrong. Any help would be
great. Thanks.

I also had a side question. I played around in making my domain
objects inherit from the fluent nhibernate Entity but that adds an
extra id to my db table schema, i don't quite understand how that
works.

James Gregory

unread,
May 27, 2009, 4:48:29 PM5/27/09
to fluent-n...@googlegroups.com
I'd seriously recommend using a surrogate key, not one that's got business meaning as you are now. If you can't alter your schema, then you need to use Assigned and, as the exception says, you have to set the value yourself before saving. Do your mappings work outside of the PersistenceSpecification? because it's not really designed to handle these special circumstances yet.
Reply all
Reply to author
Forward
0 new messages