我刚开始试用ORM,上层采用的是JPA,实现是用hibernate. 在测试中我发现了一个比较疑惑的地方,请大家帮忙看看:
实体 User.java
[code="java"]
import javax.persistence.*;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
@OneToOne(cascade = CascadeType.ALL)
Email email;
public User() {
}
public User(String name) {
this.name = name;
}
public Email getEmail() {
return email;
}
public void setEmail(Email email) {
this.email = email;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", email=" + email +
'}';
}
}
[/code]
Email.java
[code="java"]
public class Email {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
long id;
String address;
public Email() {
}
public Email(String email) {
this.address = email;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Email{" +
"id=" + id +
", address='" + address + '\'' +
'}';
}
}
[/code]
测试代码:
[code="java"]
@Test
public void testAddEmail() {
User user = new User("kane");
Email email = new Email("aaa@b.com");
user.setEmail(email);
um.add(user);
User user1 = um.find(user.getId());
user1.setEmail(new Email("bbb@b.com"));
um.update(user1);
}
[/code]
上述代码中,我先创建一个user对象和一个email对象(aaa@b.com),并将该email对象赋给该user对象。这时查看数据库中的数据是这样的:
[code="java"]
table user:
id name email_id
1 kane 2
table email:
id address
1 aaa@b.com
[/code]
之后我重新获取该user对象,并赋予另一个新的email对象(bbb@b.com)。我本来以为老的email将被删除,数据库中的数据应该变成:
[code="java"]
table user:
id name email_id
1 kane 2
table email:
id address
2 bbb@b.com
[/code]
但实际上那条老的email数据还存在,数据库中数据是这样的:
[code="java"]
table user:
id name email_id
1 kane 2
table email:
id address
1 aaa@b.com
2 bbb@b.com
[/code]
请问各位,这是ORM本来就这样设计的吗?如果我需要将老的数据自动删除,有什么办法吗?还是说需要手动删除老的email对象?
那有没有办法建立严格的one-to-one的关系呢?
答案是没有,在数据库中onetoone是通过外键约束和唯一性约束来确定的。
其实更新的话,直接更新就好了,为什么要new了,即使要new,那你先remove下也是可以的。
我想应该不能自动去删除``
因为你不能确保这样的情况:
我刚想了下你的错误在于你不能直接再去创建一个新的emali对象,因为当你将新的emali对象赋给user的时候,当更新这个user的时候会将它的所有字段,当更新emali的时候,他会到相应的eamli表中根据emali的id去找这个emali,可以因为新建了这个emali,id是0,没有找到,所以他就会帮你新创建一条数据,但是你只是想去更改这个user的emali,这个你只能用先将user的emaliget()出来然后将emali的address修改即可,然然后将修改后的emali再给user即可
或者更简单的方法是:
email.setId(1);
即可``不知道我说的你明不明白
= = 我想你要明白的是当你重新将一个新的emali对象给user的时候
那么以前的emali对象就再也没有引用指向这个对象了,当你在重新更新user的时候,orm框架是不能知道你以前还有个旧的emali存在``
你用的onetoone的关系,在数据库中,其实可以理解为manytoone的关系,所以在你更新user的时候,你new一个新的email的时候,旧email对象并不知道user中有多少引用它,当然是不能帮你删除的,逻辑需要你自己来控制。