#hibernate #grails #grails-orm
#спящий режим #grails #grails-orm
Вопрос:
Мне трудно разобраться в сути проблемы, с которой я столкнулся. У меня есть два Domain Classes
для моего приложения grails: HeadOfHousehold
и Dependent
. Они почти идентичны, за исключением нескольких мест; во-первых, HeadOfHousehold
владеет с Dependent
помощью конструкции: static hasMany = [dependents: Dependent]
, и Dependent
имеет static belongsTo = [headOfHousehold: HeadOfHousehold]
, во-вторых, Dependent
имеет свойство, String type
которое может быть либо Spouse
или Dependent
while HeadOfHousehold
имеет transient
метод getType()
, который просто возвращает Self
, и, наконец, есть два свойства currentAddress
и previousAddress
которые также Domain object
являются s, которые содержатся в HeadOfHousehold
, в то время как any Dependent
указывает на обратноена HeadOfHousehold
адреса . Теперь у меня возникли проблемы с выполнением любого запроса, который использовал бы более одного аспекта Current Address
Dependent
, поэтому я решил объединить эти объекты с помощью наследования, чтобы я мог просто запросить родительский класс из двух и получить результаты от обоих HeadOfHousehold
и Dependent
.
Поэтому я объединил их следующим образом: Parent Class
Person
class Person {
String firstName
String lastName
String middleName
String suffix
Date dateOfBirth
Date dateAdded
String driversLicenseNumber
String driversLicenseState
String ssn
String gender
Address currentAddress
Address previousAddress
MVR mvr
CreditReport creditReport
ClueAuto clueAuto
ClueProperty clueProperty
static transients =['reportDOB','reportDlNumberState','firstLastMiddleSuffix',
'reportAddressString']
static constraints = {
middleName blank: false, nullable: true
suffix blank: true, nullable: true
ssn matches: "[0-9]{9}"
gender blank: true, nullable: true, matches: "M|F"
currentAddress nullable: true
previousAddress blank: true, nullable: true
mvr nullable: true
creditReport nullable: true
clueAuto nullable: true
clueProperty nullable: true
dateAdded nullable: true
}
public String toString(){
String returnValue = lastName ", " firstName " " middleName
return returnValue.replaceAll("null"," ")
}
// I'm not sure if this is correct place for these, but they deal with
// the transformation necessary to create the order object to send it
// off to the broker in a byte[].
def getReportDOB(){//dealing with dates is stupid in java X_X
if(dateOfBirth){
GregorianCalendar calendar = new GregorianCalendar()
calendar.setTime(dateOfBirth)
return DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar)
}
}
def getReportDlNumberState(){
return driversLicenseNumber "_" driversLicenseState
}
def getFirstLastMiddleSuffix(){
return (firstName "_" lastName "_" middleName "_" suffix).replaceAll("null","")
}
def getReportAddressString(){
if(!previousAddress.isEmpty()){
return "0_HOME,1_BUSINESS"
} else{
return "0_HOME"
}
}
//TODO This really shouldn't be necessary I need to figure out why it is.
def convertGender(){
switch(gender){
case "M":
return "M"
case "F":
return "F"
default:
return null
}
}
}
Child Class
Dependent
class Dependent extends Person{
String type //relationship to head of household.
static belongsTo = [headOfHousehold: HeadOfHousehold]
static constraints = {
}
public String toString(){
String returnValue = lastName ", " firstName " " middleName
return returnValue.replaceAll("null","")
}
def beforeInsert(){
currentAddress = headOfHousehold.currentAddress
previousAddress = headOfHousehold.previousAddress
dateAdded = new Date()
}
}
Child Class
HeadOfHousehold
class HeadOfHousehold extends Person{
static hasMany = [dependents: Dependent]
static transients =['type']
static mapping = {
}
static constraints = {
}
def getType(){
return "Self"
}
}
Теперь это отлично работает, за исключением того, что у меня возникли серьезные проблемы с созданием экземпляров объектов. Я продолжал получать сообщение об ошибке:
Message: Error executing bootstraps; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: ....clients.Address
Который я решил, добавив адреса непосредственно в конструктор, а затем сразу же сохранив адреса
Таким образом:
Address currentAddress = FactoryHelperPicardAndPike.createCurrentAddress()
Address previousAddress = FactoryHelperPicardAndPike.createPreviousAddress()
HeadOfHousehold hh = FactoryHelperPicardAndPike.createPicard(picardAdded, picardBirthDate, currentAddress, previousAddress)
saveIt(currentAddress)
saveIt(previousAddress)
saveIt(hh)
Вместо:
HeadOfHousehold hh2 = FactoryHelperPicardAndPike.createPike(pikeAdded, picardBirthDate)
Address currentAddress2 = FactoryHelperPicardAndPike.createPikeCurrentAddress()
Address previousAddress2 = FactoryHelperPicardAndPike.createPikePreviousAddress()
hh2.setCurrentAddress(currentAddress2)
hh2.setPreviousAddress(previousAddress2)
saveIt(currentAddress2)
saveIt(previousAddress2)
saveIt(hh2)
Я не совсем понимаю, в чем проблема; и почему это появилось только после того, как я добавил наследование. Я смог решить его только методом проб и ошибок, что не совсем полезно, когда я столкнусь с проблемой в будущем. Теперь я прочитал все вопросы, на которые я мог найти ссылки unsaved transient instance
, и лучшее, что я могу понять, это ошибка, указывающая, что мой Address
объект считается переходным процессом, пока он не будет сохранен, и по какой-то причине он не будет каскадно сохраняться с HeadOfHousehold
помощью or Dependent
. Я не понимаю, чем он отличается для унаследованного объекта от отдельного объекта. Итак, кто-нибудь может объяснить, почему я получаю ошибку с унаследованными объектами, а не наоборот? Кроме того, где-нибудь есть подробное объяснение ошибки? Я прочитал это, и это не совсем понятно для меня.
Я знаю, что это долго, и я ценю ваше внимание.