2009-12-14 84 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

相关问题