2014-12-05 96 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

相關問題