我有以下表格:
@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 for:class CustomerDeal
答案 0 :(得分:2)
抛出异常的代码没有意义,所以我猜这不是真正的代码。
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);
现在你可能还有麻烦。如果覆盖CustomerDeal上的equals和hash,使它们基于ID(实体的典型代码生成器),则两个新CustomerDeals实例都将它们作为null,因此当您将它们添加到集合时,第二个将覆盖第一个插入的( as null ids将等于)。
您还需要通知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之外的其他表,否则它是一个简单的联合表,根本不应该映射。这样你就可以省去很多麻烦。
答案 1 :(得分:1)
你得到上述错误的原因是由于映射问题(我无法弄清楚到底是什么错误)。作为一种完全不同的方法,我修改了你的映射。我测试了这个,它工作正常。这种映射的优势在于它使CustomerDeals
类成为冗余。请注意,我在使用MySQL时删除了序列。
@Entity
@Table(name = "CUSTOMERS")
public class Customer implements Serializable {
private static final long serialVersionUID = -5419345600310440297L;
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "CUSTOMER_ID")
private Long id;
@Column(name = "NAME")
private String name;
@ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinTable(
name="CUSTOMER_DEALS",
joinColumns = @JoinColumn( name="CUSTOMER_ID"),
inverseJoinColumns = @JoinColumn( name="DEAL_ID")
)
private Set<Deals> deals = new HashSet<Deals>();
//Setters and Getters to follow
}
交易类将是
@Entity
@Table(name = "DEALS")
public class Deals implements Serializable {
private static final long serialVersionUID = -7197428343863081750L;
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "DEAL_ID")
private Long dealId;
@Column(name = "DEAL_NAME")
private String dealColName;
@ManyToMany(fetch = FetchType.EAGER, mappedBy = "deals")
private Set<Customer> customers = new HashSet<Customer>(0);
//Setters and Getters here
}
最后进行插入的主要方法。
Customer customer = new Customer();
customer.setName("NewCust2");
Deals deals = new Deals();
deals.setDealColName("Deal2");
customer.getDeals().add(deals);
customerRepository.save(customer);