2017-06-21 40 views
0
class Extra { 
    int a; 
} 

@Entity 
@Table(name = "data_table") 
@Data 
class Data { 
    @Column int state; 
    @Column(name = "extra") String _extra; 

    @Transient Extra extra; 

    @PostLoad 
    void preLoad() { 
     extra = mapper.readValue(_extra, Extra.class); 
    } 

    @PrePersist 
    @PreUpdate 
    void prePersist() { 
     _extra = mapper.writeValueAsString(extra); 
    } 
} 

Data data = jpaRepository.findOne(...); 
data.setState(1); 
data.getExtra().setA(1); 
jpaRepository.save(data); 

我想使用額外的字符串列作爲額外的對象。 所以我做了@PostLoad,@PrePersist回調,它們正在轉換額外的列。 但是,當我堅持數據對象時,狀態值是持久的,但額外的列(Data._extra)不會持久。我做錯了什麼?JPA實體沒有持續我的額外字段

+1

爲什麼不在Extra映射上使用轉換器而不是使其成爲瞬態?轉換器會將其轉換爲字符串/從字符串轉換,而不是依賴preLoad和prePersist方法,並允許您刪除_extra字段。請參閱http://docs.oracle.com/javaee/7/api/javax/persistence/Convert.html – Chris

+0

目前,我正在使用轉換器。現在我只是想知道爲什麼額外的列不會持久。 – chaeyk

回答

1

您的保存方法 - 它使用合併?由於Extra是暫時的,它對於JPA是不可見的,並且不會被合併到託管實例中。因此,在調用preUpdate方法時它將爲空。如果您需要它們,您必須編寫自己的保存方法來合併瞬態值。

2

您定義的額外對象是@Transient。瞬態對象不保存到數據庫。

+0

對不起,我的意思是額外的專欄。 (_Data成員) – chaeyk

1

如果你真的打算詢問extra.a,那麼@Abdullah G的答案是否正確。

但是,如果你犯了一個錯字,那麼你可能是指_extra場。

Hibernate的緩存值只是被堅持這樣你要在@PreUpdate回調緩存的舊對象。

UPDATE我已經找到了解決辦法是使用的

@Column(name = "password", insertable = false, updatable = false) 

代替@Transient註解。但是,它會在數據庫中創建一個始終爲空的列。


+0

我聽不懂。你的意思是prePersist()中的額外屬性是舊對象嗎?但我設置了額外的data.getExtra()。setA(1)。怎麼會這樣..? – chaeyk

+0

@chaeyk數據對象本身是舊的。你甚至可以在調試器中看到它。我發現了這個問題並檢查了我自己。當你第二次查看'extra'字段時,它不會在'state'變化時更改。所以在調用dataRepository.save(data)之前,我看到'extra'字段被更改,但是當我在@PreUpdate中調試時 - 它不是 –