2015-07-21 2 views
0

У меня следующая ситуация:Grails внешнего ключа ошибка удаления родительской строки

class Receipt { 

    BigDecimal totalAmount; 
    Date releaseDate; 

    @NotNull 
    Integer vatPercentage; 

    @NotNull 
    Integer discount; 

    Boolean isPayed; 
    Boolean isInvoice; 
    Boolean hasStampDuty; 

    Integer documentNumber; 

    @NotNull 
    static belongsTo = [patient:Patient, doctor:Doctor] 

    @NotNull 
    static hasMany = [healthServices:Receipt_HealthService] 


    static constraints = { 
     healthServices(blank: false) 
     patient(blank: false) 
     totalAmount(blank: false,) 
     vatPercentage(blank: false, nullable: false) 

    } 


} 


class HealthService { 

    int vat; 
    String description; 
    BigDecimal price; 

    static belongsTo = [healthServiceType:HealthServiceType, doctor:Doctor] 

    static constraints = { 
     healthServiceType(blank: false) 
     vat(size: 11..11) 
     description(maxSize: 255) 

    } 
} 


class Receipt_HealthService { 

    Receipt receipt 
    HealthService healthService 
    int quantity = 1 

    static constraints = { 
    } 
} 

Я вручную создал класс домена Receipt_HealthService, как описано в посте here. Все работает хорошо, но когда я пытаюсь удалить экземпляр квитанции, я вижу следующее сообщение об ошибке:

Cannot delete or update a parent row: a foreign key constraint fails 
(`my_localdb`.`receipt_health_service`, CONSTRAINT 
`FK96DE98B9D3292D2C` FOREIGN KEY (`receipt_id`) REFERENCES `receipt`(`id`)) 

Почему это произошло? Почему экземпляры Receipt_HealthService не удаляются автоматически? Что мне нужно изменить, чтобы разрешить автоматическое удаление и удалить ошибку?

ответ

2

Класс Receipt_HealthService не имеет belongsTo, поэтому удаления Receipt не каскадируются. См. http://grails.github.io/grails-doc/latest/guide/GORM.html#cascades.

Вы можете либо изменить Receipt_HealthService следующим образом:

class Receipt_HealthService { 
    ... 
    static belongsTo = [receipt: Receipt] 
} 

Или попытаться определить поведение каскада явно (см http://grails.github.io/grails-doc/latest/guide/GORM.html#customCascadeBehaviour).

Другая возможность - добавить beforeDelete в Receipt, который заботится об удалении каждой записи в healthServices. См http://grails.github.io/grails-doc/latest/guide/GORM.html#eventsAutoTimestamping

Для последнего варианта, вы можете проверить классы User, UserRole и Role из Spring Security Plugin в качестве примера. Я не нашел образец проекта в Интернете, но вы можете просто установить плагин в примерном проекте и запустить grails s2-quickstart, чтобы посмотреть, как выглядит User#beforeDelete (см. https://grails-plugins.github.io/grails-spring-security-core/ref/Scripts/s2-quickstart.html).

+0

Спасибо! Введите свойство Добавить поле в таблицу Receipt? – FrancescoDS

+0

Поле? Я так не думаю. Семантика для доступа к отношениям с обеих сторон будет одинаковой (receipt.healthServices и receipt_HealthService.receipt). DB мудрый он также должен быть таким же: receipt_health_service должен иметь FK, называемый receipt_id. – Deigote

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