2013-09-12 2 views
0

Мы пытаемся сохранить несколько объектов домена, которые связаны вместе с ограничениями внешнего ключа, и возникают проблемы с работой GORM.Сохранение нескольких цепочек с помощью 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 
} 

Мы пытались следующих вместе здесь: How do I save GORM objects with multiple many-to-one relationships?

Но это дает нам сообщение об ошибке:

| 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 

Пройдя через него с помощью отладчика, кажется, что начальная степень не создается до оператора возврата внизу метода, хотя я думал, что (flush:true) должен был заставить настойчивость?

Я просто пытаюсь сделать самый простой и самый правильный путь, и подумал, что GORM может справиться с этим таким образом, но, возможно, нет.

ответ

1

Ваш случай один-ко-многим, а не много-к-одному.

Попробуйте это вместо этого. Родитель должен быть первичным и, в конечном счете, детьми, вам не нужно добираться до детей каждый раз, когда он связан с его родителем, но, наконец, родитель корня может быть сброшен, чтобы засвидетельствовать поведение каскада.

def saveDegree(params){ 
    def degree = new Degree(params) 

    def degreeBlock = new DegreeBlock(params) 
    degree.addToDegreeBlocks(degreeBlock) 

    def courseBlock = new CourseBlock(params) 
    degreeBlock.addToCourseBlocks(courseBlock) 

    def course = new Course(params) 
    courseBlock.addToCourses(course) 

    degree.save(flush:true) 

    return degree 
} 
+0

же ошибка 'родительский ключ не найден для DEGREE_ID' – idonaldson

+0

Показать фактические классы домена и StackTrace вы видите. @idonaldson – dmahapatro

+0

Обновлено с полными классами и stacktrace – idonaldson

Смежные вопросы