ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Petr V." <greatman...@yahoo.com>
Subject Re: 2 Way 1-1 relationship
Date Wed, 21 Jan 2009 17:34:18 GMT
Thanks Ingmar Lötzsch for the reply.

Actually I was simplifying the context from 1-M to 1-1 for discussion so left groupBy attribute
mistakenly.

The problem at hand is that Teacher has students (1:M). Student must have some teacher assigned
to him but teacher does not necessarily need to have some student.

So I go ahead and load some teacher and it will load all students associated with it as Teacher
would have List<Student>. But what I want is that student also have a reference to Teacher.
Following code would explain what I want:

class Teacher {
   List<Student> students;
   ....
} 

class Student {
   Teacher teacher;
   ....
}

SQL Map config file 

<resultMap id="TeacherResultMap" class="Teacher" groupBy="id" >
    <result property="id" />
    <result property="name" />    
    <result property="students" resultMap="JOB.StudentResultMap"/>
</resultMap>

<resultMap id="StudentResultMap" class="Student" >
  <result property="id" column="stu_id"/>
  <result property="name" column="stu_Name"/>  
  <result property="teacher" resultMap="JOB.TeacherResultMap"/>    
</resultMap>


<select id="findTeacher"  parameterClass="int" resultMap="TeacherResultMap11">
    select t.id  , t.name , s.id as stu_id, s.name as stu_Name , s.tid as stu_tid from
Teacher t left join student s on t.id = s.tid where t.id = #value#
</select>

The line in red would make cyclic reference to associate teacher with student and stack overflow
so I can't do that but effectively I want to do that.

I understand your point where you tell me I could associate teacher for each student in business
logic but I am wondering if there is any way that both sides of relationship could hold a
reference of other side of relationship implicitly.

Thanks,

Petr



--- On Wed, 1/21/09, Ingmar Lötzsch <iloetzsch@asci-systemhaus.de> wrote:
From: Ingmar Lötzsch <iloetzsch@asci-systemhaus.de>
Subject: Re: 2 Way 1-1 relationship
To: user-java@ibatis.apache.org
Date: Wednesday, January 21, 2009, 4:38 PM

Petr V. schrieb:
> I want to have two way relationship like Teacher contains reference of
> Student and Student contains reference of Teacher. Is it even possible
> in iBatis ?
> 
> class Teacher {
>      Student sid;
>      ....
> }
> 
> class Student {
>      Teacher teacher;
>      ....
> }
> 
> 
> I wrote the following SQL config file and as expected I got stack over
> flow due to recursion.(Map referring each other)
> 
> <resultMap id="TeacherResultMap99" class="Teacher"
groupBy="id" >
>     <result property="id"   column="tea_id"/>
>     <result property="name" column="tea_name" />
>     <result property="sid"
resultMap="JOB.StudentResultMap99"/>
> </resultMap>
> 
> <resultMap id="StudentResultMap99" class="Student"
>
>   <result property="id" column="stu_id"/>
>   <result property="name" column="stu_Name"/>
>   <result property="teacher"
resultMap="JOB.TeacherResultMap99"/>   
> </resultMap>
> 
> 
> <select id="findStudent"  parameterClass="int"
> resultMap="StudentResultMap99">
>     select t.id as tea_id , t.name as tea_name , s.id as stu_id, s.name
> as stu_Name , s.tid as stu_tid from Teacher t left join student s on
> t.id = s.tid where s.id = #value#
> </select>

SELECT
	t.id AS tea_id,
	t.name AS tea_name,
	s.id AS stu_id,
	s.name AS stu_name,
	s.tid AS stu_tid
FROM teacher t
LEFT JOIN student s ON t.id = s.tid
WHERE s.id = #value#

I don't understand, why you use a LEFT JOIN to table student. You
provide the ID of the student as a parameter. If there exists a
corresponding row, you get a result, if not, you don't. You can use a
RIGHT JOIN instead, if there exist students without teacher.

If you have a real 1 to 1 relationship, omit the groupBy attribut and
the result element for property "sid". Otherwise use
List<Student> in
class Teacher.

StudentDAOImpl
{
	public Student findStudent(Integer id)
	{
		return (Student)
getSqlMapClientTemplate().queryForObject("<NAMESPACE>.findStudent",
id)	
	}
}

Somewhere in your business code you can write something like that:

Integer id = ...
Student student = this.studentDAO.findStudent(id);
if (student != null)
{
	Teacher teacher = student.getTeacher();
	if (teacher != null)
	{
		teacher.setStudent(student);
	}
}



      
Mime
View raw message