Spring和Hibernate数据库表的关系问题

时间:2016-07-17 08:57:03

标签: java mysql database spring hibernate

我正在学习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;
            }


    }

其中一个数据库表是一个链接表。

我想知道自己做错了什么。

0 个答案:

没有答案