ORM 关联删除的一点疑惑

我刚开始试用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下也是可以的。

我想应该不能自动去删除``
因为你不能确保这样的情况:

  1. table user:
  2. id name email_id
  3. 1 kane 2
    2 li 1

  4. table email:
  5. id address
  6. 1 aaa@b.com
  7. 2 bbb@b.com

我刚想了下你的错误在于你不能直接再去创建一个新的emali对象,因为当你将新的emali对象赋给user的时候,当更新这个user的时候会将它的所有字段,当更新emali的时候,他会到相应的eamli表中根据emali的id去找这个emali,可以因为新建了这个emali,id是0,没有找到,所以他就会帮你新创建一条数据,但是你只是想去更改这个user的emali,这个你只能用先将user的emaliget()出来然后将emali的address修改即可,然然后将修改后的emali再给user即可或者更简单的方法是:

public void testAddEmail() {

User user = new User("kane");

Email email = new Email("aaa@b.com");

      email.setId(1);

user.setEmail(email);

um.add(user);

User user1 = um.find(user.getId());

user1.setEmail(new Email("bbb@b.com"));

um.update(user1);

}

即可``不知道我说的你明不明白

= = 我想你要明白的是当你重新将一个新的emali对象给user的时候那么以前的emali对象就再也没有引用指向这个对象了,当你在重新更新user的时候,orm框架是不能知道你以前还有个旧的emali存在``

你用的onetoone的关系,在数据库中,其实可以理解为manytoone的关系,所以在你更新user的时候,你new一个新的email的时候,旧email对象并不知道user中有多少引用它,当然是不能帮你删除的,逻辑需要你自己来控制。