我们正在尝试保存多个与外键约束链接在一起的域对象,并且无法让 GORM 工作。
领域类:
class Degree {
/* Default (injected) attributes of GORM */
Long id
Long version
/* Automatic timestamping of GORM */
Date dateCreated
Date lastUpdated
String department
String subject
String catalogYear
String level
String type
Long totalCredits
Double cumulativeGPArequired
String capstone
String comment
String updatedBy
static hasMany = [degreeBlocks: DegreeBlock] // tells GORM to associate other domain objects for a 1-n mapping
static mapping = {
sort "id"
version false
table 'degree'
columns{
id column: 'id'
department column: 'department'
subject column: 'subject'
catalogYear column: 'catalog_year'
level column: 'degree_level'
type column: 'type'
totalCredits column: 'total_credits'
cumulativeGPArequired column: 'cume_gpa_req'
capstone column: 'capstone'
comment column: 'degree_comment'
dateCreated column: 'date_created'
lastUpdated column: 'last_updated'
updatedBy column: 'updated_by'
}
id generator:'sequence', params:[sequence:'degree_id_sequence']
}
static constraints = {
department(nullable: true, maxSize: 30)
subject(nullable: true, maxSize: 30 )
catalogYear(nullable: true, maxSize: 9 )
level(nullable: true, maxSize: 15)
type(nullable: true, maxSize: 30)
totalCredits(nullable: true, maxSize: 3)
cumulativeGPArequired(nullable: true, maxSize: 3)
capstone(nullable: true, maxSize: 30)
comment(nullable: true, maxSize: 2000)
lastUpdated(nullable: true)
updatedBy(nullable: true)
}
@Override // Override toString for a nicer / more descriptive UI
public String toString() {
return "${subject}";
}
}
class DegreeBlock {
/* Default (injected) attributes of GORM */
Long id
Long version
/* Automatic timestamping of GORM */
Date dateCreated
Date lastUpdated
String blockType
String comment
static hasMany = [courseBlocks: CourseBlock] // TELLS GORM TO ASSOCIATE OTHER DOMAIN OBJECTS FOR A 1-N MAPPING
static belongsTo = [degree: Degree] // TELLS GORM TO CASCADE COMMANDS: E.G., DELETE THIS OBJECT IF THE "PARENT" IS DELETED.
static mapping = {
sort "id"
version true
table 'degree_block'
columns{
id column: 'id'
level column: 'degree_level'
blockType column: 'block_type'
comment column: 'block_comment'
dateCreated column: 'date_created'
lastUpdated column: 'last_updated'
}
id generator:'sequence', params:[sequence:'degree_block_id_sequence']
}
static constraints = {
blockType(nullable: true, maxSize: 50)
comment(nullable: true, maxSize: 2000)
lastUpdated(nullable: true)
}
/*
* Methods of the Domain Class
*/
@Override // Override toString for a nicer / more descriptive UI
public String toString() {
return "${blockType}";
}
}
class CourseBlock {
/* Default (injected) attributes of GORM */
Long id
Long version
/* Automatic timestamping of GORM */
Date dateCreated
Date lastUpdated
String name
String rule
String credits
String eval
String prereqNotes
String comment
static hasMany = [courses: Course] // tells GORM to associate other domain objects for a 1-n mapping
static belongsTo = [degreeBlock: DegreeBlock] // tells GORM to cascade commands: e.g., delete this object if the "parent" is deleted.
static mapping = {
sort "id"
version false
table 'degree'
columns{
id column: 'id'
name column: 'name'
rule column: 'rule'
credits column: 'credits'
eval column: 'eval'
prereqNotes column: 'prereq_notes'
comment column: 'course_comment'
dateCreated column: 'date_created'
lastUpdated column: 'last_updated'
}
id generator:'sequence', params:[sequence:'course_block_id_sequence']
}
static constraints = {
name(nullable: true, maxSize: 80)
rule(nullable: true, maxSize: 80 )
credits(nullable: true, maxSize: 10 )
eval(nullable: true, maxSize: 4)
prereqNotes(nullable: true, maxSize: 2000)
comment(nullable: true, maxSize: 2000)
lastUpdated(nullable: true)
}
/*
* Methods of the Domain Class
*/
@Override // Override toString for a nicer / more descriptive UI
public String toString() {
return "${name}";
}
}
class Course {
/* Default (injected) attributes of GORM */
Long id
Long version
/* Automatic timestamping of GORM */
Date dateCreated
Date lastUpdated
String subject
String courseNumber
String title
String credits
String term
static belongsTo = [courseBlock:CourseBlock] // tells GORM to cascade commands: e.g., delete this object if the "parent" is deleted.
static mapping = {
sort "id"
version false
table 'degree'
columns{
id column: 'id'
subject column: 'subject_code'
courseNumber column: 'course_number'
title column: 'title'
credits column: 'credits'
term column: 'term'
dateCreated column: 'date_created'
lastUpdated column: 'last_updated'
}
id generator:'sequence', params:[sequence:'course_id_sequence']
}
static constraints = {
subject(nullable: true, maxSize: 5 )
courseNumber(nullable: true, maxSize: 5 )
title(nullable: true, maxSize: 80)
credits(nullable: true, maxSize: 8)
term(nullable: true, maxSize: 10)
lastUpdated(nullable: true)
}
/*
* Methods of the Domain Class
*/
@Override // Override toString for a nicer / more descriptive UI
public String toString() {
return "${subject} ${courseNumber}";
}
}
服务方法代码:
def saveDegree(params){
def degree = new Degree(params).save()
def degreeBlock = new DegreeBlock(params, degree:degree)
degree.addToDegreeBlocks(degreeBlock)
degreeBlock.save(flush:true)
def courseBlock = new CourseBlock(params, degreeBlock:degreeBlock)
degreeBlock.addToCourseBlocks(courseBlock)
courseBlock.save(flush:true)
def course = new Course(params, courseBlock:courseBlock)
courseBlock.addToCourses(course)
course.save(flush:true)
return degree
}
我们在这里尝试了以下操作: 如何保存具有多个多对一关系的 GORM 对象?
但它给了我们错误:
| Error 2013-09-12 11:03:12,421 [http-bio-8080-exec-10] ERROR util.JDBCExceptionReporter - ORA-02291: integrity constraint (FK1_DEGREE_ID) violated - parent key not found
| Error 2013-09-12 11:03:12,424 [http-bio-8080-exec-10] ERROR events.PatchedDefaultFlushEventListener - Could not synchronize database state with session
Message: Could not execute JDBC batch update
Line | Method
->> 49 | saveDegree in degreebuilder.DegreebuilderService
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 50 | save in degreebuilder.DegreeController
| 195 | doFilter . in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 724 | run . . . in java.lang.Thread
Caused by BatchUpdateException: ORA-02291: integrity constraint (FK1_DEGREE_ID) violated - parent key not found
->> 343 | throwBatchUpdateException in oracle.jdbc.driver.DatabaseError
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 10698 | executeBatch in oracle.jdbc.driver.OraclePreparedStatement
| 297 | executeBatch in org.apache.commons.dbcp.DelegatingStatement
| 49 | saveDegree in degreebuilder.DegreebuilderService
| 50 | save . . . in degreebuilder.DegreeController
| 195 | doFilter in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter . in grails.plugin.cache.web.filter.AbstractFilter
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 724 | run in java.lang.Thread
使用调试器遍历它,似乎直到方法底部的 return 语句才创建初始度数,即使我认为(flush:true)
应该强制持久化?
我只是想以最简单和最正确的方式进行保存,并认为 GORM 可以这样处理,但也许不是。