-->
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.  [ 7 posts ] 
Author Message
 Post subject: Parent Added to DB, but Contained Child Collection Isnt
PostPosted: Fri May 26, 2006 6:15 pm 
Newbie

Joined: Fri May 26, 2006 5:57 pm
Posts: 4
Ok, so when i create a new Account, the child Address doesnt get added to the DB. Only the Account does. The account_id -the foreign key of the address table- is created with a not null clause, but adding the "not-null" to the mapping didnt seem to fix the problem <:^|

Any ideas?

Thanks.
RM
Hibernate version:1.0.2.0

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

<class name="Hso.Accounts.Account,Hso" table="accounts">
<id name="Id" column="id">
<generator class="native"/>
</id>

<property name="UserName"/>
<property name="Password"/>
<property name="Lid"/>
<property name="Verified"/>

<property name="Email"/>
<property name="Created"/>

<bag name="Addresses" inverse="true">
<key column="account_id"/>
<one-to-many class="Hso.Accounts.Address,Hso"/>
</bag>

<bag name="Payments">
<key column="account_id"/>
<one-to-many class="Hso.Orders.Payments.Payment,Hso"/>
</bag>

</class>
</hibernate-mapping>



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

<class name="Hso.Accounts.Address,Hso" table="addresses">
<id name="Id" column="id">
<generator class="native"/>
</id>
<property name="FirstName"/>
<property name="LastName"/>
<property name="Address"/>
<property name="City"/>
<property name="State"/>
<property name="Zip"/>
<property name="Country"/>
<property name="IsDefault" column="default_address"/>
<many-to-one name="Account" class="Hso.Accounts.Account,Hso" column="account_id"/>

</class>
</hibernate-mapping>




Code between sessionFactory.openSession() and session.close():

Dim Am As IAccountManager = New AccountManagerImpl
Dim A As Account = New Account

Dim Addr As Address = New Hso.Accounts.Address
Addr.Address = "2224234"
Addr.City = "aaa"
Addr.State = "PA"
Addr.Zip = "123234"
Addr.Account = A
A.Addresses.Add(Addr)
A.Email = "qvvvv@notmail.com"
A.Password = "zzzzzzzzzzzzzz9"
A.UserName = "bass"


Try
Am.AddAccount(A)
A = Am.GetAccount("bass")
MessageBox.Show(A.ToString)
Catch Ce As Exception
MessageBox.Show(Ce.ToString)
End Try

Public Sub AddAccount(ByVal NewAccount As Account) Implements IAccountManager.AddAccount

Dim Q As IQuery
Dim List As IList
If IsNothing(NewAccount) Then Throw New ArgumentException("NewAccount is set to nothing")

Try

Session = Sf.OpenSession
Q = Session.CreateQuery("from Account as act where act.UserName = ? ")
Q.SetAnsiString(0, NewAccount.UserName)
List = Q.List

If List.Count > 0 Then Throw New AccountException("Username " & NewAccount.UserName & " already taken")

Q = Session.CreateQuery("from Account as act where act.Email = ?")
Q.SetAnsiString(0, NewAccount.Email)
List = Q.List

If List.Count > 0 Then Throw New AccountException("An account with the email address " & NewAccount.Email & " already exists")

'if not ValidateAccount(NewAccount) thr
Session.Save(NewAccount)

Finally
Session.Close()
End Try
End Sub



Name and version of the database you are using: MS SQL 2k



The generated SQL (show_sql=true):

NHibernate: select account0_.id as id, account0_.Verified as Verified, account0_.Email as Email, account0_.Lid as Lid, account0_.Created as Created, account0_.Password as Password, account0_.UserName as UserName from accounts account0_ where (account0_.UserName=@p0)
@p0 = 'bass'
'WindowsApplication1.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_32\System.Transactions\2.0.0.0__b77a5c561934e089\System.Transactions.dll', No symbols loaded.
'WindowsApplication1.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_32\System.EnterpriseServices\2.0.0.0__b03f5f7f11d50a3a\System.EnterpriseServices.dll', No symbols loaded.
NHibernate: select account0_.id as id, account0_.Verified as Verified, account0_.Email as Email, account0_.Lid as Lid, account0_.Created as Created, account0_.Password as Password, account0_.UserName as UserName from accounts account0_ where (account0_.Email=@p0)
@p0 = 'qvvvv@notmail.com'
NHibernate: INSERT INTO accounts (Verified, Email, Lid, Created, Password, UserName) VALUES (@p0, @p1, @p2, @p3, @p4, @p5); select SCOPE_IDENTITY()
@p0 = 'False'
@p1 = 'qvvvv@notmail.com'
@p2 = '0'
@p3 = '5/26/2006 12:00:00 AM'
@p4 = 'zzzzzzzzzzzzzz9'
@p5 = 'bass'
NHibernate: select account0_.id as id, account0_.Verified as Verified, account0_.Email as Email, account0_.Lid as Lid, account0_.Created as Created, account0_.Password as Password, account0_.UserName as UserName from accounts account0_ where (account0_.UserName=@p0)
@p0 = 'bass'
NHibernate: SELECT payments0_.account_id as account_id__, payments0_.id as id__, payments0_.id as id0_, payments0_.account_id as account_id0_ FROM payments payments0_ WHERE payments0_.account_id=@p0
@p0 = '0'
NHibernate: SELECT addresses0_.account_id as account_id__, addresses0_.id as id__, addresses0_.id as id0_, addresses0_.Country as Country0_, addresses0_.State as State0_, addresses0_.LastName as LastName0_, addresses0_.Address as Address0_, addresses0_.FirstName as FirstName0_, addresses0_.default_address as default_9_0_, addresses0_.City as City0_, addresses0_.account_id as account_id0_, addresses0_.Zip as Zip0_ FROM addresses addresses0_ WHERE addresses0_.account_id=@p0
@p0 = '0'


Debug level Hibernate log excerpt:
<?xml version="1.0" encoding="utf-8" ?>

<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
<section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>

<log4net>
<appender name="rollingFile" type="log4net.Appender.RollingFileAppender, log4net" >
<param name="File" value="log.txt" />
<param name="AppendToFile" value="true" />
<param name="RollingStyle" value="Date" />
<param name="DatePattern" value="yyyy.MM.dd" />
<param name="StaticLogFileName" value="true" />
<layout type="log4net.Layout.PatternLayout, log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] &lt;%X{auth}&gt; - %m%n" />
</layout>
</appender>
<root>
<priority value="DEBUG" />
<appender-ref ref="rollingFile" />
</root>
</log4net>

<nhibernate>
<add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
<add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect" />
<add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
<add key="hibernate.connection.connection_string" value="Server=192.168.191.66;Database=hso2;user id=sa;password=" />
<add key="hibernate.show_sql" value="true" />
</nhibernate>
</configuration>


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 26, 2006 7:58 pm 
Expert
Expert

Joined: Fri May 13, 2005 5:56 pm
Posts: 308
Location: Santa Barbara, California, USA
by default collections are mapped with cascade=none. try adding cascade=save-update to your Address association.


Top
 Profile  
 
 Post subject: Ok, that worked, thanks! But....
PostPosted: Tue May 30, 2006 3:22 pm 
Newbie

Joined: Fri May 26, 2006 5:57 pm
Posts: 4
Now, inorder to remove a child without having to explicitly call Session.Delete, one can set the cascade="all-delete-orphan" attribute, which will not only remove the link from child to parent, but also delete the child correct? Well, at any rate, once the child is removed from the collection and the parent is Updated, the association still remains.

Account.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
- <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" namespace="Hso" assembly="Hso">
- <class name="Hso.Accounts.Account,Hso" table="accounts">
- <id name="Id" column="id" unsaved-value="0">
<generator class="native" />
</id>
<property name="UserName" />
<property name="Password" />
<property name="Lid" />
<property name="Verified" />
<property name="Email" />
<property name="Created" />
- <bag name="Addresses" inverse="true" cascade="all-delete-orphan" order-by="shipping_address,default_address">
<key column="account_id" />
<one-to-many class="Hso.Accounts.Address,Hso" />
</bag>
- <bag name="Payments" inverse="true" cascade="all">
<key column="account_id" />
<one-to-many class="Hso.Orders.Payments.Payment,Hso" />
</bag>
</class>
</hibernate-mapping>



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

<class name="Hso.Accounts.Address,Hso" table="addresses">
<id name="Id" column="id" unsaved-value="0">
<generator class="native" />
</id>
<property name="Receiver" />
<property name="Address" />
<property name="City" />
<property name="State" />
<property name="Zip" />
<property name="Country" />
<property name="IsDefault" column="default_address" />
<property name="IsShipping" column="shipping_address" />
<many-to-one name="Account" class="Hso.Accounts.Account,Hso" column="account_id" />
</class>
</hibernate-mapping>


Code:
Public Sub UpdateAccount(ByVal Account As Account) Implements IAccountManager.UpdateAccount

Try
'ValidateAccount(Account)......
Session = Sf.OpenSession()
Session.Update(Account, Account.Id)
Catch ex As Exception
Throw New DatabaseException("Could not update account", ex)
Finally
Session.Close()
End Try



Dim A As Account
Dim Addr as Address
Dim Am As IAccountManager = New AccountManagerImpl

Try
A = Am.GetAccount("bass")
Addr = A.Accounts.Item(0)
Addr.Account = Nothing
A.Accounts.Remove(Addr)
Am.UpdateAccount(A)
Catch Ce As Exception
MessageBox.Show(Ce.ToString)
End Try
End Sub


Thanks Again!


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 30, 2006 6:09 pm 
Expert
Expert

Joined: Fri May 13, 2005 5:56 pm
Posts: 308
Location: Santa Barbara, California, USA
why is your AccountManager.UpdateAccount() method passing in the id of the object? the account is already persisted, no? usually the overloaded update method is called with the ID param when the entity you are trying to save is transient. are you sure the reference is removed from the collection before the account object is passed to the update method?

-devon


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 31, 2006 4:57 pm 
Newbie

Joined: Fri May 26, 2006 5:57 pm
Posts: 4
Hi devon,

I havent checked the elements in the list after the following:

Addr = A.Accounts.Item(0)
Addr.Account = Nothing
A.Accounts.Remove(Addr)

I cant see why the remove method wouldnt remove the object as useuall. I will do a sanity check on the collection when I return home. As for the update call with an Id, I wasnt aware there was a difference with the two calls. (well, aside from the args). I am attempting to update an object that already exists in the DB.

Thanks.......


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 03, 2006 6:19 pm 
Newbie

Joined: Fri May 26, 2006 5:57 pm
Posts: 4
As expected, the remove does indeed remone it from the collection, it just doesnt persist the changes to the DB. I tried the other version of update as well ( the one with out the "id" arg) and it doesnt work either.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 05, 2006 11:33 am 
Expert
Expert

Joined: Fri May 13, 2005 5:56 pm
Posts: 308
Location: Santa Barbara, California, USA
okay, not really sure what is going on but try this for a sanity check:

A.Accounts.Remove(Addr)
session.Delete(Addr);
session.Update(A);
session.Flush();
session.Close();

and let's see where we end up.

-devon


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