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.  [ 2 posts ] 
Author Message
 Post subject: link table
PostPosted: Fri Aug 19, 2005 10:54 am 
Regular
Regular

Joined: Fri Mar 04, 2005 1:33 pm
Posts: 65
Location: U.K.
Hibernate version: 2.1

Hi

I am using Hibernate 2.1 and have a question about a link table. I have tables EMPLOYEE, TASK and EMPLOYEE_TASK. The EMPLOYEE_TASK is a link table between EMPLOYEE and TASK. One employee can have many tasks and one task is allocated to many employees. If I get an object EMPLOYEE, do I need to fetch all its taks while I am in the session, so when I update employee object, it saves its all tasks too? While testing I found that if I do not deep fetch tasks, Hibernate thinks I deliberately made tasks set to null and it removes the records from the link table. Please let me know what to expect in this scenario.

Also does it makes a difference in following 2 scenarios:
1. If EMPLOYEE_TASK table has additional comlumn besides a composite key made of employee_id and task_id ?


2. If EMPLOYEE_TASK has only a composite key and no additional column ?

Thanks in advance.

Ron


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 19, 2005 2:48 pm 
Regular
Regular

Joined: Mon Jul 26, 2004 2:28 pm
Posts: 86
Location: Pensacola, Florida
With no other columns in the link table:

Code:
public class Employee
{
    private long _id = -1;
    private int _version = -1;
    private Set _tasks = new HashSet( );

    private void setId( long id ) { _id = id; }
    public long getId( ) { return _id; }

    private void setVersion( int version ) { _version = version; }
    private int getVersion( ) { return _version; }
   
    public void setTasks( Set tasks ) { _tasks = tasks; }
    public Set getTasks( ) return _tasks;

    public void addTask( Task task )
    {
        if( task != null ) _tasks.add( task );
    }
    public Task removeTask( Task task )
    {
        if( task != null ) _tasks.remove( task );
    }
}

public class Task
{
    private long _id = -1;
    private int _version = -1;
    private Set _employees = new HashSet( );
   
    private void setId( long id ) { _id = id; }
    public long getId( ) { return _id; }

    private void setVersion( int version ) { _version = version; }
    private int getVersion( ) { return _version; }

    public void setEmployees( Set employees ) { _employees = employees; }
    public Set getEmployees( ) return _employees;

    public void addEmployee( Employee employee )
    {
        if( employee != null ) _employees.add( employee );
    }
    public Employee removeEmployee( Employee employee )
    {
        if( employee != null ) _employee.remove( employee );
    }
}

<hibernate-mapping>
    <class name="Employee" table="employee">
        <id name="id" column="employee_id">
             <generator class="native"/>
        </id>

        <version name="version" column="version"/>
        <set name="tasks" inverse="false" cascade="all" lazy="true">
            <key column="employee_id"/>
            <many-to-many class="Task"/>
        </set>
</hibernate-mapping>

<hibernate-mapping>
    <class name="Task" table="task">
        <id name="id" column="task_id">
             <generator class="native"/>
        </id>

        <version name="version" column="version"/>
        <set name="employees" inverse="true" cascade="none" lazy="true">
            <key column="task_id"/>
            <many-to-many class="Employee"/>
        </set>
</hibernate-mapping>


In the above example, the tasks collection of an employee is saved when the employee is saved, but employees are not saved when a task is saved (note the inverse="true/false" on both mappings).

If you have other columns in your link table, then you will need to make a third class (EmployeeTask). In that case, it is recommended that you add a primary key column to the EMPLOYEE_TASK table so that you don't have a composite-key (they are a pain). Your Employee and Task classes would then have Sets of EmployeeTask objects that you would have to do some extra maintenance on:

Code:
public class Employee
{
    private long _id = -1;
    private int _version = -1;
    private Set _employeeTasks = new HashSet( );

    private void setId( long id ) { _id = id; }
    public long getId( ) { return _id; }

    private void setVersion( int version ) { _version = version; }
    private int getVersion( ) { return _version; }
   
    public void setEmployeeTasks( Set employeeTasks ) { _employeeTasks = employeeTasks; }
    public Set getEmployeeTasks( ) return _employeeTasks;

    public void addTask( Task task )
    {
        if( task != null )
        {
            EmployeeTask employeeTask = new EmployeeTask( );
            employeeTask.setEmployee( this );
            employeeTask.setTask( task );
            _employeeTasks.add( employeeTask );
        }
    }
    public Task removeTask( Task task )
    {
        if( task != null )
        {
            for( Iterator i = _employeeTasks.iterator( ); i.hasNext( ); )
            {
                EmployeeTask employeeTask = (EmployeeTask)i.next( );
                if( employeeTask.getTask( ).equals( task ) ) i.remove( );
            }
        }
    }
}

public class Task
{
    private long _id = -1;
    private int _version = -1;
    private Set _employeeTasks = new HashSet( );
   
    private void setId( long id ) { _id = id; }
    public long getId( ) { return _id; }

    private void setVersion( int version ) { _version = version; }
    private int getVersion( ) { return _version; }

    public void setEmployees( Set employees ) { _employees = employees; }
    public Set getEmployees( ) return _employees;

    public void setEmployeeTasks( Set employeeTasks ) { _employeeTasks = employeeTasks; }
    public Set getEmployeeTasks( ) return _employeeTasks;

    public void addEmployee( Employee employee )
    {
        if( employee != null )
        {
            EmployeeTask employeeTask = new EmployeeTask( );
            employeeTask.setTask( this );
            employeeTask.setEmployee( employee );
            _employeeTasks.add( employeeTask );
        }
    }
    public Task removeEmployee( Employee employee )
    {
        if( employee != null )
        {
            for( Iterator i = _employeeTasks.iterator( ); i.hasNext( ); )
            {
                EmployeeTask employeeTask = (EmployeeTask)i.next( );
                if( employeeTask.getEmployee( ).equals( employee ) ) i.remove( );
            }
        }
    }
}

<hibernate-mapping>
    <class name="Employee" table="employee">
        <id name="id" column="employee_id">
             <generator class="native"/>
        </id>

        <version name="version" column="version"/>
        <set name="employeeTasks" inverse="false" cascade="all" lazy="true">
            <key column="employee_id"/>
            <one-to-many class="EmployeeTask"/>
        </set>
</hibernate-mapping>

<hibernate-mapping>
    <class name="Task" table="task">
        <id name="id" column="task_id">
             <generator class="native"/>
        </id>

        <version name="version" column="version"/>
        <set name="employeeTasks" inverse="true" cascade="none" lazy="true">
            <key column="task_id"/>
            <one-to-many class="EmployeeTask"/>
        </set>
</hibernate-mapping>


The EmployeeTask class and mapping should be trivial.


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