grails数据完整性违规异常和原因?

grails data integrity violation exception and cause?

Map的定义是

class Map {

    MapCoordinate center
    Integer zoom
    List path

    static hasMany = [path: MapCoordinate]

    static hasOne = [center: MapCoordinate]

    static constraints = {

    }
}

MapCoordinate的定义是

class MapCoordinate {

    BigDecimal latitude
    BigDecimal longitude


    static belongsTo = [map: Map]

    static mapping = {

        latitude scale: 9
        longitude scale: 9

    }

    static constraints = {
    }
}

这个简单的脚本失败并出现以下异常

Map map = new Map()

def cent = new MapCoordinate(latitude: 0.123, longitude: 0.2424)

map.center = cent

map.zoom = 5

map.save(flush:true, failOnError: true)

异常

org.springframework.dao.DataIntegrityViolationException: could not insert: [MapCoordinate]; SQL [insert into map_coordinate (version, latitude, longitude, map_id, path_idx) values (?, ?, ?, ?, ?)]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not insert: [MapCoordinate]

有人可以向我解释这个错误的原因是什么吗?我感谢您的帮助!谢谢!

我认为您的问题是因为 List path 为空,因此无法保存实体。请尝试查看 table Map 在数据库中的外观,您将看到它具有不可为空的列 path

如果您将条目添加到 gorm 的 hasManyhasOne,那么您不需要显式地为它们创建属性。如果你删除 centerpath 那么它应该开始工作:

MapCoordinate center //remove this
Integer zoom
List path //remove this

我认为这里的问题是 MapCoordinate 只有一个 belongsTo 定义。另一方面,Map 中有 hasOnehasMany。我建议您将域 classes 的结构更改为以下内容(包括 Randall 的建议)。使用 mappedBy 可以确保 grails 能够正确识别这两个关系。

class Map {
    Integer zoom
    SortedSet path
    static hasMany = [path: MapCoordinate]
    MapCoordinate center

    static mappedBy = [path: "mapPath", center: "mapCenter"]

    static constraints = {
        center nullable: true
    }
}

class MapCoordinate implements Comparable {
    BigDecimal latitude
    BigDecimal longitude

    static belongsTo = [mapPath: Map, mapCenter: Map]

    static mapping = {
        latitude scale: 9
        longitude scale: 9
    }
    static constraints = {
        mapPath nullable: true
        mapCenter nullable: true
    }

    int compareTo(other) {
        if (id) {
            id.compareTo(other.id)
        }
        else {
            return -1
        }
    }

}

通过添加 SortedSet,您应该能够保留 MapCoordinate 条目的顺序。但是,MapCoordinate class 必须实现 Comparable 接口。最后,尝试修改代码如下:

Map map = new Map()
def cent = new MapCoordinate(latitude: 0.123, longitude: 0.2424)
map.center = cent
map.zoom = 5
map.addToPath(new MapCoordinate(latitude: 0.33, longitude: 0.33))
map.addToPath(new MapCoordinate(latitude: 0.34, longitude: 0.34))
map.save(flush: true, failOnError: true)