1

我的电话表有一个电话号码和 id 的复合主表。id 也是 Student 表的外键。

我在运行它时看到以下错误。

23:30:28,228 错误 SqlExceptionHelper:147 -列“id”不能为空 org.hibernate.exception.ConstraintViolationException:无法执行语句

架构:

表:学生

Columns:

id (PK)
fName
lName
mName

表:电话

Columns:

phoneNumber (PK)
color
id(PK)(FK references to Student id)

学生.java

import java.io.Serializable;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;

@Entity
@SuppressWarnings("serial")
public class Student implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;

private String fName;

private String lName;

private String mname;

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "id")
private Set<Phone> phones;

/**
 * @return the fName
 */
public String getfName() {
    return fName;
}

/**
 * @return the id
 */
public int getId() {
    return id;
}

/**
 * @return the lName
 */
public String getlName() {
    return lName;
}

/**
 * @return the mname
 */
public String getMname() {
    return mname;
}

/**
 * @return the phones
 */
public Set<Phone> getPhones() {
    return phones;
}

/**
 * @param fName
 *            the fName to set
 */
public void setfName(final String fName) {
    this.fName = fName;
}

/**
 * @param id
 *            the id to set
 */
public void setId(final int id) {
    this.id = id;
}

/**
 * @param lName
 *            the lName to set
 */
public void setlName(final String lName) {
    this.lName = lName;
}

/**
 * @param mname
 *            the mname to set
 */
public void setMname(final String mname) {
    this.mname = mname;
}

/**
 * @param phones
 *            the phones to set
 */
public void setPhones(final Set<Phone> phones) {
    this.phones = phones;
}

}

电话.java

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

@IdClass(PhonePK.class)
@Entity
@SuppressWarnings("serial")
public class Phone implements Serializable {

@Id
private String phoneNumber;

//    @Id
//    @ManyToOne
//    @JoinColumn(name = "id", insertable = false, updatable = false)
//    private String id;

@Id
@ManyToOne
@JoinColumn(name = "id", insertable = false, updatable = false)
private Student student;

//    public String getId() {
//      return id;
//  }
//
//  public void setId(String id) {
//      this.id = id;
//  }

private String color;

/**
 * @return the color
 */
public String getColor() {
    return color;
}

/**
 * @return the phoneNumber
 */
public String getPhoneNumber() {
    return phoneNumber;
}

/**
 * @return the student
 */
public Student getStudent() {
    return student;
}

/**
 * @param color
 *            the color to set
 */
public void setColor(final String color) {
    this.color = color;
}

/**
 * @param phoneNumber
 *            the phoneNumber to set
 */
public void setPhoneNumber(final String phoneNumber) {
    this.phoneNumber = phoneNumber;
}

/**
 * @param student
 *            the student to set
 */
public void setStudent(final Student student) {
    this.student = student;
}

}

PhonePK.java

import java.io.Serializable;

@SuppressWarnings("serial")
public class PhonePK implements Serializable {

private String phoneNumber;
//private String id;

private Student student;

//    public String getId() {
//      return id;
//  }
//
//  public void setId(String id) {
//      this.id = id;
//  }

/**
 * @return the phoneNumber
 */
public String getPhoneNumber() {
    return phoneNumber;
}

/**
 * @return the student
 */
public Student getStudent() {
    return student;
}

/**
 * @param phoneNumber
 *            the phoneNumber to set
 */
public void setPhoneNumber(final String phoneNumber) {
    this.phoneNumber = phoneNumber;
}

/**
 * @param student
 *            the student to set
 */
public void setStudent(final Student student) {
    this.student = student;
}

  @Override
  public boolean equals(final Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    if (getClass() != obj.getClass()) {
        return false;
    }
    PhonePK other = (PhonePK) obj;
    if (phoneNumber == null) {
        if (other.phoneNumber != null) {
            return false;
        }
    } else if (!phoneNumber.equals(other.phoneNumber)) {
        return false;
    }
    if (student == null) {
        if (other.student != null) {
            return false;
        }
    } else if (!student.equals(other.student)) {
        return false;
    }
//        if (id == null) {
//            if (other.id != null) {
//                return false;
//            }
//        } else if (!id.equals(other.id)) {
//            return false;
//        }

    return true;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((phoneNumber == null) ? 0 : phoneNumber.hashCode());
    result = prime * result + ((student == null) ? 0 : student.hashCode());
//        result = prime * result + ((id == null) ? 0 : id.hashCode());

    return result;
}

}

休眠.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">pwd</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="hibernate.connection.username">user</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.pool_size">1</property>
<property name="hbm2ddl.auto">create</property>
</session-factory>
</hibernate-configuration>

主.java

import java.util.LinkedHashSet;
import java.util.Set;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class Main {

 public static void main(final String args[]) {

    Configuration configuration = new Configuration();
    Transaction transaction = null;

    configuration.addAnnotatedClass(Student.class);
    configuration.addAnnotatedClass(Phone.class);
    configuration.addAnnotatedClass(PhonePK.class);
    configuration.configure("hibernate.cfg.xml");

    SessionFactory sessionFactory = configuration.buildSessionFactory();
    System.out.println("Session Factory!!!!" + sessionFactory);

    Session session = sessionFactory.openSession();


    Student student = new Student();
    student.setfName("Bob");
    student.setlName("Buster");
    Set<Phone> phones = new LinkedHashSet<Phone>();
    Phone ph1 = new Phone();
    ph1.setColor("Black");
    ph1.setPhoneNumber("1111111111");

    Phone ph2 = new Phone();
    ph2.setColor("Blue");
    ph2.setPhoneNumber("2222222222");
    phones.add(ph1);
    phones.add(ph2);

    student.setPhones(phones);

    try {
        transaction = session.beginTransaction();
        session.save(student);
        transaction.commit();
    } catch (HibernateException e) {
        transaction.rollback();
        e.printStackTrace();
    } finally {
        session.close();
    }

        }
}

控制台输出:

23:30:24,291  INFO SchemaExport:343 - HHH000227: Running hbm2ddl schema export
23:30:24,296 DEBUG SQL:104 - alter table Phone drop foreign key   
FK_aoj0eivd0ap3drxnoyk4xj10q
23:30:25,613 DEBUG SQL:104 - drop table if exists Phone
23:30:25,967 DEBUG SQL:104 - drop table if exists Student
23:30:26,230 DEBUG SQL:104 - create table Phone (phoneNumber varchar(255) not null,   
color varchar(255), id integer not null, primary key (phoneNumber, id))
23:30:26,731 DEBUG SQL:104 - create table Student (id integer not null auto_increment,  
fName varchar(255), lName varchar(255), mname varchar(255), primary key (id))
23:30:26,792 DEBUG SQL:104 - alter table Phone add index FK_aoj0eivd0ap3drxnoyk4xj10q   
(id), add constraint FK_aoj0eivd0ap3drxnoyk4xj10q foreign key (id) references Student    
(id)
23:30:27,352  INFO SchemaExport:405 - HHH000230: Schema export complete
Session Factory!!!!org.hibernate.internal.SessionFactoryImpl@548997d1
23:30:27,823 DEBUG SQL:104 - insert into Student (fName, lName, mname) values (?, ?, ?)
23:30:27,886 TRACE BasicBinder:84 - binding parameter [1] as [VARCHAR] - Bob
23:30:27,887 TRACE BasicBinder:84 - binding parameter [2] as [VARCHAR] - Buster
23:30:27,888 TRACE BasicBinder:72 - binding parameter [3] as [VARCHAR] - <null>
23:30:28,005 DEBUG SQL:104 - select phone_.phoneNumber, phone_.id, phone_.color as    
color2_0_ from Phone phone_ where phone_.phoneNumber=? and phone_.id=?
23:30:28,009 TRACE BasicBinder:84 - binding parameter [1] as [VARCHAR] - 1111111111
23:30:28,010 TRACE BasicBinder:72 - binding parameter [2] as [INTEGER] - <null>
23:30:28,102 DEBUG SQL:104 - select phone_.phoneNumber, phone_.id, phone_.color as     
color2_0_ from Phone phone_ where phone_.phoneNumber=? and phone_.id=?
23:30:28,103 TRACE BasicBinder:84 - binding parameter [1] as [VARCHAR] - 2222222222
23:30:28,104 TRACE BasicBinder:72 - binding parameter [2] as [INTEGER] - <null>
23:30:28,222 DEBUG SQL:104 - insert into Phone (color, phoneNumber, id) values (?, ?,    

?)
23:30:28,223 TRACE BasicBinder:84 - binding parameter [1] as [VARCHAR] - Black
23:30:28,224 TRACE BasicBinder:84 - binding parameter [2] as [VARCHAR] - 1111111111
23:30:28,224 TRACE BasicBinder:72 - binding parameter [3] as [INTEGER] - <null>
23:30:28,227  WARN SqlExceptionHelper:145 - SQL Error: 1048, SQLState: 23000
23:30:28,228 ERROR SqlExceptionHelper:147 - Column 'id' cannot be null
org.hibernate.exception.ConstraintViolationException: could not execute statement
at   
 org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert
 (SQLExceptionTypeDelegate.java:74)
at   org.hibernate.exception.internal.StandardSQLExceptionConverter.convert
 (StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert
 (SqlExceptionHelper.java:125)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert
 (SqlExceptionHelper.java:110)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate
 (ResultSetReturnImpl.java:136)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch
 (NonBatchingBatch.java:58)
at org.hibernate.persister.entity.AbstractEntityPersister.insert
 (AbstractEntityPersister.java:3067)
at org.hibernate.persister.entity.AbstractEntityPersister.insert
 (AbstractEntityPersister.java:3509)
at org.hibernate.action.internal.EntityInsertAction.execute
 (EntityInsertAction.java:88)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:377)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:369)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:286)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions
   (AbstractFlushingEventListener.java:339)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush
  (DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)
at   org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.
   beforeTransactionCommit
 (JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit
  (AbstractTransactionImpl.java:175)
at Main.main(Main.java:49)
   Caused by:      
   com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 
   Column '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.executeUpdate(PreparedStatement.java:2375)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate
    (ResultSetReturnImpl.java:133)
... 14 more
    23:30:28,323  INFO AbstractBatchImpl:195 - HHH000010:
   On release of batch it still   contained JDBC statements
4

1 回答 1

1

您可以创建嵌入主键类。

@Embeddable
public class Phone_pk implements Serializable{
    @ManyToOne(targetEntity=Student.class)
    @JoinColumn(name="id", referencedColumnName="id")
    @ForeignKey(name="Student_Phone_FK")
    private Student student;

    private String phoneNumber;

}

并将其用作电话类中的主键

@EmbeddedId
private Phone_pk PK;
于 2013-07-01T05:25:57.390 回答