我有一个Customer类,它具有与订阅的OneToOne双向关系:
@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;
}
现在,当我创建一个订阅客户并在客户上保持呼叫时,它可以很好地将订阅保存到数据库中。但是,当我已经保留了一个客户并希望添加订阅时,它会因以下错误而失败:
引起:org.hibernate.id.IdentifierGenerationException:尝试过 从null一对一属性中分配id [com.qmino.miredot.portal.domain.Subscription.customer]
我已经写了一个测试来解释我想要实现的目标:
@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()));
}
我哪里出错了?
答案 0 :(得分:2)
此处级联不是问题,Cascade指示实体在删除或更新时要执行的操作。如果要保存完整的实体,这是正确的。但为此,您需要拥有正确的数据,您的消息建议它尝试更新Customer
实体,但它发现空AccountDetails
,因此为了正确获取其他实体,您需要添加FecthType.EAGER
,以获取映射实体的所有属性。
@OneToOne(mappedBy="customer",cascade = CascadeType.ALL, fetch = FetchType.EAGER))