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);
}
}
