我有类似下面的域结构(它是一个遗留数据库!):
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 方法。因为删除和娱乐。
我目前不知道,我该如何解决它。
答案 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讨论之后,可以通过这种方式处理它。 (但我仍然想知道,为什么它没有工作,即使是会话冲洗......: - )