2016-11-02 4 views
0

Определение Карта являетсяИсключение причины нарушения целостности данных Grails и причина?

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] 

Может кто-нибудь, пожалуйста, объясните мне, в чем причина этой ошибки? Я ценю вашу помощь! Благодаря!

+0

Я думаю, что проблема в том, что вам нужно 'Map' сэкономить' MapCoordinate', но так как вам нужно 'MapCoordinate' сохранить' Map', вы попадаете в круглую ссылку. – rvargas

+0

@ rvargas вы можете предложить решение? Я пытаюсь создать карту с центром, масштабированием и списком путей. – kofhearts

ответ

0

Я думаю, что проблема здесь в том, что MapCoordinate имеет только один belongsTo определение. С другой стороны, у вас есть hasOne и hasMany в пределах Map. Я предлагаю вам изменить структуру классов домена следующим образом (включая предложение Рэндалла). С помощью 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 должен реализовать интерфейс 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) 
+0

спасибо! Габриэль. Как вы добавляете путь, а также в центр выше кода? – kofhearts

+0

Либо вы добавляете его в конструктор ('new MapCoordinate (mapCenter: map, mapPath: map, широта: 0.123, longitude: 0.2424)'), либо вы можете попробовать, добавив эту строку после определения 'cent':' map. addToPath (cent) ' – gabriel

+0

gabriel, почему это невозможно? map.center = new MapCoordinate (широта: 0,123, долгота: 0,2424). в приведенном выше примере вы добавляете одну и ту же координату в путь, а также в центр. они должны быть разными. Я попытался добавить другую координату к пути и получил ошибку. org.codehaus.groovy.runtime.typehandling.GroovyCastException: не может передать объект 'null' с классом 'null' в класс 'int'. Попробуйте «java.lang.Integer» вместо – kofhearts

0

Я думаю, что ваша проблема вызвана тем, что List path имеет значение null, и поэтому объект не может быть сохранен. Попробуйте посмотреть, как выглядит таблица Map в dataase, и вы увидите, что она имеет столбец path, который не может быть недействителен.

Если вы добавили записи в gorm's hasMany или hasOne, вам не нужно явно создавать для них свойства. Если удалить center и path, то он должен начать работать:

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

, комментируя свойства центра и пути, исправляет ошибку, но причина, по которой у меня есть тип пути, установленный в List, заключается в том, что я хочу поддерживать порядок. Я думаю, что не указывая тип будет по умолчанию Set, который в моем случае нарушает это требование. можете ли вы предложить решение без изменения базовых типов данных? Благодаря! – kofhearts