JPA:如何保存两个具有一对一关系的实体?

时间:2014-08-04 06:36:58

标签: java spring jpa

假设您有以下两个实体,Address和Customer,它们之间具有一对一的映射。

@Entity
public class Address {    
    @Id @GeneratedValue
    private Long id;    
    private String street_1;
    private String street_2;    
    private String city;
    private String state;
    private String zipcode;
    private String country;

    @OneToOne(mappedBy = "address")
    private Customer customer;

    //getters, setters, and constructors
}

@Entity
public class Customer {

    @Id @GeneratedValue
    private Long id;  
    private String firstName;
    private String lastName;
    private String email;
    private String phoneNumber;

    @OneToOne @JoinColumn( name = "address_id" )
    private Address address;

    //getters, setters, and constructors
}

此外,我有这两个存储库类:

public interface AddressRepository extends CrudRepository<Address, Long> {
}

public interface CustomerRepository extends CrudRepository<Customer, Long> {
    List<Customer> findByLastName(String lastName);
    List<Customer> findByFirstName(String lastName);
}

我也有如下测试:

    Customer customer = new Customer('Jon', 'Doe')
    Address address = new Address(street_1: '1700 Sunlight Ave', state: 'CA',
        city: 'Boulder', zipcode: '12345', country: 'USA')
    customer.address = address
    address.customer = customer
    customerRepository.save( customer )
    addressRepository.save( address )

正如您所料,测试失败。例外情况也或多或少是预期的:

org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : foo.bar.model.Customer.address -> foo.bar.model.Address

我尝试切换两次保存的顺序,但正如预期的那样,它没有工作。那么,这个问题的解决方案是什么?

非常感谢。

1 个答案:

答案 0 :(得分:5)

@Entity
public class Address {    
    @Id @GeneratedValue
    private Long id;    
    private String street_1;
    private String street_2;    
    private String city;
    private String state;
    private String zipcode;
    private String country;

    @OneToOne(mappedBy = "address")
    private Customer customer;

    //getters, setters, and constructors
}

@Entity
public class Customer {

    @Id @GeneratedValue
    private Long id;  
    private String firstName;
    private String lastName;
    private String email;
    private String phoneNumber;

    @OneToOne(cascade = CascadeType.ALL) @JoinColumn( name = "address_id" )
    private Address address;

    //getters, setters, and constructors
}