-->
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.  [ 5 posts ] 
Author Message
 Post subject: one-to-one mapping error on save
PostPosted: Thu Jun 16, 2005 6:06 pm 
Newbie

Joined: Thu Jun 16, 2005 5:53 pm
Posts: 9
Hi,

I am new to nhibernate and I have been trying to solve this for hours with no luck so I am hoping someone here can help me with this.

I have a simple one-to-one mapping from a User class to a SecretAnswer class. When I save the User object I expect a new User to be inserted into the Users table and then a new SecretAnswer to be inserted into another table.

The error I get is "SQL update or deletion failed (row not found)". When I look in the log I can see that nhiberante has attempted to execute an insert for the User object and then an update for the SecurityAnswer object. Obviously the update does not work because the row doesn't exist yet!

I expect 2 insert statements to be executed and I cannot work out why this is not happening.

Here are my mappings...

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
   <class name="MLT.Domain.User, MLT.Domain" table="Users">
      
      <id name="Id" column="UID" type="Guid">
         <generator class="guid" />
      </id>
      
      <property name="FirstName" column="firstName" type="String" length="50"/>
      <property name="LastName" column="lastName" type="String" length="50"/>
      <property name="Password" column="password" type="String" length="50"/>
      <property name="Username" column="Username" type="String" length="50"/>
      <property name="Email" column="email" type="String" length="255"/>
      <property name="CreationDate" column="creationDate" type="DateTime"/>
      <property name="AccountPrivate" column="PrivateStatus" type="Boolean"/>
      <property name="AccountActive" column="Active" type="Boolean"/>
      <property name="ReceiveCommentsEmail" column="ReceiveComments" type="Boolean"/>
      
      <one-to-one
         name="SecretAnswer"
         class="MLT.Domain.SecretAnswer, MLT.Domain"
         cascade="all"
         constrained="true"
         property-ref="UserId" />
   </class>
</hibernate-mapping>



Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
   <class name="MLT.Domain.SecretAnswer, MLT.Domain" table="SecurityAnswer">
      <id name="SecretAnswerId" column="SecurityAnswerID" type="Guid">
         <generator class="guid" />
      </id>
      <property name="UserId" column="UID" type="Guid" />
      <property name="QuestionId" column="QuestionID" type="Int32" />
      <property name="Answer" column="Answer" type="String" />
   </class>
</hibernate-mapping>


The code I am using to do the save is below...

Code:
User user = new User();
user.FirstName = firstName;
user.LastName = lastName;
user.Email = email;
user.Password = password;
user.AccountActive = false;
user.AccountPrivate = privateAccount;
user.CreationDate = DateTime.Now;
user.ReceiveCommentsEmail = receiveCommentsEmail;
user.Username = username;
//user.LastLogon = DateTime.Now;

SecretAnswer sa = new SecretAnswer();
sa.QuestionId = secretQuestionId;
sa.Answer = secretAnswer;
sa.UserId = user.Id;
sa.User = user;

user.SecretAnswer = sa;

userDAO.SaveNewUser(user);



Note that the UserDAO just calls session.Save() passing in the user object.

If someone can tell me what I am doing wrong that would be great. At the moment I have a work around which is to save the objects separately which I think is not a good solution.

[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 16, 2005 6:10 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
You have to specify unsaved-value="{000...00}" (a null guid) for the SecurityAnswer class.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 16, 2005 6:25 pm 
Newbie

Joined: Thu Jun 16, 2005 5:53 pm
Posts: 9
Thank's for the quick reply, that seems to have fixed that issue. But I have another one unfortunalely.

It seems it's now executing the two inserts, but in the wrong order (I need the user to be inserted first)...

INSERT statement conflicted with COLUMN FOREIGN KEY constraint 'FK_SecurityAnswer_Users'. The conflict occurred in database 'MLOT', table 'Users', column 'UID'. The statement has been terminated.

I must still have something wrong in the mapping but I am not sure what it is.

This is the code I am using for the save...

Code:
User user = new User();
user.FirstName = firstName;
user.LastName = lastName;
user.Email = email;
user.Password = password;
user.AccountActive = false;
user.AccountPrivate = privateAccount;
user.CreationDate = DateTime.Now;
user.ReceiveCommentsEmail = receiveCommentsEmail;
user.Username = username;
//user.LastLogon = DateTime.Now;

SecretAnswer sa = new SecretAnswer();
sa.QuestionId = secretQuestionId;
sa.Answer = secretAnswer;
//sa.UserId = user.Id;
sa.User = user;

user.SecretAnswer = sa;

userDAO.SaveNewUser(user);


Thank's for your help.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 16, 2005 7:19 pm 
Newbie

Joined: Thu Jun 16, 2005 5:53 pm
Posts: 9
Ok, I have figured out that setting constrained="false" in the User mapping will execute the inserts in the correct order...

Code:
<one-to-one
   name="SecretAnswer"
   class="MLT.Domain.SecretAnswer, MLT.Domain"
   cascade="all"
   constrained="false"
   property-ref="UserId" />



But there still seems to be a problem! I am getting the same error...

INSERT statement conflicted with COLUMN FOREIGN KEY constraint 'FK_SecurityAnswer_Users'. The conflict occurred in database 'MLOT', table 'Users', column 'UID'. The statement has been terminated.

It seems that after the user is inserted the newly inserted UID is not used for the 2nd insert for the SecretAnswer object.

Any ideas?


Top
 Profile  
 
 Post subject: Re: one-to-one mapping error on save
PostPosted: Wed Jul 06, 2005 7:05 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
lachlanj wrote:
The code I am using to do the save is below...

Code:
User user = new User();
user.FirstName = firstName;
user.LastName = lastName;
user.Email = email;
user.Password = password;
user.AccountActive = false;
user.AccountPrivate = privateAccount;
user.CreationDate = DateTime.Now;
user.ReceiveCommentsEmail = receiveCommentsEmail;
user.Username = username;
//user.LastLogon = DateTime.Now;

SecretAnswer sa = new SecretAnswer();
sa.QuestionId = secretQuestionId;
sa.Answer = secretAnswer;
sa.UserId = user.Id; // <-- look here
sa.User = user;

user.SecretAnswer = sa;

userDAO.SaveNewUser(user);



If you use the code above, then sa.UserId is going to have the default value (at the marked line user.Id is still zero). You should set the sa.UserId after you call Save on User. But since you use cascades it's going to be too late at that time, so instead try coding your sa.UserId property to return sa.User.Id.


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