JBT
JBT

Reputation: 8746

JPA: How to save two entities that have one-to-one relation?

Suppose you have the following two entities, Address and Customer, which have a one-to-one mapping between them.

@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
}

Additionally, I have these two repository classes:

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

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

I also have test like below:

    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 )

As you might expect, the test fails. The exception is also more or less expected:

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

I tried switching the order of the two saves, but as expected, it didn't work. So, what is the solution to this problem?

Many thanks.

Upvotes: 5

Views: 12879

Answers (1)

shlomi33
shlomi33

Reputation: 1568

@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
}

Upvotes: 4

Related Questions