Heym
I'm trying to map a legacy database system that we have internally
that we use to dynamically generate extraction statements from a
database. All of the tables use string identifiers and some of the
tables have composite keys. I've been trying an initial set of 4
tables and ran into a problem.
Basically, in my model a Relation has any Variables and a Variable can
exist on a Relation (although, the same variable name may be on two or
more relations ... don't ask!). We have Modules that consist of
Variables with some extra attributes attached for the Variable in the
module.
Here is my initial stab at the model:
Relation
[class]
public class Relation
{
public virtual string RelationId
{
get;
set;
}
public virtual ISet<Variable> Variables
{
get;
set;
}
public virtual DateTime LastUpdated
{
get;
set;
}
public Relation()
{
Variables = new HashedSet<Variable>();
}
public virtual void AddVariable(Variable variable)
{
Variables.Add(variable);
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
var other = obj as Relation;
if (other == null)
{
return false;
}
if (other.RelationId != this.RelationId)
{
return false;
}
return base.Equals(obj);
}
public override int GetHashCode()
{
return RelationId.GetHashCode();
}
[mapping]
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="STC.EI.Data"
namespace="STC.EI.Data.Entities">
<class name="Relation">
<id name="RelationId" type="string">
<generator class="assigned" />
</id>
<timestamp column="last_updated" name="LastUpdated"/>
<set name="Variables" inverse="true" cascade="save-update">
<key column="RelationId"/>
<one-to-many class ="Variable"/>
</set>
</class>
</hibernate-mapping>
Variable
[class]
public class Variable
{
public virtual string VariableId
{
get;
set;
}
public virtual Relation RelationId
{
get;
set;
}
public virtual DateTime LastUpdated
{
get; set;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
var other = obj as Variable;
if (other == null)
{
return false;
}
if (other.VariableId != this.VariableId)
{
return false;
}
if (other.RelationId != this.RelationId)
{
return false;
}
return true;
}
public override int GetHashCode()
{
return VariableId.GetHashCode();
}
}
[mapping]
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="STC.EI.Data"
namespace="STC.EI.Data.Entities">
<class name="Variable">
<composite-id>
<key-property name="VariableId" />
<key-many-to-one name="RelationId" />
</composite-id>
<timestamp column="last_updated" name="LastUpdated" />
</class>
</hibernate-mapping>
Module
[class]
public class Module
{
public Module()
{
Variables = new HashedSet<ModuleVariable>();
}
public virtual string ModuleId
{
get;
set;
}
public virtual ISet<ModuleVariable> Variables
{
get;
set;
}
public virtual DateTime LastUpdated
{
get;
set;
}
public virtual void AddVariable(ModuleVariable variable)
{
Variables.Add(variable);
}
}
[mapping]
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="STC.EI.Data"
namespace="STC.EI.Data.Entities">
<class name="Module">
<id name="ModuleId" type="string">
<generator class="assigned" />
</id>
<timestamp column="last_updated" name="LastUpdated"/>
<set name="Variables" table="ModuleVariable" cascade="save-update"
inverse="true">
<key column="VariableId" />
<one-to-many class="ModuleVariable"/>
</set>
</class>
</hibernate-mapping>
ModuleVariable (a variable for a module with attributes attached)
[class]
public class ModuleVariable
{
public virtual Module ModuleId
{
get;
set;
}
public virtual string VariableId
{
get;
set;
}
public virtual Variable DownloadId
{
get;
set;
}
public virtual Variable UploadId
{
get;
set;
}
public virtual string Repeatable
{
get;
set;
}
public virtual DateTime LastUpdated
{
get;
set;
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
var other = obj as ModuleVariable;
if (other == null)
{
return false;
}
if (other.ModuleId != this.ModuleId)
{
return false;
}
if (other.VariableId != this.VariableId)
{
return false;
}
return true;
}
public override int GetHashCode()
{
int hash = 13;
hash = hash + (this.ModuleId == null ? 0 :
this.ModuleId.GetHashCode());
return hash + (this.VariableId == null ? 0 :
this.VariableId.GetHashCode());
}
[mapping]
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="STC.EI.Data"
namespace="STC.EI.Data.Entities">
<class name="ModuleVariable">
<composite-id>
<key-many-to-one name="ModuleId" class="Module" lazy="proxy" />
<key-property name="VariableId" />
</composite-id>
<timestamp column="last_updated" name="LastUpdated"/>
<many-to-one name="DownloadId" class="Variable" cascade="save-
update">
<column name="DownloadId_VariableId"/>
<column name="DownloadId_RelationId"/>
</many-to-one>
<many-to-one name="UploadId" class="Variable" cascade="save-
update">
<column name="UploadId_VariableId"/>
<column name="UploadId_RelationId"/>
</many-to-one>
<property name="Repeatable"/>
</class>
</hibernate-mapping>
The problem occurs when I try this test:
[Fact]
public void CanAddNewModuleSuccessfully()
{
CreateSchema();
var relation = new Relation
{
RelationId = "PP01"
};
var downloadVariable = new Variable()
{
RelationId = relation,
VariableId = "AGEU"
};
var uploadVariable = new Variable()
{
RelationId = relation,
VariableId = "AGE"
};
relation.AddVariable(downloadVariable);
relation.AddVariable(uploadVariable);
var module = new Module
{
ModuleId = "DEI1"
};
var moduleVariable = new ModuleVariable()
{
ModuleId = module,
VariableId = "AGE",
UploadId = uploadVariable,
DownloadId =
downloadVariable,
Repeatable = "R"
};
module.AddVariable(moduleVariable);
using (var session = SessionManager.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
session.Save(module);
transaction.Commit();
}
}
}
I get a TransientObjectException like so:
NHibernate.HibernateException: NHibernate.HibernateException : There
is already an object named 'Variable' in the database.
---- System.Data.SqlClient.SqlException : There is already an object
named 'Variable' in the database.
C:\Dev\nhibernate-trunk\nhibernate\src\NHibernate\Tool\hbm2ddl
\SchemaExport.cs(302,0): at
NHibernate.Tool.hbm2ddl.SchemaExport.Execute(Action`1 scriptAction,
Boolean export, Boolean justDrop, Boolean format)
C:\Dev\nhibernate-trunk\nhibernate\src\NHibernate\Tool\hbm2ddl
\SchemaExport.cs(255,0): at
NHibernate.Tool.hbm2ddl.SchemaExport.Execute(Boolean script, Boolean
export, Boolean justDrop, Boolean format)
C:\Dev\STC.EI\STC.EI.Data\SessionManager.cs(48,0): at
STC.EI.Data.SessionManager.BuildSchema()
C:\Dev\STC.EI\STC.EI.Data.Test\ModuleVariable_Fixture.cs(15,0): at
STC.EI.Data.Test.ModuleVariable_Fixture.CreateSchema()
C:\Dev\STC.EI\STC.EI.Data.Test\ModuleVariable_Fixture.cs(21,0): at
STC.EI.Data.Test.ModuleVariable_Fixture.CanAddNewModuleSuccessfully()
----- Inner Stack Trace -----
at System.Data.SqlClient.SqlConnection.OnError(SqlException
exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException
exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning
(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior,
SqlCommand cmdHandler, SqlDataReader dataStream,
BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject
stateObj)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String
methodName, Boolean async)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery
(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
C:\Dev\nhibernate-trunk\nhibernate\src\NHibernate\Tool\hbm2ddl
\SchemaExport.cs(146,0): at
NHibernate.Tool.hbm2ddl.SchemaExport.Execute(Action`1 scriptAction,
Boolean export, Boolean format, Boolean throwOnError, TextWriter
exportOutput, IDbCommand statement, String sql)
C:\Dev\nhibernate-trunk\nhibernate\src\NHibernate\Tool\hbm2ddl
\SchemaExport.cs(206,0): at
NHibernate.Tool.hbm2ddl.SchemaExport.Execute(Action`1 scriptAction,
Boolean export, Boolean justDrop, Boolean format, IDbConnection
connection, TextWriter exportOutput)
C:\Dev\nhibernate-trunk\nhibernate\src\NHibernate\Tool\hbm2ddl
\SchemaExport.cs(292,0): at
NHibernate.Tool.hbm2ddl.SchemaExport.Execute(Action`1 scriptAction,
Boolean export, Boolean justDrop, Boolean format)
Note: I am using the NHibernate from the trunk (so 2.1.0Beta, I
believe) if this helps.
I am a little confused because the mapping is generated fine and if I
work with just Variables and Relations then the entire object graph is
persisted. It seems weird to me but I'm an NHibernate newbie so if
someone can offer some help it will be greatly appreciated!
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en
-~----------~----~----~----~------~----~------~--~---