I work on a bug. I have a excel file that is imported into the application. The file contains information for the core domain object (Zoo, see below). Every row has two cells, string value for the name and int value for the number of animals.
If i have an invalid field inside this excel file, it will show an error msg like "Error on column X on cell Y. Value is "someValue" invalid". Let's assume we have an excel file with 250 rows. If we have an invalid field error on row 200, every row that comes after it will throw the following error
Validation error whilst flushing entity [com.rolotec.ost.Zoo]:
- Field error in object 'com.rolotec.ost.Zoo' on field 'ceo': rejected value [null]
If i look in the DB the object isn't null on ceo field.
Here the domain objects.
class Zoo{
String name;
int animalsInTheZoo;
CEO ceo;
hasMany=[ zooEnclosures : ZooEnclosures]
constraints=[//some constraints]
}
class CEO{
Date ceoTillDate;
Person person;
constraints=[//some constraints]
}
class Person{
String name;
int age;
constraints=[//some constraints]
}
Here is the service for the import
class ImportService{
importExcel(){
String errorMsg="";
Zoo.withTransaction { status->
try{
//some other operations
for(int rowNum = excelFile.firstRow; rowNum<=excelFile.lastRow; rowNum++) {
try {
importRow(row);
} catch (Exception e) {
//doSomething
}
} //end for-loop
if (errorMsg != "") {
status.setRollback();
}
} catch(Exception e){
//doSomething with e
status.setRollback();
}
}
}
importRow(Row row){
String name = row.getCell(1).stringCellValue;
Zoo.findAllByName(name).each{
try{
//reads every cell in Excel data and validates the field
it.save() //error occures here in the validation
} catch(Exception e){
//doSomething with e
}
}
}
If i inspect the object, it will have a value for it.ceo.name but the rest will be null inside it.ceo. Also will be the it.ceo.person = null. In the DB there are all values for the attributes.
EDIT: If there are no invalid fields inside the excel file, there are no ValidationException. Everything will be imported fine.
EDIT 2: Added the for-loop inside the importExcel() method.
The problem was, that inside the Zoo.withTransaction
closure was a for-loop which looped through all the rows inside the excel file. For the solution, we moved the .withTransaction
inside the for-loop and the problem was gone.
Code in ImportService looks now like this:
importExcel(){
String errorMsg="";
//some operations
for(int rowNum = excelFile.firstRow; rowNum<=excelFile.lastRow; rowNum++){
Zoo.withTransaction{status ->
//some operations
try{
importRow(row)
}
catch(Exception e){
//do something with exception
status.setRollbackOnly()
}
}
}
}