2014-12-05 98 views
0

一个Grails 2.3.4应用程序连接到Oracle数据库使用以下域类:Grails何时将一个ID分配给一个对象?

class Person { 

    String name 

    static mapping = { 
     id column: "PERSON_ID", generator: "sequence", params: [sequence: 'person_seq'] 
    } 
} 

PersonController使得在PersonService方法的调用,它使以UtilService的呼叫。在UtilService该方法被称为具有基于阉此Person对象是新的一些逻辑:

if (personInstance.id == null) { ... } 

我已经发现的是,的personInstanceid属性(其通过上述的方法调用传递)被分配时调用UtilService

调用PersonService的控制器操作是@Transactional,并且服务没有任何事务配置。

所以,几个问题:

  • id值由GORM分配(我猜的插入,但看上去是错的)?
  • 有没有更好的方法来检查对象是否是新的(isAttached()返回true这样对我不好)?

编辑:save()尚未呼吁personInstanceUtilService做的id检查。

+0

我不是你的问题是什么完全清楚:你期待的ID仍在调用'save()'后为空或即使在保存后ID仍为空?否则在你的情况下(使用序列发生器)我会说,只要你的保存被刷新,这个ID就会被填充 - 如果你想急于你可以调用'save(flush:true)'。 – 2014-12-05 06:44:46

+0

否则,也许是由于糟糕的经验,但我不会依赖GORM内部来查看某个对象是否刚刚被保存。你可以在'save()'后面设置的域类上使用'transient Boolean newlyInserted'属性,将实例包装成一个POGO或命令对象(它将包含一个'newInstance'属性),或者只需要一个您的服务方法的额外参数。 – 2014-12-05 06:48:32

+0

@GregorPetrin,'id'在我调用'save()'之前有一个值,因此我的困惑。 – zoran119 2014-12-06 10:01:46

回答

0

事实证明,我有一个findBy这是冲洗会议:

utilService.someMethod(Person.findByUsername(username)) 

正是在这一点上,id被填充。

围绕它得到了利用withNewTransaction

def personInstance = Person.withNewSession { Person.findByUsername(username) } 
utilService.someMethod(personInstance) 

现在导致我到next question ...

1

当您拨打save()时,会分配该ID。对于大多数持久性调用,Hibernate会延迟刷新变化直到感觉到需要刷新)以确保正确性。但save()调用的处理方式不同。我相信动机是,即使我们知道flush()最终会被调用,即使它在请求的最后,我们也希望尽早检索这个id,这样它就不会突然改变。

需要注意的是,它“没有任何事务配置”的服务是事务性 - 让非事务性服务的唯一方法是删除所有@Transactional注释(较新的Grails的注释和老春注解),并添加

static transactional = false 

所有其他服务都是事务性的,尽管您可以配置单个方法来忽略## Headin。

+0

我忘记提及我没有调用'UtilService'中选中'id'时,'save()'在'personInstance'上。因此我的困惑。这几乎就像是调用'UtilService'刷新休眠会话... – zoran119 2014-12-06 10:05:28

+0

这是一个'findBy',它正在刷新会话,并且这个刷新正在填充'id'(据我所知,发布了一个描述我如何处理它) – zoran119 2014-12-16 10:45:06

相关问题