|
Think I've just encountered a similar problem.
In my case the legacy database contains orphaned foreign keys. e.g. class Report { Person author Person subject } Where the Report table contains person keys for rows in the Person table that don't exist. Fetching Reports and eagerly fetching their Person typed fields, I get an exception: Caused by: org.hibernate.ObjectNotFoundException: No row with the given identifier exists: ... Would like an easy way to just ignore these cases (so the unmatched Person typed fields would just contain null) e.g. static ignoreNotFound = ["author", "subject"] Checking over my code, it turns out that it was a lazy fetch of the Person typed fields.
Aplogies for posting this piecemeal. While I thought I was using lazy loading for this field (as I'd never specified for it to be eagerly fetched) it turns out that lazy loading wasn't possible as it is a one-to-many (so same as one-to-one from its point of view) nullable field.
The fact it is nullable prevents hibernate from putting a proxy there and it thus might as well try and populate it. This conceptual limitation for Hibernate is explained properly here: http://www.hibernate.org/162.html#A3 However, all this just means I still need to be able to specify something like: static ignoreNotFound = ["author", "subject"] As a workaround will have to see if the db can be cleaning up dba's persuaded to add constraints. |
|||||||||||||||||||||||||||||||||||||||||||||
class Project implements Comparable
{
String name;
Person intPerson;
Person extPerson;
String isCompany;
Date begindate;
Date enddate;
static hasMany = [currentUsers:Person, subprojects:Project]
static belongsTo = [parentProject:Project]
static mappedBy = [currentUsers:"lastProject"]
static constraints = {
name(blank:false, nullable:false, size:1..100)
parentProject(nullable:true, validator: {return (true)}) //nullable:false,
isCompany(blank:false, inList:["Y","N"])
begindate(attributes:[precision:"day", years:"${2008..2015}"])
enddate(attributes:[precision:"day", years:"${2008..2015}"])
fullName(editable:false)
}
static mapping = { version false currentUsers column:'FK_PROJECT_ID' intPerson column:'FK_INT_PERSON_ID', lazy:true extPerson column:'FK_EXT_PERSON_ID', lazy:true parentProject column: 'FK_PARENT_PROJECT_ID', lazy:true subProjects column: 'FK_PARENT_PROJECT_ID', lazy:true }
static fetchMode = [parentProject:"lazy",subProjects:"lazy"]
static transients = ['fullName']
public int compareTo(Object o) { return getFullName().toLowerCase().compareTo(o.getFullName().toLowerCase()) }
String toString() {
return getFullName() + " (ID:${id})"
}
String getFullName() {
def s =""
if (isCompany.equals("N") && (id != 0)) {
if ((parentProject)
&& (parentProject.id >= 0)) { s = parentProject.getFullName() + "/" }
}
s += name
}
}
The exception is:
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: Project#-1
at Project$$EnhancerByCGLIB$$71ab07ff.getMetaClass(<generated>)
at C_grails_1_0_3_tk_dev_zesadmin_grails_app_views_project_list_gsp$_run_closure15.doCall(C_grails_1_0_3_tk_dev_zesadmin_grails_app_views_project_list_gsp:101)
at C_grails_1_0_3_tk_dev_zesadmin_grails_app_views_project_list_gsp.run(C_grails_1_0_3_tk_dev_zesadmin_grails_app_views_project_list_gsp:89)