How to do unidirectional mapping of NHibernate to a single one?

This is a one-way, one-to-one mapping problem in NHibernate.

Student.cs

public class Student { public int ID { get; set; } public int Roll { get; set; } public int RegNo { get; set; } public string Name { get; set; } public StudentDetail StudentDetail { get; set; } } 

StudentDetail.cs

 public class StudentDetail { public int ID { get; set; } public string Father { get; set; } public string Mother { get; set; } } 

How can I map these classes (what does the hbm mapping file look like) in the following one-to-one relationship?

alt text

Please read the classes and table carefully.

Where can I put the <many-to-one> in Student.hbm.xml or StudentDetail.hbm.xml ? If I put it in Student.hbm.xml , how can I match the StudentDetail.StudentID column because it is in a different table?

So this mapping:

 <class name="Student" table="Student"> <id name="ID" column="ID"> <generator class="native"/> </id> ....... <many-to-one class="StudentDetail" name="StudentDetail" column="StudentID" unique="true" cascade="all" /> </class> 

throws the following exception:

 {"Invalid column name 'StudentID'."} 

On the other hand, <many-to-one> cannot be placed in StudentDetail.hbm.xml . Coz, StudentDetail.cs does not contain any property of type Student .

Can I use the <one-to-one> -tag? If so, where should I place it in Student.cs or StudentDetail.cs ? And how to configure it?

+7
nhibernate one-to-one
source share
2 answers

You can match it as a one-to-many relationship, and the collection property is hidden and only its first element is publicly open:

 public class Student { public virtual int ID { get; set; } public virtual int Roll { get; set; } public virtual int RegNo { get; set; } public virtual string Name { get; set; } protected virtual IList<StudentDetail> StudentDetails { get; set; } public virtual StudentDetail StudentDetail { get { if (StudentDetails.Count == 0) return null; return StudentDetails[0]; } set { if (StudentDetails.Count != 0) throw new Exception(); StudentDetails.Add(value); value.Student = this; } } } 

You can handle the setter better than this - you need to make sure that you are not adding multiple lines to one-to-many. Obviously, StudentDetails displayed in this, but StudentDetail not in your .hbm.xml or Fluent mappings.

+2
source share

Case No. 1:

In Student ...

 <one-to-one name="StudentDetail" cascade="save-update,delete" property-ref="Student" /> 

In StudentDetail ...

 <many-to-one name="Student" column="StudentID" unique="true" cascade="none" /> 

Note that you will need to have a property in your StudentDetail class that references an oobject for students (called Student). In addition, your cascades may vary depending on your use. You most likely want to remove the cascade there.

unique="true" provides a one-to-one mapping on the StudentDetail side.

Case No. 2:

Just exchange two mappings, making sure you change the property names to the opposite class.

For more information, contact: http://nhforge.org/blogs/nhibernate/archive/2009/04/19/nhibernate-mapping-lt-one-to-one-gt.aspx

+5
source share

All Articles