2011-11-03 89 views
2

我拿到這2個實體:JPA /休眠堅持級聯即使它不應該

@javax.persistence.Entity 
public class Book { 
    @javax.persistence.EmbeddedId 
    private BookPK id; 

    private String title; 

    @javax.persistence.ManyToOne(fetch = javax.persistence.FetchType.LAZY) 
    @javax.persistence.JoinColumns({ 
      @javax.persistence.JoinColumn(name = "LNGCOD", referencedColumnName = "LNGCOD"), 
      @javax.persistence.JoinColumn(name = "LIBCOD", referencedColumnName = "LIBCOD") }) 
    private Language language; 
} 

@javax.persistence.Entity 
public class Language { 
    @javax.persistence.EmbeddedId 
    private LanguagePK id; 

    private String name; 
} 

與由PK的:

@Embeddable 
public class BookPK implements Serializable { 
    private Integer bookcod; 
    private Integer libcod; 
} 

@Embeddable 
public class LanguagePK implements Serializable { 
    private Integer lngcod; 
    private Integer libcod; 
} 

如果我嘗試創建一個新的圖書,並堅持它,我得到一個異常,告訴我libcod在insert語句中找到兩次(「Column'libcod'指定兩次」)。但是在定義JoinColumn時不能使用「insertable = false」(「在屬性中不允許插入和不可插入的列混合」)。

有什麼辦法來定義這些對象+關係,所以列由Hibernate自動管理?

回答

2

當連接到會話時,Hibernate和JPA會自動對持久實體進行所有修改。這就是ORM的要點:你加載一個持久化對象,修改它,並且新的狀態在事務提交時自動持久化,而不需要調用persist,merge,save或者其他方法。

請注意,在持久實體上調用persist(除了級聯副作用)是沒有意義的。 persist用於創建一個暫時的實體(即一個新的,不在數據庫中,沒有生成的ID)持久化。

+0

沒關係。我匆匆做了測試,並犯了一些錯誤。測試應該與分離的對象一起運行。我現在遇到了一個新問題,請檢查編輯後的問題。謝謝。 – ccc

+0

這裏有一個非常奇怪的模式:在不改變主鍵的情況下改變圖書的語言是不可能的。我會使用單列代理鍵。如果你不能,那麼我會有兩個獨立的libcod列:一個用於本書的主鍵,另一個用於語言外鍵。 –

+0

問題是我無法更改數據庫結構。我必須使用這個遺留數據庫,所以我正試圖找到通過JPA描述和管理它的最優雅方式。當然,我更喜歡有PK和FK的簡單ID,但是... – ccc

0

您只能爲libcod使用一個增變器。也許,你應該做的是將libcod getter留在BookPK類中,並且在Language類中,使用一個帶有refc的連接列引用返回到libcod。它適用於單個嵌入式PK類,但對於多個PK類,您可能必須玩轉。

所以,在你的語言課上,你會有這個。

@javax.persistence.Entity public class Language { 

    private LanguagePK id; 
    private Integer libcod; 

    @javax.persistence.EmbeddedId @AttributeOverrides({ 
     @AttributeOverride(name = "lngcod", column = @Column(name = "LNGCOD", nullable = false)), 
     @AttributeOverride(name = "libcod", column = @Column(name = "LIBCOD", nullable = false)) }) 
    public LanguagePK getId() { 
      return this.id; 
    } 
    public void setId(LanguagePK id) { 
      this.id = id; 
    }  


    @ManyToOne(fetch = FetchType.LAZY) 

     @JoinColumn(name = "LIBCOD", insertable = false , updatable = false) 
     public Integer getLibcod() { 
     return this.libcod; 
     }