Java – when using Grails sortedset, the first () element cannot be accessed from an empty list
I'm trying to dynamically create some Grails domain objects and then add a sortedset declared in another Grails domain object I created a project class, filled in its values, and checked to make sure it was valid It is valid, so I want to add this item to the employee
My code is basically like this
Employee employee = Employee.get(session.empid) ... //populate some Project objects ... //add projects to employee employee.addToProjects(project)
This could go wrong? If I execute project Validate (), and then check for errors, the only one that indicates that the project does not have a valid employee associated with it – but once I execute employee Addtoprojects should disappear Employee has many project objects. Its declaration is as follows:
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,lazy:false roleTools cascade:"all,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} } }
Solution
Go back to the basics and write an integration test with your object. Everything is normal. You must make an error in how to save the object
Test fragment
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 object
public class Project implements Comparable { static belongsTo = [employee:Employee] String name; static mapping = { roles lazy:false,delete-orphan" } String toString() { return name } // compare by latest date of roles,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,lazy:false } SortedSet<Project> projects = new TreeSet<Project>(); int compareTo(obj) { if(obj == null){ return 1; } return this.name.compareTo(obj.name); } }