2009-12-14 52 views
1

雖然我嘗試保存頂級實體(使用JPA),我是否需要從數據庫剛剛獲取ManyToOne映射的實體,並設置它或不能我只是設置Id ?的多對一映射的實體,並保存頂級實體 在沒有得到新的實體,它拋出:org.hibernate.TransientObjectException:我們正在使用Hibernate - ManyToOne - 保存 - org.hibernate.TransientObjectException:

表結構:

DEPARTMENT(DEPARTMENT_ID BIGINT, NAME VARCHAR(128)) 

EMPLOYEE(EMPLOYEE_ID BIGINT, NAME VARCHAR(128), DEPARTMENT_ID BIGINT) 

Entities: 
class Department 
{ 
    @Id 
    Long departmentId; 
    String name; 
    @Version 
    Long versionNumber; 
} 

class Employee 
{ 
    @Id 
    Long employeeId; 
    String name; 
    @ManyToOne 
    Department department; 
    @Version 
    Long versionNumber 
} 

(兩個類具有setter和getter所有字段和默認構造函數的方法,以主鍵作爲參數的構造函數) 現在,如果我想用departmentId保存員工(比如說100),是否需要先取得部門記錄,然後將其設置在員工中?

我不能直接創建Department實例(通過設置主鍵(departmentId))並在Employee中設置Department實例並保存Employee? 當我這樣做時,它拋出org.hibernate.TransientObjectException。

關於最佳實踐的任何建議都需要遵循嗎?如果要保存父不保存每個孩子

預先感謝您

回答

1

謝謝ChssPly76和Wysawyg。

其中一個解決方案可能是: 我們將更新員工POJO如下

ManyToOne(fetch=FetchType.EAGER) 
@**JoinColumn**(name = "DEPARTMENT_ID", referencedColumnName = "DEPARTMENT_ID", **insertable=false, updatable=false**) 
private Department department; 

@Column(name = "department_id") 
private Long departmentId; 

(包括部門和DepartmentID的將有setter和getter方法)

現在這裏(請參閱兩個部門和departmentId映射到同一列(DEPARTMENT_ID) 我們使用部門僅用於提取部門詳細信息 和departmentId以插入或更新員工

但我很擔心,如果這是一個更好的方法。

+0

我不知道誰降低了這個?他們可以辯解嗎? – 2011-06-07 22:58:19

1

,你需要映射它像(我不記得確切的語法)

@ManyToOne(CascadeType = Cascade.All) 
Department department; 

編輯:我犯了錯誤,認爲它是父母對孩子而不是孩子對父母。按照ChssPly76的例子。

7

如果你想你的Employee實例與`系實例相關聯,可以設置an appropriate cascading behavior,讓Hibernate來整個事情的護理:

class Employee { 
    ... 
    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) 
    Department department; 
} 

注意,你希望使用CascadeType.ALL,因爲刪除員工不應刪除部門。

如果OTOH,你想你的Employee實例與現有`系實例相關聯,你最好的辦法是的確加載它。您可以使用session.load()方法,該方法不會碰到數據庫

另一種解決方案是在Employee上使用session.merge()(其中級聯如上所述)將傳播到Department。雖然這可能有副作用。

+1

啊,我的壞,我錯過了打字,它是@ManyToOne而不是反之亦然。是的,Cascade.All會很糟糕! – Wysawyg 2009-12-14 18:36:51

+0

謝謝。我的要求沒有什麼不同。我根本不想打數據庫。 – 2009-12-17 12:58:38

+0

正如我上面所說的,使用'session.load()' - 直到你刷新/提交,它根本不會觸及數據庫。 – ChssPly76 2009-12-17 17:02:54

相關問題