.IdentifierGenerationException: пустой идентификатор, сгенерированный для: class

1

У меня есть следующие таблицы:

@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 генерируется для: class CustomerDeal

Это не дублирование этого вопроса

  • 0
    Какую БД вы используете? Как выглядит ваш файл persistence.xml?
  • 0
    @DirkSchumacher Я использую БД Oracle, без постоянства.xml
Показать ещё 3 комментария
Теги:
hibernate
jpa
jpql

2 ответа

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);
  • 0
    хм, но это отношение OneToMany. и я ищу отношения ManyToMany. так как у Клиента может быть много сделок И в одной сделке могут участвовать несколько клиентов
  • 0
    упс .. Изменено. Этот работает на меня.
1

Ваш код, который вызывает исключение, не имеет смысла, поэтому я думаю, что это не настоящий код.

CustomerDeal имеет составной ключ, поэтому вы не сможете получить его с помощью dealsRepository.findOne(1), что означает, что вы, вероятно, извлекали Deal not CustomerDeal, но тогда часть никогда не будет компилироваться:

Set<CustomerDeal>  custDealsSet = new HashSet<CustomerDeal>();
custDealsSet.add(dealsRepository.findOne(1)) 

Поэтому, кроме того, я предполагаю, что вы использовали существующие сделки. И вы создали нового клиента. Поскольку ключ CustomerDeal зависит как от клиента, так и от сделки, должен быть установлен как custumer, так и сделка, прежде чем продолжать его, что вы, вероятно, забыли сделать (и вы получили свое исключение). Поэтому он должен выглядеть так:

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 и hash в CustomerDeal, поэтому они основаны на идентификаторах (что типичный генератор кода для сущностей), оба новых экземпляра CustomerDeals имеют их как null, поэтому, когда вы добавляете их в набор, второй будет переопределять первый вставленный ( поскольку нулевые идентификаторы будут равны).

Вам также необходимо сообщить JPA, что идентификатор будет получен из отношений. В вашем CustomerDea вам нужно добавить аннотацию @MapsId (в обоих соединениях), например:

@MapsId("customerId")
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "CUSTOMER_ID", insertable = false, updatable = false)
private Customers customers;

Наконец, если таблица CustomerDeal не содержит дополнительных данных, кроме CUSTOMER_ID и Deal_ID, то это простая совместная таблица и не должна отображаться вообще. Таким образом, вы сэкономите массу неприятностей.

  • 0
    Спасибо, я исправил код. Мне нужно добавить дополнительную информацию. Я новичок в спящем и JPA. так что если вы можете добавить ссылки или пример, это будет здорово.
  • 0
    Это не ваш оригинальный код, поскольку он не имеет; на концах. Не могли бы вы вставить настоящий код или использовать мой и подтвердить, что вы все еще получаете исключение. Есть ли у вас необходимость в объекте CustomerDeal, есть ли у него какие-либо свойства?
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню