Grails无法保存对象,会话中是否已存在?

时间:2012-03-09 20:51:34

标签: hibernate grails gorm grails-domain-class

  

可能重复:
  Spring + Hibernate : a different object with the same identifier value was already associated with the session

我有三个类似于以下示例排列的域名:

class Computer {
    static hasMany = [progStartTimes:ProgStartTime]
    static belongsTo = User

    static constraints = {
        name()
        operatingSystem()
        processor()
    }

    User owner
    OperatingSystem os
    Processor processor
}

class OperatingSystem {
    static hasMany = [computers:Computer]

    static constraints = {
        name(blank:false,unique:'versionType',maxSize:80)
        versionType()
    }

    static mapping = {
        versionType type:VersionTypeMapping
    }

    String name
    VersionType versionType
}

class ProgStartTime implements Serializable {
    static constraints = {
        computer()
        program()
        duration()
    }

    static mapping = {
        id composite:['computer','program']
        duration type:DurationMapping
    }

    Computer computer
    Program program
    Duration duration
}

我有一个控制器,可以创建一堆对象并在事务中同时保存它们。保存了大约五六个不同的批次后,它工作正常,但过了一段时间我得到了例外:

org.springframework.orm.hibernate3.HibernateSystemException: a different object
with the same identifier value was already associated with the session:
[diag.ProgStartTime#diag.ProgStartTime : null]; nested exception is
org.hibernate.NonUniqueObjectException: a different object with the same
identifier value was already associated with the session:
[diag.ProgStartTime#diag.ProgStartTime : null]

以下是保存对象的控制器代码部分。有谁知道发生了什么事?

ownerInstance.withTransaction { status ->
    try {
        if (operatingSystem.id == null) {
            operatingSystem.save()
        }

        if (processor.id == null) {
            processor.save()
        }

        startTimes.each {
            if (it.id == null) {
                it.save()
        }
    } catch (Exception e) {
        ownerInstance.errors.reject("Failed to save the necessary objects: " + e)
        status.setRollbackOnly()
    }
}

1 个答案:

答案 0 :(得分:2)

你对ProgStartTime的id映射是我在Grails中经常使用的东西,但在查找之后,在我看来,通过执行复合 id,你可以保证ProgStartTime的独特之处在于,没有两个人可以共享计算机和程序。

如果您违反了该约束条件,我会发现您遇到的错误。检查您输入的数据与ProgStartTime数据表中的内容相关,以查看是否存在问题。如果是别的,我会尽力协助进一步:)

出于好奇,你正在使用什么版本的grails?