如果Address嵌套在User中,为什么我必须保留两个对象?

时间:2012-09-28 14:24:46

标签: java jpa

我想更好地熟悉JPA,所以我创建了一个非常简单的项目。我有一个User Class和一个Address类。看来我必须坚持两个,即使我正在向我的用户类添加地址吗?

用户:

import javax.persistence.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Entity
@Table(name = "usr") // @Table is optional, but "user" is a keyword in many SQL variants 
@NamedQuery(name = "User.findByName", query = "select u from User u where u.name = :name")
public class User {
    @Id // @Id indicates that this it a unique primary key
    @GeneratedValue // @GeneratedValue indicates that value is automatically generated by the server
    private Long id;

    @Column(length = 32, unique = true)
    // the optional @Column allows us makes sure that the name is limited to a suitable size and is unique
    private String name;

    // note that no setter for ID is provided, Hibernate will generate the ID for us

    @OneToMany(fetch=FetchType.LAZY, mappedBy="user")
    private List<Address> addresses;

地址:

@Entity
public class Address {

    @Id // @Id indicates that this it a unique primary key
    @GeneratedValue // @GeneratedValue indicates that value is automatically generated by the server
    private Long id;

    @Column(length=50)
    private String address1;

    @ManyToOne
    @JoinColumn(name="user_id")
    private User user;

的EntityManager:

EntityManager entityManager = Persistence.createEntityManagerFactory("tutorialPU").createEntityManager();

entityManager.getTransaction().begin();

User user = new User();
user.setName("User");

List<Address> addresses = new ArrayList<Address>();
Address address = new Address();
address.setAddress1("Address1");

addresses.add(address);
user.setAddresses(addresses);
entityManager.persist(user);
entityManager.persist(address);
entityManager.getTransaction().commit();
entityManager.close();

可能做错了什么......只是不确定它是什么?

任何建议将不胜感激。

谢谢,

取值

3 个答案:

答案 0 :(得分:10)

尝试注释的cascade元素。

@OneToMany(fetch=FetchType.LAZY, mappedBy="user", cascade=CascadeType.PERSIST) 
private List<Address> addresses; 

documentation表示默认情况下不会级联任何操作。它还声明级联操作是可选的,因此它实际上取决于您正在使用的实现。

此外,在设置关系时,请确保设置关系的两侧。将地址设置为用户和用户的地址。

答案 1 :(得分:6)

你在说什么叫做级联。这意味着对嵌套对象执行相同的操作,例如Address中的User。默认情况下,如果您未指定任何CascadeType,则根本没有级联。

您可以一次定义各种级联类型

@OneToMany(fetch=FetchType.LAZY, mappedBy="user", cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
private List<Address> addresses;

或者告诉JPA级联每个操作:

@OneToMany(fetch=FetchType.LAZY, mappedBy="user", cascade = CascadeType.ALL)
private List<Address> addresses;

在移除Address时,这两种方式都会导致User持续存在Address或删除关联的User

但是!...如果从第一个示例中删除CascadeType.REMOVE,删除User将不会删除其关联的Address(删除操作不会应用于嵌套对象)。

答案 2 :(得分:0)

您正在使用oneToMany注释。根据我的理解,当你想要为它添加子类(地址)时,你必须坚持父类(USer)。

通过持久化User类,您可以让JPA知道要更新的行。