как сделать сохранение или обновление в Grails? - PullRequest
4 голосов
/ 26 апреля 2011

Если запись не существует, ее следует вставить.И если запись существует, Grails должен сделать обновление.

new MyEntity(attr1:'val1', attr2:'val2').saveOrUpdate()????

EDIT Я изменил свой код в соответствии с вашими предложениями:

List<NutDto> res = np.parseNutData(file.inputStream);
for(NutDto cellValue : res){
    def nutInstance = NutData.get(cellValue.getIdd())       
    System.out.println("nutInstance = " + nutInstance);         
    if(nutInstance){
        System.out.println("Exists : " + nutInstance);
        nutInstance.foo=cellValue.getFoo()
        nutInstance.bar=cellValue.getBar()              
    }
    else{
        System.out.println("Not Exists")
        nutInstance =   new NutData(idd:cellValue.getIdd(),
                foo:cellValue.getFoo(),
                bar:cellValue.getBar())
    }

    def saveres = nutInstance.save(failOnError: true);
    println("saveres = " + saveres);
    nutInstance.errors.each { println it }
}

Тем не менее его нетобновление.Его ошибки выброса.

Field error in object 'sps.NutData' on field 'idd': rejected value [123456-1234]; codes [sps.NutData.idd.unique.error.sps.NutData.idd,sps.NutData.idd.unique.error.idd,sps.NutData.idd.unique.error.java.lang.String,sps.NutData.idd.unique.error,nutData.idd.unique.error.sps.NutData.idd,nutData.idd.unique.error.idd,nutData.idd.unique.error.java.lang.String,nutData.idd.unique.error,sps.NutData.idd.unique.sps.NutData.idd,sps.NutData.idd.unique.idd,sps.NutData.idd.unique.java.lang.String,sps.NutData.idd.unique,nutData.idd.unique.sps.NutData.idd,nutData.idd.unique.idd,nutData.idd.unique.java.lang.String,nutData.idd.unique,unique.sps.NutData.idd,unique.idd,unique.java.lang.String,unique]; arguments [idd,class sps.NutData,123456-1234]; default message [Property [{0}] of class [{1}] with value [{2}] must be unique]

Значения не обновляются.

РЕДАКТИРОВАТЬ 2

package sps    
class NutData {

    String idd
    String foo
    String bar


    static constraints = {
        idd(blank:false, unique:true)
    }

    static mapping = {
        table 'M_NUT_DATA'
        version false
        id generator: 'assigned', name: "idd", type: 'string'
        foo column:'FOO_COL'
        bar column:'BAR_COL'        
    }

    String toString(){
        return idd + '_' + foo
    }
}

Ответы [ 7 ]

11 голосов
/ 30 ноября 2013

Динамические искатели точно доступны для этой цели.

Используя findOrSaveBy * ваш первый пример кода будет записан так:

def entity = MyEntity.findOrSaveByAttr1AndAttr2( val1, val2 )

Документация: http://grails.org/doc/latest/ref/Domain%20Classes/findOrSaveBy.html

3 голосов
/ 26 апреля 2011

A .save() должен делать все это, но это зависит от того, как вы создали объект.

если вы используете new MyEntity(..) grails создаст запись, если вы получите объект из базы данных, сохранение выполнит обновление.

2 голосов
/ 26 апреля 2011

Вы можете использовать следующий код (замените Widget вашим классом / сущностью):

def widgetInstance = Widget.findByName('firstWidget') ?: new Widget(name: 'firstWidget').save(failOnError: true)

Аргумент функции сохранения "failOnError: true" гарантирует, что код потерпит неудачу в случае, если естьошибка.

1 голос
/ 26 апреля 2011

Как говорит elCapitano, проблема здесь во многом зависит от того, как вы получаете объект.

Если вы получили объект из базы данных, а затем изменили его, вам просто нужно вызвать save () для объекта.

Если вы создаете новый объект (как ваш пример): теперь это зависит от того, как вы знаете, «этот же объект уже существует в базе данных». Вы должны выполнить запрос, чтобы определить, существует ли объект, а затем выполнить обновление или создать соответственно. Там нет ярлыка для этого.

Но чаще проблема не так уж и сложна, поскольку обычно вы обновляете объект, только если он уже загружен (например, в форму) для редактирования пользователями. В противном случае вы знаете, что вам нужно создать объект.

Вы можете использовать функцию grails scaffolding , чтобы увидеть типичную модель, как Grails выполняет CRUD (create-update-delete).

0 голосов
/ 26 апреля 2016

findOrSaveBy... не не обновляет существующие данные. Поэтому я написал свой собственный код для домена с именем Person.

Boolean saveOrUpdate(Integer id, String name, Status status, Date startDate) {

    Person person = Person.findById(id)

    //If the person is new, create a new instance and assign ID
    if(!person) {
        person = new Person()
        person.setId(id.toLong()) 
       /** I set the ID here because I am using Postgres and I want to assign the ID manually
       `static mapping = {
           id generator: 'assigned'
        }`
       */
    }

    person.name = name
    person.status = status
    person.startDate = startDate
    person.save(flush: true, failOnError: true)

    if (person?.hasErrors()) {
        log.error("Person ${id} is not saved. Domain Errors: ${person?.errors}")
    }
}
0 голосов
/ 18 мая 2011

a .save () 'должен делать все это, но это зависит от того, как вы создали объект.

если вы используете 'new MyEntitiy (..)', grails создаст запись, если вы получите объект из >> базы данных, сохранение выполнит обновление.

Точно в точку. Сначала получите объект, проверьте, что изменилось, затем сохраните его обратно. Использование new создаст другую запись в БД во время сохранения «только потому, что» это новый объект.

def gottenFromDB = TheObject.get( params.id ) ; //for example
def updatesObject = new MakeNewObjectFromJSON( request ) ; // this one contains the updates

// either check property  by property or just update all properties 
// whatever is more efficiente or if you don't care.

gottenFromDB.prop1 = updatesObject.prop1
gottenFromDB.prop2 = updatesObject.prop2
gottenFromDB.propN   = updatesObject.propN

gottenFromDB.save() ; // this will perform "update"
0 голосов
/ 30 апреля 2011

Чтобы обновить запись, мы должны уточнить: - Если у моего класса домена есть поля a, b, c и d.Затем, при попытке сохранить, если a и b совпадают с обновлением записи, в противном случае вставьте новую запись.

Итак, прежде всего определите эти поля в классе вашего домена.

Затем мынужен метод saveOrUpdate для класса домена, который выполняет что-то вроде следующего:

//This method is present in domain class
saveOrUpdate()
{
   //listOfFields is a list of fields that are identifiers or the once that decide whether to update or insert.
   def existingObject = DomainClass.findWhere([this.properties.subMap(listOfFields)])

   if(existingObject)
   {
      // Hey!!! This object already exists in DB. Let us update it .... 
      // Update the existingObject and save the same
   }
else{
    // No object already exists in the DB so, let us create a new one and save it.
   } 
}

Если вы хотите выполнить рабочую реализацию того же самого, пожалуйста, обратитесь к моему блогу:

http://www.intelligrape.com/blog/2011/03/15/implementing-saveorupdate-for-domain-classes/

Надеюсь, это поможет.

...