views:

42

answers:

2

I am working on creating some grails domain objects dynamically and then adding them a SortedSet declared in another grails domain object. I have created a Project class, filled in its values, and checked to make sure it is valid. It is valid, so I want to add this Project to an Employee.

My code essentially goes like this

Employee employee = Employee.get(session.empid)
...
//populate some Project objects
...
//add projects to employee
employee.addToProjects(project)

What could be going wrong here? If I do a project.validate(), and then check for errors, the only one says that project has no valid employee associated with it - but that should go away once I do the employee.addToProjects. Employee hasMany Project objects, and it is declared like so:

class Employee implements Comparable
{
    static hasMany = [projects:Project]

    static constraints = 
    {
    }

    static mapping = {
        projects cascade:"all,delete-orphan", lazy:false
    }

    SortedSet<Project> projects = new TreeSet<Project>();
}


public class Project implements Comparable
{  
    static belongsTo = [employee:Employee]

    static hasMany = [roles:Role]

    static mapping = {
          roles lazy:false, cascade:"all,delete-orphan"
    }

    @XmlElement
    List<Role> roles = new ArrayList<Role>();


    /*
     * return sorted list.  overwriting default getter was causing error upon saving multiple roles.
     *
     */
    def List getSortedRoles(){
        Collections.sort(roles, new RoleComparator());
        return roles;
    }


    String toString()
    {
        return name
    }


    // compare by latest date of roles, then by name + id
    //if this is too intrusive, implement comparator with this logic and sort on rendering page
       int compareTo(obj) {
           if(obj == null){
               return 1;
           }

           def myMaxRole = findMaxRole(roles);
           def rhsMaxRole = findMaxRole(obj.roles);

           def rcomparator = new RoleComparator();

           System.out.println(myMaxRole.title + " " + rhsMaxRole.title + " " + rcomparator.compare(myMaxRole, rhsMaxRole));
           return rcomparator.compare(myMaxRole, rhsMaxRole);
       }

    def List getExpandableRoleList()
    {
        return LazyList.decorate(roles, FactoryUtils.instantiateFactory(Role.class));
    }


    def setExpandableRoleList(List l)
    {
        return roles = l;
    }

        def Role findMaxRole(roles){
            RoleComparator rc = new RoleComparator();

            Role maxRole = roles.first();
            for(role in roles){
                if(rc.compare(maxRole, role) > 0){
                    maxRole = role;
                }
            }

            return maxRole;
        }

public class Role implements Comparable
{

    static belongsTo = [project:Project]
    static hasMany = [roleSkills:RoleSkill,roleTools:RoleTool]

    static mapping = {
        duties type:"text"
        roleSkills cascade:"all,delete-orphan", lazy:false
        roleTools cascade:"all,delete-orphan", lazy:false

    }

    static contraints = {
        endDate(nullable: true)
    }

    boolean _deleted
    static transients = ['_deleted']

    @XmlElement
    String title = ""
    @XmlElement
    String duties = ""
    @XmlElement
    int levelOfEffort
    @XmlElement
    Date startDate = new Date()
    @XmlElement
    Date endDate = new Date()
    @XmlElement
    Date lastModified = new Date()
    @XmlElement
    LocationType locationType = new LocationType(type: "Unknown")
    @XmlElement
    String rank
    @XmlElement
    List<RoleSkill> roleSkills = new ArrayList<RoleSkill>()
    @XmlElement
    List<RoleTool> roleTools  = new ArrayList<RoleTool>()

    String toString()
    {   
        return title;
    }

    int compareTo(obj) {

        return title.compareTo(obj.title)
    }

    def skills() {
        return roleSkills.collect{it.skill}
    }
    def tools() {
        return roleTools.collect{it.tool}
    }
}
A: 

first() is part of groovy. calling first on an empty set will throw a no such element exception.

add the project to the employee and then try saving the employee.

try saving using code like:

if(!employee.save()) 
    employee.errors.allErrors.each {
        println it
    }

try removing the line : SortedSet projects = new TreeSet();

Ray Tayek
As far as I can tell, the exception happens on the line employee.addToProjects(proj) and it never makes it to the save() function.
Derek
also, when I took out the SortedSet line my table got fubar'd or something, and I had to re-create employee, because I got a DIFFERENT message about first() returning null on trying to load an employee
Derek
A: 

went back to basics and wrote an integration test using your objects and it all works fine, you error must be in how you are saving the objects

test snippet

void testSomething() {
    def emp = new Employee(first:"Aaron", last:"Saunders")
    emp.save()

    emp =  Employee.get(1)

    emp.addToProjects(new Project(name:"Project 3"))
    emp.addToProjects(new Project(name:"Project 1"))
    emp.addToProjects(new Project(name:"Project 2"))

    emp.save()

    println Employee.get(1)

    println Employee.get(1).projects.first()
}

my objects..

public class Project implements Comparable
{  
    static belongsTo = [employee:Employee]

    String name;

    static mapping = {
          roles lazy:false, cascade:"all,delete-orphan"
    }


    String toString()
    {
        return name
    }


    // compare by latest date of roles, then by name + id
    //if this is too intrusive, implement comparator with this logic and sort on rendering page
       int compareTo(obj) {
           if(obj == null){
               return 1;
           }


           return this.name.compareTo(obj.name);
       }

}

class Employee implements Comparable
{
    static hasMany = [projects:Project]

    String first, last
    static constraints = 
    {
    }

    static mapping = {
        projects cascade:"all,delete-orphan", lazy:false
    }

    SortedSet<Project> projects = new TreeSet<Project>();

    int compareTo(obj) {
        if(obj == null){
            return 1;
        }
           return this.name.compareTo(obj.name);
    }

}
Aaron Saunders
I will do a comparison of this and mine. I didn't post the creation of the Project objects, because there is more involved than what I posted, and I have to make several child objects to create a project
Derek