JPA 2 @ManyToMany java.sql.BatchUpdateException: Field ‘id’ doesn’t have a default value

Required: having a ManyToMany relation with JPA. Underlying ORM framework I use is Hibernate, but that is irrelevant here since JPA abstracts this.

The Entities
For a @ManyToMany we need two entities. Here we have a entity ‘Beurs’, which owns a collection of ‘Fonds’.

Beurs:

@Entity
@Table(name = “Beurs”)
public class Beurs implements Serializable {
private static final long serialVersionUID = -6250201709027758975L;

@Id
@Column(name = “beurscode”, unique = true, nullable = false)
private Long beurscode;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = “BeursFonds” , joinColumns = { @JoinColumn(name = “beurs_beurscode”, nullable = false, updatable = true) }
, inverseJoinColumns = { @JoinColumn(name = “fonds_fondscode”, nullable = false, updatable = true) })
private List fondsen;

Fonds:

@Entity
@Table(name = “Fonds”)
public class Fonds implements Serializable {
private static final long serialVersionUID = 4655056015858729584L;

@Id
@Column(name = “fondscode”)
private Long fondscode;

@ManyToMany(mappedBy = “fondsen”, fetch=FetchType.EAGER, cascade = CascadeType.ALL)
private List beurzen;

The Join Entity

@Entity
@Table(name = “BeursFonds”)
public class BeursFonds implements Serializable {

@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;

@Column(name = “beurs_beurscode”)
private Long beurscode;

@Column(name = “fonds_fondscode”)
private Long fondscode;

public BeursFonds() {
// default constructor for jpa
}

public BeursFonds(Long beurscode, Long fondscode) {
this.beurscode = beurscode;
this.fondscode = fondscode;
}

The entitymanager

public void store(Fonds fonds) {
List beurzen = fonds.getBeurzen();
for(Beurs beurs: beurzen) {
Beurs beursRepo = entityManager.find(Beurs.class, beurs.getBeurscode());

beursRepo.getFondsen().add(fonds);
entityManager.merge(beursRepo);
}
}

I have the ‘hibernate.hbm2ddl.auto’ set to value ‘update’, so when starting the webapplication with the new entities, these are auto generated. When you generated these tables by hand you might get the following exception. Solution: recreate the tables.

Caused by:
java.sql.BatchUpdateException: Field ‘id’ doesn’t have a default value
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2007)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1443)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.BatchingBatcher.addToBatch(BatchingBatcher.java:56)
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1207)