我有以下表格:

@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之外的其他表,否则它是一个简单的联合表,根本不应映射。这样,您将为自己省去很多麻烦。

07-27 18:27