Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp
As per the
documentation on components and collections, I cannot get the following to work. However, if I change the mapping to cascade="all" and save the collection entities individually, I do not get an error. This is not the functionality that I wish to achieve.
The MappingException seems to be thrown because ComponentType returns false is IsEntityType (see line 265 in CollectionType.cs). Is the documentation wrong and this cannot be accomplished?
Any help is appreciated. Thank you.
Hibernate version: 1.2.0.CR1
Mapping documents:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="ClassLibrary1" namespace="ClassLibrary1" default-lazy="false">
<class name="Person">
<id name="Id" unsaved-value="0">
<generator class="identity"></generator>
</id>
<property name="Name"></property>
<bag name="Addresses" table="PersonAddresses" lazy="true" cascade="all-delete-orphan">
<key column="PersonId"></key>
<composite-element class="PersonAddress">
<property name="Description" not-null="false"></property>
<many-to-one column="AddressId" name="Address" not-null="true"></many-to-one>
</composite-element>
</bag>
<!--<list name="Addresses" table="PersonAddresses" lazy="true" cascade="all">
<key column="PersonId"></key>
<index column="AddressIndex"></index>
<composite-element class="PersonAddress">
<property name="Description" not-null="false"></property>
<many-to-one class="Address" column="AddressId" name="Address" cascade="delete-orphan" not-null="true"></many-to-one>
</composite-element>
</list> //lists, bags, etc. all break-->
</class>
<class name="Address">
<id name="Id" unsaved-value="0">
<generator class="identity"/>
</id>
<property name="City"></property>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
[TestFixture]
public class ComponentListMapping
{
ISessionFactory factory = null;
ISession session = null;
[SetUp]
public void TestSetup()
{
//BasicConfigurator.Configure(new ConsoleAppender(new SimpleLayout(), false));
factory = new Configuration()
.SetProperty("hibernate.connection.connection_string", "server=(local)\\sqlexpress;database=test;trusted_connection=yes")
.SetProperty("hibernate.connection.provider", "NHibernate.Connection.DriverConnectionProvider")
.SetProperty("hibernate.connection.driver_class", "NHibernate.Driver.SqlClientDriver")
.SetProperty("hibernate.show_sql", "true")
.SetProperty("hibernate.dialect", "NHibernate.Dialect.MsSql2005Dialect")
.SetProperty("hibernate.use_outer_join", "false")
.SetProperty("hibernate.hbm2ddl.auto", "create-drop")
.SetProperty("hibernate.query.substitutions", "true 1, false 0, yes 'Y', no 'N'")
.AddAssembly(typeof(ComponentListMapping).Assembly)
.BuildSessionFactory();
session = factory.OpenSession();
}
[Test]
public void CreateAndSave()
{
int id = 0;
using (ITransaction tx = session.BeginTransaction())
{
try
{
Address a1 = new Address();
a1.City = "Springfield";
//session.Save(a1);
Address a2 = new Address();
a2.City = "hbg";
//session.Save(a2);
Person p = new Person();
p.Name = "Homer Simpson";
PersonAddress pa = new PersonAddress();
pa.Address = a1;
PersonAddress pa2 = new PersonAddress();
pa2.Address = a2;
p.Addresses.Add(pa);
p.Addresses.Add(pa2);
//p.Addresses.Add(a1);
//p.Addresses.Add(a2);
id = (int)session.Save(p);
tx.Commit();
}
catch
{
tx.Rollback();
throw;
}
}
Assert.AreNotEqual(0, id);
Person p1 = session.Load<Person>(id);
Assert.IsNotNull(p1);
Assert.AreEqual(2, p1.Addresses.Count);
p1.Addresses.RemoveAt(1);
using (ITransaction tx = session.BeginTransaction())
{
try
{
session.SaveOrUpdate(p1);
tx.Commit();
session.Evict(p1);
}
catch
{
tx.Rollback();
throw;
}
}
p1 = session.Load<Person>(id);
Assert.IsNotNull(p1);
Assert.AreEqual(1, p1.Addresses.Count);
Assert.AreEqual(1, session.CreateCriteria(typeof(Address)).List<Address>().Count);
}
[TearDown]
public void TestTearDown()
{
session.Dispose();
factory.Dispose();
}
}
Full stack trace of any exception that occurs:
NHibernate.MappingException : collection was not an association: ClassLibrary1.Person.Addresses
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Type\CollectionType.cs(268,0): at NHibernate.Type.CollectionType.GetAssociatedClass(ISessionFactoryImplementor factory)
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Engine\Cascades.cs(691,0): at NHibernate.Engine.Cascades.CascadeCollection(CascadingAction action, CascadeStyle style, CollectionType collectionType, IType elemType, Object child, CascadePoint cascadeVia, ISessionImplementor session, Object anything)
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Engine\Cascades.cs(582,0): at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, Object child, IType type, CascadingAction action, CascadeStyle style, CascadePoint cascadeTo, Object anything)
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Engine\Cascades.cs(643,0): at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, IEntityPersister persister, Object parent, CascadingAction action, CascadePoint cascadeTo, Object anything)
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Impl\SessionImpl.cs(982,0): at NHibernate.Impl.SessionImpl.DoSave(Object theObj, EntityKey key, IEntityPersister persister, Boolean replicate, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything)
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Impl\SessionImpl.cs(872,0): at NHibernate.Impl.SessionImpl.DoSave(Object obj, Object id, IEntityPersister persister, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything)
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Impl\SessionImpl.cs(767,0): at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything)
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Impl\SessionImpl.cs(708,0): at NHibernate.Impl.SessionImpl.Save(Object obj)
C:\Documents and Settings\hboyce\Desktop\classlibrary1\Class1.cs(78,0): at ClassLibrary1.ComponentListMapping.CreateAndSave()
Name and version of the database you are using:
MS SQL Server 2005 / SQL Server Express 2005
The generated SQL (show_sql=true):
Quote:
NHibernate: INSERT INTO Person (Name) VALUES (@p0); select SCOPE_IDENTITY(); @p0 = 'Homer Simpson'
Debug level Hibernate log excerpt:Quote:
INFO - NHibernate 0.0.0.0 (FYI: I am referencing NH source in this test directly so AssemblyInfo.cs, etc. not being generated)
INFO - nhibernate section not found in application configuration file
INFO - Bytecode provider name : lcg
INFO - Using reflection optimizer
INFO - Found mapping document in assembly: ClassLibrary1.mapping.hbm.xml
INFO - Mapping resource: ClassLibrary1.mapping.hbm.xml
INFO - Using dialect: NHibernate.Dialect.MsSql2005Dialect
INFO - Mapping class: ClassLibrary1.Person -> Person
DEBUG - Mapped property: Id -> Id, type: Int32
DEBUG - Mapped property: Name -> Name, type: String
INFO - Mapping collection: ClassLibrary1.Person.Addresses -> PersonAddresses
DEBUG - Mapped property: Addresses, type: IList`1
INFO - Mapping class: ClassLibrary1.Address -> Address
DEBUG - Mapped property: Id -> Id, type: Int32
DEBUG - Mapped property: City -> City, type: String
INFO - processing one-to-many association mappings
DEBUG - Second pass for collection: ClassLibrary1.Person.Addresses
DEBUG - Mapped property: Description -> Description, type: String
DEBUG - Mapped property: Address -> AddressId, type: Address
DEBUG - Mapped collection key: PersonId, element: Description, AddressId, type: PersonAddress
INFO - processing one-to-one association property references
INFO - processing foreign key constraints
DEBUG - resolving reference to class: Address
DEBUG - resolving reference to class: Person
INFO - Using dialect: NHibernate.Dialect.MsSql2005Dialect
INFO - Initializing connection provider: NHibernate.Connection.DriverConnectionProvider
INFO - Configuring ConnectionProvider
INFO - Optimize cache for minimal puts: False
INFO - Connection release mode: auto
INFO - echoing all SQL to stdout
INFO - Query translator: NHibernate.Hql.Classic.ClassicQueryTranslatorFactory
INFO - Query language substitutions: {false=0, no='N', yes='Y', true=1}
INFO - cache provider: NHibernate.Cache.NoCacheProvider, NHibernate, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
INFO - building session factory
DEBUG - instantiating session factory with properties: {hibernate.dialect=NHibernate.Dialect.MsSql2005Dialect, hibernate.connection.connection_string=server=(local)\sqlexpress;database=test;trusted_connection=yes, hibernate.connection.driver_class=NHibernate.Driver.SqlClientDriver, hibernate.show_sql=true, hibernate.use_reflection_optimizer=true, hibernate.hbm2ddl.auto=create-drop, hibernate.use_outer_join=false, hibernate.connection.provider=NHibernate.Connection.DriverConnectionProvider, hibernate.query.substitutions=true 1, false 0, yes 'Y', no 'N'}
DEBUG - initializing class SessionFactoryObjectFactory
DEBUG - registered: 1243940ae6c84d50a2d7a68f9c46bcf4(unnamed)
INFO - no name configured
DEBUG - Static select for entity ClassLibrary1.Address: SELECT address0_.Id as Id2_0_, address0_.City as City2_0_ FROM Address address0_ WHERE address0_.Id=?
DEBUG - Static select for entity ClassLibrary1.Address: SELECT address0_.Id as Id2_0_, address0_.City as City2_0_ FROM Address address0_ WHERE address0_.Id=?
DEBUG - Static select for entity ClassLibrary1.Address: SELECT address0_.Id as Id2_0_, address0_.City as City2_0_ FROM Address address0_ with (updlock, rowlock) WHERE address0_.Id=?
DEBUG - Static select for entity ClassLibrary1.Address: SELECT address0_.Id as Id2_0_, address0_.City as City2_0_ FROM Address address0_ with (updlock, rowlock) WHERE address0_.Id=?
DEBUG - Static select for entity ClassLibrary1.Person: SELECT person0_.Id as Id0_0_, person0_.Name as Name0_0_ FROM Person person0_ WHERE person0_.Id=?
DEBUG - Static select for entity ClassLibrary1.Person: SELECT person0_.Id as Id0_0_, person0_.Name as Name0_0_ FROM Person person0_ WHERE person0_.Id=?
DEBUG - Static select for entity ClassLibrary1.Person: SELECT person0_.Id as Id0_0_, person0_.Name as Name0_0_ FROM Person person0_ with (updlock, rowlock) WHERE person0_.Id=?
DEBUG - Static select for entity ClassLibrary1.Person: SELECT person0_.Id as Id0_0_, person0_.Name as Name0_0_ FROM Person person0_ with (updlock, rowlock) WHERE person0_.Id=?
DEBUG - Static select for collection ClassLibrary1.Person.Addresses: SELECT addresses0_.PersonId as PersonId__1_, addresses0_.Description as Descript2_1_, addresses0_.AddressId as AddressId1_, address1_.Id as Id2_0_, address1_.City as City2_0_ FROM PersonAddresses addresses0_ inner join Address address1_ on addresses0_.AddressId=address1_.Id WHERE addresses0_.PersonId=?
DEBUG - Instantiated session factory
INFO - Using dialect: NHibernate.Dialect.MsSql2005Dialect
INFO - processing one-to-many association mappings
INFO - processing one-to-one association property references
INFO - processing foreign key constraints
DEBUG - resolving reference to class: Address
DEBUG - resolving reference to class: Person
INFO - processing one-to-many association mappings
INFO - processing one-to-one association property references
INFO - processing foreign key constraints
DEBUG - resolving reference to class: Address
DEBUG - resolving reference to class: Person
INFO - Initializing connection provider: NHibernate.Connection.DriverConnectionProvider
INFO - Configuring ConnectionProvider
DEBUG - Obtaining IDbConnection from Driver
DEBUG - alter table PersonAddresses drop constraint FK3756C2195EBFF014
WARN - Unsuccessful: alter table PersonAddresses drop constraint FK3756C2195EBFF014
WARN - Cannot find the object "PersonAddresses" because it does not exist or you do not have permissions.
DEBUG - alter table PersonAddresses drop constraint FK3756C219EC21280C
WARN - Unsuccessful: alter table PersonAddresses drop constraint FK3756C219EC21280C
WARN - Cannot find the object "PersonAddresses" because it does not exist or you do not have permissions.
DEBUG - if exists (select * from dbo.sysobjects where id = object_id(N'PersonAddresses') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table PersonAddresses
DEBUG - if exists (select * from dbo.sysobjects where id = object_id(N'Person') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Person
DEBUG - if exists (select * from dbo.sysobjects where id = object_id(N'Address') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Address
DEBUG - create table PersonAddresses (
PersonId INT not null,
Description NVARCHAR(255) null,
AddressId INT not null
)
DEBUG - create table Person (
Id INT IDENTITY NOT NULL,
Name NVARCHAR(255) null,
primary key (Id)
)
DEBUG - create table Address (
Id INT IDENTITY NOT NULL,
City NVARCHAR(255) null,
primary key (Id)
)
DEBUG - alter table PersonAddresses add constraint FK3756C2195EBFF014 foreign key (AddressId) references Address
DEBUG - alter table PersonAddresses add constraint FK3756C219EC21280C foreign key (PersonId) references Person
DEBUG - Closing connection
DEBUG - Disposing of ConnectionProvider.
INFO - Using dialect: NHibernate.Dialect.MsSql2005Dialect
INFO - processing one-to-many association mappings
INFO - processing one-to-one association property references
INFO - processing foreign key constraints
DEBUG - resolving reference to class: Address
DEBUG - resolving reference to class: Person
INFO - processing one-to-many association mappings
INFO - processing one-to-one association property references
INFO - processing foreign key constraints
DEBUG - resolving reference to class: Address
DEBUG - resolving reference to class: Person
DEBUG - opened session
DEBUG - begin
DEBUG - Obtaining IDbConnection from Driver
DEBUG - saving [ClassLibrary1.Person#<null>]
DEBUG - executing insertions
DEBUG - processing cascades for: ClassLibrary1.Person
DEBUG - done processing cascades for: ClassLibrary1.Person
DEBUG - Wrapped collection in role: ClassLibrary1.Person.Addresses
DEBUG - Inserting entity: ClassLibrary1.Person (native id)
DEBUG - Opened new IDbCommand, open IDbCommands: 1
DEBUG - Building an IDbCommand object for the SqlString: INSERT INTO Person (Name) VALUES (?); select SCOPE_IDENTITY()
DEBUG - Dehydrating entity: [ClassLibrary1.Person#<null>]
DEBUG - binding 'Homer Simpson' to parameter: 0
DEBUG - INSERT INTO Person (Name) VALUES (@p0); select SCOPE_IDENTITY(); @p0 = 'Homer Simpson'
NHibernate: INSERT INTO Person (Name) VALUES (@p0); select SCOPE_IDENTITY(); @p0 = 'Homer Simpson'
TestCase 'ClassLibrary1.ComponentListMapping.CreateAndSave'
failed: NHibernate.MappingException : collection was not an association: ClassLibrary1.Person.Addresses
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Type\CollectionType.cs(268,0): at NHibernate.Type.CollectionType.GetAssociatedClass(ISessionFactoryImplementor factory)
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Engine\Cascades.cs(691,0): at NHibernate.Engine.Cascades.CascadeCollection(CascadingAction action, CascadeStyle style, CollectionType collectionType, IType elemType, Object child, CascadePoint cascadeVia, ISessionImplementor session, Object anything)
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Engine\Cascades.cs(582,0): at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, Object child, IType type, CascadingAction action, CascadeStyle style, CascadePoint cascadeTo, Object anything)
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Engine\Cascades.cs(643,0): at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, IEntityPersister persister, Object parent, CascadingAction action, CascadePoint cascadeTo, Object anything)
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Impl\SessionImpl.cs(982,0): at NHibernate.Impl.SessionImpl.DoSave(Object theObj, EntityKey key, IEntityPersister persister, Boolean replicate, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything)
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Impl\SessionImpl.cs(872,0): at NHibernate.Impl.SessionImpl.DoSave(Object obj, Object id, IEntityPersister persister, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything)
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Impl\SessionImpl.cs(767,0): at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything)
C:\Documents and Settings\hboyce\My Documents\svn workspace\SourceForge\nhibernate\trunk\nhibernate\src\NHibernate\Impl\SessionImpl.cs(708,0): at NHibernate.Impl.SessionImpl.Save(Object obj)
C:\Documents and Settings\hboyce\Desktop\classlibrary1\Class1.cs(78,0): at ClassLibrary1.ComponentListMapping.CreateAndSave()
DEBUG - Opened IDataReader, open IDataReaders: 1
DEBUG - returning '1' as column:
DEBUG - Natively generated identity: 1
DEBUG - running NHybridDataReader.Dispose()
DEBUG - Closed IDataReader, open IDataReaders :0
DEBUG - Closed IDbCommand, open IDbCommands: 0
DEBUG - processing cascades for: ClassLibrary1.Person
DEBUG - cascading to collection: ClassLibrary1.Person.Addresses
DEBUG - rollback
DEBUG - running AdoTransaction.Dispose()
DEBUG - aggressively releasing database connection
DEBUG - Closing connection
DEBUG - transaction completion
DEBUG - running AdoTransaction.Dispose()
DEBUG - running ISession.Dispose()
DEBUG - closing session
DEBUG - running BatcherImpl.Dispose(true)
INFO - Closing
DEBUG - Disposing of ConnectionProvider.
INFO - Initializing connection provider: NHibernate.Connection.DriverConnectionProvider
INFO - Configuring ConnectionProvider
DEBUG - Obtaining IDbConnection from Driver
DEBUG - alter table PersonAddresses drop constraint FK3756C2195EBFF014
DEBUG - alter table PersonAddresses drop constraint FK3756C219EC21280C
DEBUG - if exists (select * from dbo.sysobjects where id = object_id(N'PersonAddresses') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table PersonAddresses
DEBUG - if exists (select * from dbo.sysobjects where id = object_id(N'Person') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Person
DEBUG - if exists (select * from dbo.sysobjects where id = object_id(N'Address') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Address
DEBUG - Closing connection
DEBUG - Disposing of ConnectionProvider.