我正在学习Spring并尝试使用Hibernate创建一个简单的应用程序,但在将数据插入数据库时,我得到了一些关于表之间关系的JdbcSQLExceptions。
我正在使用H2-in-memory数据库。我的schema.sql
文件是:
DROP TABLE IF EXISTS CONTACT;
CREATE TABLE CONTACT(
ID INT NOT NULL AUTO_INCREMENT,
FIRST_NAME VARCHAR(60) NOT NULL,
LAST_NAME VARCHAR(40) NOT NULL,
BIRTH_DATE DATE,
VERSION INT NOT NULL DEFAULT 0,
UNIQUE UQ_CONTACT_1 (FIRST_NAME, LAST_NAME),
PRIMARY KEY (ID)
);
DROP TABLE IF EXISTS HOBBY;
CREATE TABLE HOBBY (
HOBBY_ID VARCHAR(20) NOT NULL,
PRIMARY KEY (HOBBY_ID)
);
DROP TABLE IF EXISTS CONTACT_TEL_DETAIL;
CREATE TABLE CONTACT_TEL_DETAIL (
ID INT NOT NULL AUTO_INCREMENT,
CONTACT_ID INT NOT NULL,
TEL_TYPE VARCHAR(20) NOT NULL,
TEL_NUMBER VARCHAR(20) NOT NULL,
VERSION INT NOT NULL DEFAULT 0,
UNIQUE UQ_CONTACT_TEL_DETAIL_1 (CONTACT_ID, TEL_TYPE),
PRIMARY KEY (ID),
CONSTRAINT FK_CONTACT_TEL_DETAIL_1 FOREIGN KEY (CONTACT_ID)
REFERENCES CONTACT (ID)
);
DROP TABLE IF EXISTS CONTACT_HOBBY_DETAIL;
CREATE TABLE CONTACT_HOBBY_DETAIL (
CONTACT_ID INT NOT NULL,
HOBBY_ID VARCHAR(20) NOT NULL,
PRIMARY KEY (CONTACT_ID, HOBBY_ID),
CONSTRAINT FK_CONTACT_HOBBY_DETAIL_1 FOREIGN KEY (CONTACT_ID)
REFERENCES CONTACT (ID) ON DELETE CASCADE,
CONSTRAINT FK_CONTACT_HOBBY_DETAIL_2 FOREIGN KEY (HOBBY_ID)
REFERENCES HOBBY (HOBBY_ID)
);
insert into contact (first_name, last_name, birth_date) values ('Chris', 'Schaefer', '1981-05-03');
insert into contact (first_name, last_name, birth_date) values ('Scott', 'Tiger', '1990-11-02');
insert into contact (first_name, last_name, birth_date) values ('John', 'Smith', '1964-02-28');
insert into contact_tel_detail (contact_id, tel_type, tel_number) values (1, 'Mobile','1234567890');
insert into contact_tel_detail (contact_id, tel_type, tel_number) values (1, 'Home', '1234567890');
insert into contact_tel_detail (contact_id, tel_type, tel_number) values (2, 'Home', '1234567890');
insert into hobby (hobby_id) values ('Swimming');
insert into hobby (hobby_id) values ('Jogging');
insert into hobby (hobby_id) values ('Programming');
insert into hobby (hobby_id) values ('Movies');
insert into hobby (hobby_id) values ('Reading');
insert into contact_hobby_detail(contact_id, hobby_id) values (1, 'Swimming');
insert into contact_hobby_detail(contact_id, hobby_id) values (1, 'Movies');
insert into contact_hobby_detail(contact_id, hobby_id) values (2, 'Swimming');
异常在执行第一个insert语句时开始。例外是:
Caused by: org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement at line 1 of resource class path resource [test-data.sql]: insert into contact (first_name, last_name, birth_date) values ('Chris', 'Schaefer', '1981-05-03')
at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.executeSqlScript(ResourceDatabasePopulator.java:202)
at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.populate(ResourceDatabasePopulator.java:135)
at org.springframework.jdbc.datasource.init.CompositeDatabasePopulator.populate(CompositeDatabasePopulator.java:56)
at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:47)
... 37 more
Caused by: org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "UQ_CONTACT_1_INDEX_6 ON PUBLIC.CONTACT(FIRST_NAME, LAST_NAME) VALUES ('Chris', 'Schaefer', 1)"; SQL statement:
insert into contact (first_name, last_name, birth_date) values ('Chris', 'Schaefer', '1981-05-03') [23505-192]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.index.BaseIndex.getDuplicateKeyException(BaseIndex.java:103)
at org.h2.mvstore.db.MVSecondaryIndex.checkUnique(MVSecondaryIndex.java:231)
at org.h2.mvstore.db.MVSecondaryIndex.add(MVSecondaryIndex.java:190)
at org.h2.mvstore.db.MVTable.addRow(MVTable.java:704)
at org.h2.command.dml.Insert.insertRows(Insert.java:156)
at org.h2.command.dml.Insert.update(Insert.java:114)
at org.h2.command.CommandContainer.update(CommandContainer.java:98)
at org.h2.command.Command.executeUpdate(Command.java:258)
at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:184)
at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:158)
at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.executeSqlScript(ResourceDatabasePopulator.java:187)
... 40 more
我的课程如下:
// Contact
@Entity
@Table(name="contact")
public class Contact implements Serializable{
private Long id;
private int version;
private String firstName;
private String lastName;
private Date birthDate;
private Set<ContactTelDetail> contactTelDetails = new HashSet<ContactTelDetail>();
private Set<Hobby> hobbies = new HashSet<Hobby>();
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "ID")
public Long getId(){
return this.id;
}
public void setId(Long id) {
this.id = id;
}
@Version
@Column(name = "VERSION")
public int getVersion() {
return this.version;
}
public void setVersion(int version) {
this.version = version;
}
@Column(name = "FIRST_NAME")
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@Column(name = "LAST_NAME")
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Temporal(TemporalType.DATE)
@Column(name = "BIRTH_DATE")
public Date getBirthDate() {
return this.birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
@OneToMany(mappedBy = "contact", cascade=CascadeType.ALL,
orphanRemoval=true)
public Set<ContactTelDetail> getContactTelDetails() {
return this.contactTelDetails;
}
public void setContactTelDetails(Set<ContactTelDetail> contactTelDetails) {
this.contactTelDetails = contactTelDetails;
}
public void addContactTelDetail(ContactTelDetail contactTelDetail){
contactTelDetail.setContact(this);
getContactTelDetails().add(contactTelDetail);
}
public void removeContactTelDetail(ContactTelDetail contactTelDetail) {
getContactTelDetails().remove(contactTelDetail);
}
@ManyToMany
@JoinTable(name="contact_hobby_detail",
joinColumns=@JoinColumn(name="CONTACT_ID"),
inverseJoinColumns=@JoinColumn(name="HOBBY_ID"))
public Set<Hobby> getHobbies(){
return this.hobbies;
}
public void setHobbies(Set<Hobby> hobbies) {
this.hobbies = hobbies;
}
public String toString() {
return "Contact - Id: " + id + ", First name: " + firstName
+ ", Last name: " + lastName + ", Birthday: " + birthDate;
}
}
// Hobby
@Entity
@Table(name = "hobby")
public class Hobby implements Serializable{
private String hobbyId;
private Set<Contact> contacts = new HashSet<Contact>();
@Id
@Column(name = "HOBBY_ID")
public String getHobbyId() {
return this.hobbyId;
}
public void setHobbyId(String hobbyId) {
this.hobbyId = hobbyId;
}
@ManyToMany
@JoinTable(name="contact_hobby_detail",
joinColumns=@JoinColumn(name="HOBBY_ID"),
inverseJoinColumns=@JoinColumn(name="CONTACT_ID"))
public Set<Contact> getContacts() {
return this.contacts;
}
public String toString() {
return "Hobby :" + getHobbyId();
}
}
// ContactTelDetail
@Entity
@Table(name = "contact_tel_detail")
public class ContactTelDetail implements Serializable{
private Long id;
private int version;
private String telType;
private String telNumber;
private Contact contact;
public ContactTelDetail() {
}
public ContactTelDetail(String telType, String telNumber) {
this.telType = telType;
this.telNumber = telNumber;
}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "ID")
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
@Version
@Column(name = "VERSION")
public int getVersion() {
return this.version;
}
public void setVersion(int version) {
this.version = version;
}
@Column(name = "TEL_TYPE")
public String getTelType() {
return this.telType;
}
public void setTelType(String telType) {
this.telType = telType;
}
@Column(name = "TEL_NUMBER")
public String getTelNumber() {
return this.telNumber;
}
public void setTelNumber(String telNumber) {
this.telNumber = telNumber;
}
@ManyToOne
@JoinColumn(name="CONTACT_ID")
public Contact getContact() {
return this.contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
public String toString() {
return "Contact Tel Detail - Id: " + id + ", Contact id: "
+ getContact().getId() + ", Type: "
+ telType + ", Number: " + telNumber;
}
}
其中一个数据库表是一个链接表。
我想知道自己做错了什么。