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 的 hasMany
或 hasOne
,那么您不需要显式地为它们创建属性。如果你删除 center
和 path
那么它应该开始工作:
MapCoordinate center //remove this
Integer zoom
List path //remove this
我认为这里的问题是 MapCoordinate
只有一个 belongsTo
定义。另一方面,Map
中有 hasOne
和 hasMany
。我建议您将域 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)
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 的 hasMany
或 hasOne
,那么您不需要显式地为它们创建属性。如果你删除 center
和 path
那么它应该开始工作:
MapCoordinate center //remove this
Integer zoom
List path //remove this
我认为这里的问题是 MapCoordinate
只有一个 belongsTo
定义。另一方面,Map
中有 hasOne
和 hasMany
。我建议您将域 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)