数据库中的重复条目错误

时间:2015-01-27 13:45:18

标签: grails gorm

我有类似下面的域结构(它是一个遗留数据库!):

class Contract implements Serializable {
    int type
    ...
    hasMany = [attachments: Attachment]

    static mapping = {
        attachments cascade: "all-delete-orphan"
    }
}

class Attachment implements Serializable {
    static belongsTo = [contract: Contract]
    int attNo
    String name

    static mapping = {
        id generator: 'assigned', composite: ['contract', 'attNo']
    }
}

合同具有 - 取决于它的类型 - 一些默认附件,如果类型发生变化,应删除并重新创建。

为此,我创建了一个在保存编辑的合同之前调用的服务。 (该服务没有@Transactional注释,使其在与保存/更新合同相同的事务中运行。)

class AttachmentService {

    def removeAttRecords(int contractId) {
        Contract contract = Contract.get(contractId)
        def records = contract.getAttachments()
        for (int i = 0; i < records.size(); i++) {
            Attachment record = records[i]
            contract.removeFromAttachments(record)
        }
    }

    def insertAttRecord(int contractId, String name) {
        def contract = Contract.get(contractId)
        def records = contract.attachments
        int maxNo = 0
        for (attachment record: records) {
            if (record.attNo > maxNo) 
                maxNo = record.attNo
        }

        Attachment att = new Attachment()
        att.contract = contract
        att.attNo = maxNo +1
        att.name = name
        att.validate()
        att.save(insert: true, flush: true, failOnError: true)
    }

    def createDefaultRecords(int newType, int contractId) {
        if (newType == 1) {
            removeAttRecords(contractId)
        } else if (newType == 2) {
            removeAttRecords(contractId)
            insertAttRecord(contractId, "Attachment XYZ")
            insertAttRecord(contractId, "Attachment ABC")
        } else if (newType == 3) {
            removeAttRecords(contractId)
            insertAttRecord(contractId, "Attachment DEF")
        }
    }
}

我现在的问题是,如果我调用,我会在 insertAttRecord-&gt; att.save调用中从数据库中收到重复条目错误我的服务中的createDefaultRecords 方法。因为删除和娱乐。

我目前不知道,我该如何解决它。

2 个答案:

答案 0 :(得分:0)

您正在使用id generator: 'assigned'作为附件类。这意味着您必须自己设置其ID(主键)。看起来好像你没有分配它,新条目都将具有相同的id,因此重复的条目失败。

答案 1 :(得分:0)

我使用以下代码解决了我的问题:

class AttachmentService {

    def removeAttRecords(int contractId) {
        Attachment.executeUpdate("delete from Attachment att where att.contract.id = ?", [contractId])
    }

    def insertAttRecord(int contractId, int nextMaxNo, String name) {
        Attachment att = new Attachment()
        att.contract = Contract.get(contractId)
        att.attNo = nextMaxNo
        att.name = name
        att.validate()
        att.save(insert: true, flush: true, failOnError: true)
    }

    def createDefaultRecords(int newType, int contractId) {
        def result = Attachment.executeQuery("select max(att.attNo) from Attachment att where att.contract.id = ?", contractId)
        if (result[0] == null) result[0] = 0;
        int currMaxNo = result[0]

        if (newType == 1) {
            removeAttRecords(contractId)
        } else if (newType == 2) {
            removeAttRecords(contractId)
            insertAttRecord(contractId, currMaxNo +1, "Attachment XYZ")
            insertAttRecord(contractId, currMaxNo +2, "Attachment ABC")
        } else if (newType == 3) {
            removeAttRecords(contractId)
            insertAttRecord(contractId, currMaxNo +1, "Attachment DEF")
        }
    }
}

在与db-designer讨论之后,可以通过这种方式处理它。 (但我仍然想知道,为什么它没有工作,即使是会话冲洗......: - )