Reputation: 944
I have a class Customer that has a OneToOne bidirectional relationship with a Subscription:
@Entity
@Table(name = "customers")
public class Customer{
@OneToOne(mappedBy="customer",cascade = CascadeType.ALL)
private Subscription currentSubscription;
}
@Entity
@Table(name = "subscriptions")
public class Subscription {
@Id
@Column(columnDefinition = "INT8",name="id", unique=true, nullable=false)
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign", parameters=@Parameter(name="property", value="customer"))
private Long id;
@OneToOne
@PrimaryKeyJoinColumn
private Customer customer;
}
Now, when I create a customer with a subscription and call persist on the customer, it nicely saves the subscription as well into the database. However when I have already persisted a customer, and want to add a subscription, it fails with the following error:
Caused by: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [com.qmino.miredot.portal.domain.Subscription.customer]
I've written a test in order to explain what I want to achieve:
@Test
public void shouldCascadeUpdateSubscription(){
Customer owner = customerRepository.save(CustomerMother.getCustomer(false));
Subscription subscription = SubscriptionBuilder.create()
.setBillingDayOfMonth(LocalDate.now().getDayOfMonth())
.setSubscriptionPlan(subscriptionPlan)
.build();
subscription.setCustomer(owner);
owner.setCurrentSubscription(subscription);
customerRepository.save(owner);
Customer result = customerRepository.findOne(owner.getId());
assertThat(result.getCurrentSubscription(),is(notNullValue()));
assertThat(result.getCurrentSubscription().getId(),is(result.getId()));
}
Where did I go wrong?
Upvotes: 0
Views: 3168
Reputation: 26961
Cascade here is not the problem, Cascade indicates the action to be done by entity when deleted or updated. What is correct if you want to save complete entity. But for that, you need to have the correct data, your message suggest it tries to update the Customer
entity but it founds an empty AccountDetails
, so in order to correctly fetch the other entities, you need to add FecthType.EAGER
, to get all attributes of mapped entities.
@OneToOne(mappedBy="customer",cascade = CascadeType.ALL, fetch = FetchType.EAGER))
Upvotes: 2