I have 2 JPA entities that resemble the following:
@Entity
class Customer {
@Id
@GeneratedValue
Long id
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
CustomerInformation customerInformation
}
@Entity
class CustomerInformation {
@Id
@OneToOne
@JoinColumn(name = "id")
Customer customer
String firstName
String lastName
}
I’m using spring-data-jpa to generate my DAO layer. Here it is, though it’s not very interesting:
public interface CustomerRepository extends CrudRepository<Customer, Long> {
}
I’m calling this in a spring context and using @Transactional annotations to tell the JPA provider when to commit the transaction to the database. For testing, I grab the entity manager using @PersistenceContext and manually flush it to end the transaction. Due to the nature of our application, there may be a Customer that exists in the database without a customerInformation object associated with it. If I create a new customer and a customerInformation object in the same transaction, things work as I expect them. For example, this works:
@Transactional
public void createNewCustomer() {
Customer cust = new Customer();
CustomerInformation custInf = new CustomerInformation;
custInf.setCustomer(cust);
custInf.setFirstName("asdf");
custInf.setLastName("hjkl");
cust.setCustomerInformation(custInf);
customerRepository.save(cust);
}
But if I want to update an existing customer, I run into an issue where it tries to insert the CustomerInformation object with a null id. For example, this fails miserably:
@Transactional
public void updateExistingCustomer(Long userId) {
Customer foundCustomer = customerRepository.findOne(userId);
if (foundCustomer.getCustomerInformation() == null) {
CustomerInformation custInf = new CustomerInformation();
custInf.setCustomer(foundCustomer);
custInf.setFirstName("asdf");
custInf.setLastName("hjkl");
cust.setCustomerInformation(custInf);
customerRepository.save(foundCustomer);
}
}
This fails with the error message:
Hibernate: insert into CustomerInformation (firstName, lastName, id) values (?, ?, ?)
Feb 1, 2013 7:40:12 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 20000, SQLState: 23502
Feb 1, 2013 7:40:12 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Column 'ID' cannot accept a NULL value.
Am I misunderstanding something? Any help is appreciated.
Thanks in advance!
I modified the entity to look like this:
And everything worked. As far as I could tell, both versions of
CustomerInformationwould have resulted in the same SQL, except the second version models the actual id, which I don’t necessarily need. I’ll expand this in another question, but the above code solved my problem.