【问题标题】:How to get and use a transient instance?如何获取和使用瞬态实例?
【发布时间】:2013-08-14 18:17:42
【问题描述】:

我只是想在控制器中使用域类的瞬态实例。瞬态实例本质上是两个持久性实例的交叉产物,我不需要也不想持久化它。但是,我仍然收到 TransientObjectException。有没有办法仅仅为了方便而实例化一个对象,然后在不持久化的情况下将其丢弃?

这是 grails 2.2.0。谢谢!

好的,添加一些代码:

我正在处理的具体课程是Warranty

class Warranty {

    // ...other fields...
    Client client

client 是唯一必填字段。 Client 类也有一个 Warranty 外键:

class Client {

    // ...other fields...
    Warranty warranty

在控制器中:

String name = params.name
if (name == null) { return }
Client client = Client.findByClientName(name as String)

// ...other stuff...

def warranty = new Warranty(client: client)
return // for testing purposes

...这引发了异常!

【问题讨论】:

  • instance.discard() 应该可以你能粘贴你的真实代码吗?
  • @SérgioMichels:好的,添加了一些代码。
  • 您的异常行是def warranty = new Warranty(client: client)?之后真的有回报吗?
  • @SérgioMichels 在这一点上,出于测试目的,我这样做了。 warranty 将在控制器中进一步使用,但现在我要立即退出以确认 Warranty 对象的实例化是问题所在。

标签: hibernate grails grails-orm


【解决方案1】:

我的猜测是你修改了你的客户端实例,所以当你创建一个新的保修时,它引用了未保存的客户端。

尝试在创建保修之前添加client.discard()

【讨论】:

  • 天哪……这太明显了!我不敢相信我没有尝试过。这太疯狂了,因为客户端根本没有改变,但是它可以工作,所以谢谢!
  • 嗯,client 是另一个类的动态查找器的参数。甚至触摸动态查找器是否会导致刷新会话?
  • 是的,动态查找器会自动刷新会话。
  • 只是:有时当我们覆盖 getter 或 setter 时,域类总是会发生变化。
  • 啊哈!来自 Burt Beckwith 本人:“永远不要更改 setter 中的值或从 getter 返回不同的值 - 你会混淆 Hibernate。” (grails.1312388.n4.nabble.com/…)
【解决方案2】:

您可以在会话中evict,这样在刷新期间不会对其进行处理

【讨论】:

  • 我试过instance.discard(),它是 Grails 的等价物,它似乎没有任何效果。奇怪的是,我什至无法在不引发异常的情况下创建此实例和 return:/ 恐怕域中的某处必须尝试刷新。
猜你喜欢
  • 2018-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多