Java 多对多额外列-MySQLIntegrityConstraintViolationException:column';波段ID';不能为空

Java 多对多额外列-MySQLIntegrityConstraintViolationException:column';波段ID';不能为空,java,hibernate,jpa,Java,Hibernate,Jpa,我试图保存一个具有多对多关系的实体,但收到一个错误 Band.java package it.entities; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import

我试图保存一个具有多对多关系的实体,但收到一个错误

Band.java

package it.entities;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;


/**
 * The persistent class for the band database table.
 * 
 */
@Entity
@Table(name="BAND")
@NamedQuery(name="Band.findAll", query="SELECT b FROM Band b")
public class Band implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", unique = true, nullable = false)
    private int id;

    @Column(name="DESCRIZIONE")
    private String descrizione;

    @Column(name="NOME")
    private String nome;

    //bi-directional many-to-one association to Audio
    @ManyToOne
    @JoinColumn(name="AUDIO_ID")
    private Audio audio;

    //bi-directional many-to-one association to Video
    @ManyToOne
    @JoinColumn(name="VIDEO_ID")
    private Video video;

    //bi-directional many-to-one association to Citta
    @ManyToOne
    @JoinColumn(name="CITTA_ID")
    private Citta citta;

    @OneToMany(mappedBy="pk.band", fetch = FetchType.LAZY, cascade={CascadeType.ALL})
    private List<BandHasMusicista> bandHasMusicista = new ArrayList<BandHasMusicista>();

    public Band() {
    }

    public int getId() {
        return this.id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getDescrizione() {
        return this.descrizione;
    }

    public void setDescrizione(String descrizione) {
        this.descrizione = descrizione;
    }

    public String getNome() {
        return this.nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public Audio getAudio() {
        return this.audio;
    }

    public void setAudio(Audio audio) {
        this.audio = audio;
    }

    public Video getVideo() {
        return this.video;
    }

    public void setVideo(Video video) {
        this.video = video;
    }

    public Citta getCitta() {
        return this.citta;
    }

    public void setCitta(Citta citta) {
        this.citta = citta;
    }

//  @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.band")
    public List<BandHasMusicista> getBandHasMusicista() {
        return bandHasMusicista;
    }

    public void setBandHasMusicista(List<BandHasMusicista> bandHasMusicista) {
        this.bandHasMusicista = bandHasMusicista;
    }

}
BandHasMusicistaPK.java

package it.entities;

import java.io.Serializable;

import javax.persistence.*;

/**
 * The primary key class for the band_has_musicista database table.
 * 
 */
@Embeddable
public class BandHasMusicistaPK implements Serializable {
    //default serial version id, required for serializable classes.
    private static final long serialVersionUID = 1L;

    private Band band;

    private Musicista musicista;

    public BandHasMusicistaPK() {
    }

    @ManyToOne
//  @JoinColumn(name="BAND_ID")
    public Band getBand() {
        return this.band;
    }

    public void setBand(Band band) {
        this.band = band;
    }

    @ManyToOne
//  @JoinColumn(name="MUSICISTA_ID")
    public Musicista getMusicista() {
        return this.musicista;
    }

    public void setMusicista(Musicista musicista) {
        this.musicista = musicista;
    }

}
Musicista.java

package it.entities;

import java.io.Serializable;

import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Transient;


/**
 * The persistent class for the band_has_musicista database table.
 * 
 */
@Entity
@Table(name="BAND_HAS_MUSICISTA")
@AssociationOverrides({
    @AssociationOverride(name = "pk.musicista", joinColumns = @JoinColumn(name = "MUSICISTA_ID")),
    @AssociationOverride(name = "pk.band", joinColumns = @JoinColumn(name = "BAND_ID"))})
@NamedQuery(name="BandHasMusicista.findAll", query="SELECT b FROM BandHasMusicista b")
public class BandHasMusicista implements Serializable {
    private static final long serialVersionUID = 1L;

    private BandHasMusicistaPK pk = new BandHasMusicistaPK();

    private Band band;

    private Musicista musicista;

    private boolean bandAccept;

    private boolean musicistaAccept;

    public BandHasMusicista() {
    }

    @EmbeddedId
    public BandHasMusicistaPK getPk() {
        return pk;
    }

    public void setPk(BandHasMusicistaPK pk) {
        this.pk = pk;
    }

    @Column(name="BAND_ACCEPT", nullable=false)
    public boolean getBandAccept() {
        return this.bandAccept;
    }

    public void setBandAccept(boolean bandAccept) {
        this.bandAccept = bandAccept;
    }

    @Column(name="MUSICISTA_ACCEPT", nullable=false)
    public boolean getMusicistaAccept() {
        return this.musicistaAccept;
    }

    public void setMusicistaAccept(boolean musicistaAccept) {
        this.musicistaAccept = musicistaAccept;
    }

    @Transient
//  @JoinColumn(name="BAND_ID")
    public Band getBand() {
        return this.band;
    }

    public void setBand(Band band) {
        this.band = band;
    }

    @Transient
//  @JoinColumn(name="MUSICISTA_ID")
    public Musicista getMusicista() {
        return this.musicista;
    }

    public void setMusicista(Musicista musicista) {
        this.musicista = musicista;
    }

}
package it.entities;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;


/**
 * The persistent class for the MUSICISTA database table.
 * 
 */
@Entity
@Table(name="MUSICISTA")
@NamedQuery(name="Musicista.findAll", query="SELECT m FROM Musicista m")
public class Musicista implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(generator="SharedPrimaryKeyGenerator")
    @GenericGenerator(name="SharedPrimaryKeyGenerator", strategy="foreign", parameters =  @Parameter(name="property", value="account"))
    @Column(name = "ID", unique = true, nullable = false)
    private int id;

    @Column(name="COGNOME", nullable=false, length=155)
    private String cognome;

    @Temporal(TemporalType.DATE)
    @Column(name="DATA_NASCITA")
    private Date dataNascita;

    @Column(name="NOME", nullable=false, length=155)
    private String nome;

    //bi-directional one-to-one association to Account
    @OneToOne
    @PrimaryKeyJoinColumn
    private Account account;

    @OneToMany(mappedBy="pk.musicista", fetch = FetchType.LAZY, cascade={CascadeType.ALL})
    private List<BandHasMusicista> bandHasMusicista = new ArrayList<BandHasMusicista>();

    public Musicista() {
    }

    public int getId() {
        return this.id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCognome() {
        return this.cognome;
    }

    public void setCognome(String cognome) {
        this.cognome = cognome;
    }

    public Date getDataNascita() {
        return this.dataNascita;
    }

    public void setDataNascita(Date dataNascita) {
        this.dataNascita = dataNascita;
    }

    public String getNome() {
        return this.nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public Account getAccount() {
        return this.account;
    }

    public void setAccount(Account account) {
        this.account = account;
    }

//  @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.musicista")
    public List<BandHasMusicista> getBandHasMusicista() {
        return bandHasMusicista;
    }

    public void setBandHasMusicista(List<BandHasMusicista> bandHasMusicista) {
        this.bandHasMusicista = bandHasMusicista;
    }

}
堆栈跟踪:

javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:614)
    at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:307)
    at it.logic.BandLogic.addBand(BandLogic.java:46)
    at it.interfaces.ServiceBean.addBand(ServiceBean.java:184)
    at it.test.BandTest.testAddBand(BandTest.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at junit.framework.TestCase.runTest(TestCase.java:176)
    at junit.framework.TestCase.runBare(TestCase.java:141)
    at junit.framework.TestResult$1.protect(TestResult.java:122)
    at junit.framework.TestResult.runProtected(TestResult.java:142)
    at junit.framework.TestResult.run(TestResult.java:125)
    at junit.framework.TestCase.run(TestCase.java:129)
    at junit.framework.TestSuite.runTest(TestSuite.java:255)
    at junit.framework.TestSuite.run(TestSuite.java:250)
    at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
    at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:304)
    ... 22 more
Caused by: java.sql.BatchUpdateException: Column 'BAND_ID' cannot be null
    at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2054)
    at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1467)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
    ... 28 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'BAND_ID' cannot be null
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.Util.getInstance(Util.java:386)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4187)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4119)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)
    at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2006)
    ... 31 more
在此代码中:

if(musicista != null){

            Band band = new Band();
            band.setNome(inVO.getNome());
            band.setDescrizione(inVO.getDescrizione());
            band.setCitta(citta);

            BandHasMusicista bandHasMusicista = new BandHasMusicista();
            bandHasMusicista.setBand(band);
            bandHasMusicista.setMusicista(musicista);
            bandHasMusicista.setBandAccept(true);
            bandHasMusicista.setMusicistaAccept(true);

            band.getBandHasMusicista().add(bandHasMusicista);

            em.persist(band);
            em.flush();
            em.clear();
        }
您正在创建一个新的
乐队
,然后尝试向乐队添加
Musicista
。问题是,在您执行
em.persist(band)
时,生成的SQL在保存
band
之前试图保存
Musicista
,因此自动生成的
band\u ID
仍然是
null
。将
波段
另存为

if(musicista != null){

            Band band = new Band();
            band.setNome(inVO.getNome());
            band.setDescrizione(inVO.getDescrizione());
            band.setCitta(citta);

            band = em.persist(band);

            BandHasMusicista bandHasMusicista = new BandHasMusicista();
            bandHasMusicista.setBand(band);
            bandHasMusicista.setMusicista(musicista);
            bandHasMusicista.setBandAccept(true);
            bandHasMusicista.setMusicistaAccept(true);

            band.getBandHasMusicista().add(bandHasMusicista);

            em.persist(band);
            em.flush();
            em.clear();
        }

应该可以工作(我认为您也可以在第一次保存时简单地执行
em.persist(band);
,但我不确定)。

不要使用您的代码。但奇怪的是,查询的顺序是:Hibernate:insert-into-BAND(AUDIO\u-ID,CITTA\u-ID,descripione,NOME,VIDEO\u-ID)值(?,,,,,,?)Hibernate:insert-into-BAND\u有\u-MUSICISTA(BAND\u-ACCEPT,MUSICISTA\u-ID,MUSICISTA\u-ID)值(?,,,,,?)实体管理器是否在persist上执行
flush
?这似乎与Hibernate的内部缓存有关(我不是专家),因此,如果在创建
BandHasMusicista
之前持久化并刷新,会发生什么?找到答案了吗?
if(musicista != null){

            Band band = new Band();
            band.setNome(inVO.getNome());
            band.setDescrizione(inVO.getDescrizione());
            band.setCitta(citta);

            band = em.persist(band);

            BandHasMusicista bandHasMusicista = new BandHasMusicista();
            bandHasMusicista.setBand(band);
            bandHasMusicista.setMusicista(musicista);
            bandHasMusicista.setBandAccept(true);
            bandHasMusicista.setMusicistaAccept(true);

            band.getBandHasMusicista().add(bandHasMusicista);

            em.persist(band);
            em.flush();
            em.clear();
        }