我有以下表格:
@Entity
@Table(name = "CUSTOMER")
public class Customers implements Serializable {
private static final long serialVersionUID = -5419345600310440297L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "cust")
@SequenceGenerator(name = "cust", sequenceName = "cust_ID_SEQ")
@Column(name = "CUSTOMER_ID")
private Long id;
@Column(name = "NAME")
private String name;
@OneToMany(mappedBy = "customer", cascade = CascadeType.PERSIST)
private Set<CustomerDeal> customerDeals;
//getters and setters goes here ....
}
@Entity
@Table(name = "DEALS")
public class Deals implements Serializable {
private static final long serialVersionUID = -7197428343863081750L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "deals_seq")
@SequenceGenerator(name = "deals_seq", sequenceName = "DEALS_SEQ")
@Column(name = "DEAL_ID")
private Long dealId;
@Column(name = "DEAL_NAME")
private String dealColName;
//getters setters
}
@Entity
@Table(name = "CUSTOMER_DEALS")
public class CustomerDeals implements Serializable {
private static final long serialVersionUID = -4249326793843278525L;
@EmbeddedId
private CustomerDealId customerDealId;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "CUSTOMER_ID", insertable = false, updatable = false)
private Customers customers;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "DEAL_ID", insertable = false, updatable = false)
private Deals deals;
//getters setters
}
@Embeddable
public class CustomerDealId implements Serializable {
private static final long serialVersionUID = 9086627167426987610L;
@Column(name = "DEAL_ID")
private Long dealId;
@Column(name = "CUSTOMER_ID")
private Long customerId;
}
但是,当我尝试创建新客户时
Customer cust - new Customer ()
cust.setName("Foo")
CustomerDeals custDeals = new CustomerDeals()
Set<CustomerDeal> custDealsSet = new HashSet<CustomerDeal>
CustomerDeal custDealsSet1 = new CustomerDeal()
CustomerDeal custDealsSet2 = new CustomerDeal()
custDealsSet1.setDeals(dealsRepository.findOne(1))//getting existing deal
custDealsSet1.customers(cust)
custDealsSet2.setDeals(dealsRepository.findOne(2))//getting existing deal
custDealsSet2.customers(cust)
custDealsSet.add(custDealsSet1)
custDealsSet.add(custDealsSet2)
cust.setCustomerDeals(custDealsSet)
customerRepository.saveAndFlush(cust)
customerRepository.saveAndFlush(cust)
我正进入(状态
org.hibernate.id.IdentifierGenerationException:生成的null ID
适用于:Classic CustomerDeal
这不是this question的重复项
最佳答案
您的引发异常的代码没有意义,所以我猜它不是真实的代码。
CustomerDeal具有复合密钥,因此您将无法使用dealsRepository.findOne(1)
对其进行检索,这意味着您可能不是在检索Deal而不是CustomerDeal,而是该部分永远不会编译:
Set<CustomerDeal> custDealsSet = new HashSet<CustomerDeal>();
custDealsSet.add(dealsRepository.findOne(1))
因此,除此之外,我想您正在检索现有交易。然后您结识了新客户。由于CustomerDeal的关键取决于客户和交易,因此必须先设置客户和交易,然后再保留它,而您可能会忘记这样做(并且您得到了例外)。所以它应该看起来像:
Customer cust - new Customer ();
cust.setName("Foo");
CustomerDeals custDeal = new CustomerDeals();
custDeal.setCustomer(cust);
custDeal.setDeal(dealsRepository.findOne(1));
cust.getCustomerDeals().add(custDeal);
custDeal = new CustomerDeals();
custDeal.setCustomer(cust);
custDeal.setDeal(dealsRepository.findOne(2));
cust.getCustomerDeals().add(custDeal);
customerRepository.saveAndFlush(cust);
现在您可能仍然有麻烦。如果您覆盖equals并在CustomerDeal上进行哈希处理,因此它们是基于ID的(实体的典型代码生成器会这样做),则两个新的CustomerDeals实例都将它们设置为null,因此,将它们添加到集合中时,第二个将覆盖第一个插入的(因为空ID等于)。
您还需要通知JPA该ID将来自该关系。
在您的CustomerDea中,您需要添加
@MapsId
批注(在两个联接上),例如:@MapsId("customerId")
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "CUSTOMER_ID", insertable = false, updatable = false)
private Customers customers;
最后,除非您的CustomerDeal表包含除CUSTOMER_ID和Deal_ID之外的其他表,否则它是一个简单的联合表,根本不应映射。这样,您将为自己省去很多麻烦。