2013-07-01 58 views
1

我的電話表具有電話號碼和ID的組合主鍵。 id也是Student表的外鍵。帶有在MySQL中不工作的外鍵的組合主鍵

我看到下面的錯誤,當我運行它。

23:30:28,228 ERROR SqlExceptionHelper:147 - 列 'ID' 不能爲空 org.hibernate.exception.ConstraintViolationException:無法執行語句

模式:

表:學生

Columns: 

id (PK) 
fName 
lName 
mName 

表:電話

Columns: 

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

Student.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; 
} 

} 

Phone.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; 
} 

} 

的hibernate.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> 

Main.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 [email protected] 
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 

回答

1

您可以創建embeddale P三角關鍵類。

@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; 
+0

感謝烏拉圭回合的答覆,但我想這不必給學生設置到手機工作。我希望所有的插入都是從學生側進行,而不是從雙方進行。我如何做到這一點? – nomula

+0

換句話說,這是有效的學生=新學生(); student.setfName(「Bob」); student.setlName(「Buster」); Set phones = new LinkedHashSet (); 電話ph1 =新電話(); ph1.setColor(「Black」); Phone_PK phonePK = new Phone_PK(); phonePK.setStudent(student); phonePK.setPhoneNumber(「1111111111」); ph1.setPK(phonePK); phones.add(ph1);但我不想做phonePK.setStudent(學生); – nomula