【发布时间】:2016-02-14 07:23:01
【问题描述】:
我在Employee 和Phone 实体之间有一个简单的one-to-many 关系。
我这里有 2 个问题。
场景 1:
@Entity
public class Employee {
@Id
@GeneratedValue
private long id;
private String firstName;
private String lastName;
private double salary;
@OneToMany
@JoinColumn(name = "parent_id", referencedColumnName = "id", insertable=false, updatable=false)
private List<Phone> phones = new ArrayList<Phone>(0);
// Setters & Getter methods
}
Phone.java
@Entity
public class Phone {
@Id
private long id;
private String type;
private int areaCode;
private String phoneNumber;
// Setter & Getters
}
现在我创建了员工实例并向其中添加了 2 部电话。
Employee e1 = new Employee(10,"Bob", "Way",50000);
Phone p1 = new Phone(1,"home",613,"792-0000");
Phone p2 = new Phone(2,"work",613,"896-1234");
e1.addPhone(p1);
e1.addPhone(p2);
然后在休眠中,如果我使用下面的代码:
session.save(e1);
session.save(p1);
session.save(p2);
或者如果我保存phone 然后employee
session.save(p1);
session.save(p2);
session.save(e1);
在这两种情况下,Hibernate 只运行 insert 查询而没有任何 update 查询,但 foreign key 设置为 NULL。
mysql> select * from Phone;
+----+----------+-------------+------+-----------+
| id | areaCode | phoneNumber | type | parent_id |
+----+----------+-------------+------+-----------+
| 1 | 613 | 792-0000 | home | NULL |
| 2 | 613 | 896-1234 | work | NULL |
| 3 | 416 | 123-4444 | work | NULL |
+----+----------+-------------+------+-----------+
我该如何解决这个问题?请让我知道我在哪里犯了错误。
场景 2:
现在,如果我在Employee 表中更改我的@JoinColumn,如下所示:
@JoinColumn(name = "parent_id")
然后 Hibernate 生成 **insert** 然后 update 查询以正确映射外键。
Hibernate: insert into Employee (firstName, lastName, salary) values (?, ?, ?)
Hibernate: insert into Phone (areaCode, phoneNumber, type, id) values (?, ?, ?, ?)
Hibernate: insert into Phone (areaCode, phoneNumber, type, id) values (?, ?, ?, ?)
Hibernate: insert into Phone (areaCode, phoneNumber, type, id) values (?, ?, ?, ?)
Hibernate: update Phone set parent_id=? where id=?
Hibernate: update Phone set parent_id=? where id=?
当 Hibernate 在 Employee 表上运行 insert 时,它自己会在那里获得 employee id,那么当 Hibernate 通过包含外键值?
我知道在update 查询中它正在添加外键,但我想知道为什么这不是在电话表上的insert 查询本身中管理的。你能解释一下吗?
场景 3:
如果我这样说:
@JoinColumn(name = "OWNER_ID", insertable=false, updatable=false, nullable=false)
然后我得到以下异常:
Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value : onetomany.Phone._phones_OWNER_IDBackref
【问题讨论】:
-
对于场景 1) 和 3),您指定了
insertable=false, updatable=false,因此不保存这些值的原因很明显。对于场景 2),正如@NitinPrabhu 已经指出的那样,这些问题的重复。 -
@DraganBozanovic,你能告诉我们什么时候需要使用
insertable=false, updatable=false吗?
标签: java mysql hibernate hibernate-onetomany