gpt4 book ai didi

chalice 。调用保存后id为空

转载 作者:行者123 更新时间:2023-12-04 11:27:12 26 4
gpt4 key购买 nike

我已经对此进行了搜索,但仍然无法弄清楚我做错了什么。调用save()后域对象 idnull .

我已经阅读了如果保存对象时出现问题会发生这种情况,并且 save(flush:true)如果是这种情况,应该会抛出错误,但事实并非如此。看看我的代码和输出:

def pic = new Picture(title:'XX', path:"XXX")
album.addToPictures(pic).save()
if(pic.validate())
println "no errors. New id: " + pic.id
else
println "with errors"

输出:
no errors. New id: null

并且在使用 flush:true 时
def pic = new Picture(title:'XX', path:"XXX")
album.addToPictures(pic).save(flush:true)
if(pic.validate())
println "no errors. New id: " + pic.id
else
println "with errors"

输出:
no errors. New id: 17

如您所见,创建对象没有任何错误,我应该能够得到 id刚刚调用 save() 后的对象.有任何想法吗?

谢谢

最佳答案

您误解了对象实际持久保存到数据库的时间。调用 obj.save() 时对象不会被持久化,当以下任何一种情况首先发生时,它就会被持久化:

  • 调用 save() 的事务已提交
  • 调用 save() 的 Hibernate session 已关闭

  • 可以使用显式启动事务
    SomeDomainClass.withTransaction {
    // code in here runs within a transaction
    }

    通常,每次调用服务方法时也会隐式启动事务
    class MyService {

    void doSomething () {
    // code in here runs within a transaction
    }
    }

    如果您不显式或隐式使用事务,则保存的对象会在 Hibernate session 关闭时(大致)在 HTTP 请求完成时持久化。

    但是,如果您调用 someObject.save(flush: true)您是在告诉 Hibernate 立即持久化对象,这就是为什么
    album.addToPictures(pic).save(flush: true)

    Picture 分配一个 ID例如,但是
    album.addToPictures(pic).save()

    仅在封闭 session /事务关闭/提交时分配 ID

    更新

    进一步你的评论

    The problem is that I want to use the id as part of the name of a file I need to save. What about if I get an error saving the file? Should I use a explicit transaction and roll it back?



    是的,使用显式事务,并在确定对象已成功持久化后保存文件,如果持久性失败则回滚事务
    def pic = new Picture(title:'XX', path:"XXX")

    Picture.withTransaction { TransactionStatus status ->

    try {
    album.addToPictures(pic).save()

    } catch(ex) {
    status.setRollbackOnly()
    throw ex
    }
    }

    // At this point you can be sure pic has been persisted, so use pic.id to save the file

    更新 2

    根据您的评论

    I don't want to save the file once I'm sure the object has been successfully persisted, but the opposite, I want to persist the object once the file has been successfully saved. So, I'm going to reformulate my questions as "Is there a way to configure Grails so that I can know the id that's going to be assigned to the new object before the object is effectively saved in the database?"



    你已经知道了
    album.addToPictures(pic).save(flush:true)

    将为您提供 Picture 的 ID例如,因此如果您在事务中执行此操作,则无需实际提交事务即可获得 ID。但是,我认为这仅在您使用使用序列的数据库(Oracle,Postgres)时才有效。像下面这样的东西应该工作
    Picture.withTransaction { TransactionStatus status ->        

    try {
    def pic = new Picture(title:'XX', path:"XXX")
    album.addToPictures(pic).save(flush: true)

    // pic.id should now be assigned, so save the file. I'm assuming an
    // an exception will be thrown if saving the file fails

    } catch(ex) {
    // you may also want to try rolling back the file save here, i.e. delete it
    status.setRollbackOnly()
    throw ex
    }
    }

    关于 chalice 。调用保存后id为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13595854/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com