Сбой DAO при создании записи в БД - Spring Boot - PullRequest
1 голос
/ 30 июня 2019

Всякий раз, когда я отправляю свои данные формы моему контроллеру отдыха, и они переходят в мой класс DAO, я получаю эту ошибку:

org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation


2019-06-29 20:27:20.730 ERROR 5000 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: StatementCallback;SQL [INSERT INTO Foo(name, typeOfPlan, email, website, phoneNum, username, password) VALUES('Test', '2 Year', 'example@gmail.com', 'test.org', '123456789', 'Master', '1234');]; Referential integrity constraint violation: "CONSTRAINT_B3: PUBLIC.FOO FOREIGN KEY(ID) REFERENCES PUBLIC.Foo(ID) (33)"; SQL statement:
INSERT INTO Foo(name, typeOfPlan, email, website, phoneNum, username, password) VALUES('Test', '2 Year', 'example@gmail.com', 'test.org', '123456789', 'Master', '1234'); [23506-199]; nested exception is org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation: "CONSTRAINT_B3: PUBLIC.Foo FOREIGN KEY(ID) REFERENCES PUBLIC.Foo(ID) (33)"; SQL statement:
INSERT INTO Foo(name, typeOfPlan, email, website, phoneNum, username, password) VALUES('Test', '2 Year', 'example@gmail.com', 'test.org', '123456789', 'Master', '1234'); [23506-199]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:457)
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:427)
    at org.h2.message.DbException.get(DbException.java:205)
    at org.h2.message.DbException.get(DbException.java:181)
    at org.h2.constraint.ConstraintReferential.checkRowOwnTable(ConstraintReferential.java:319)
    at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:261)
    at org.h2.table.Table.fireConstraints(Table.java:1020)
    at org.h2.table.Table.fireAfterRow(Table.java:1038)
    at org.h2.command.dml.Insert.insertRows(Insert.java:194)
    at org.h2.command.dml.Insert.update(Insert.java:132)
    at org.h2.command.CommandContainer.updatmmandContainer.java:133)
    at org.h2.command.Command.executeUpdate(Command.java:267)
    at org.h2.server.TcpServerThread.process(TcpServerThread.java:398)
    at org.h2.server.TcpServerThread.run(TcpServerThread.java:175)
    at java.lang.Thread.run(Thread.java:748)
] with root cause

org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation: "CONSTRAINT_B3: PUBLIC.Foo FOREIGN KEY(ID) REFERENCES PUBLIC.Foo(ID) (33)"; SQL statement:
INSERT INTO Foo(name, typeOfPlan, email, website, phoneNum, username, password) VALUES('Test', '2 Year', 'example@gmail.com', 'test.org', '123456789', 'Master', '1234'); [23506-199]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:457) ~[h2-1.4.199.jar:1.4.199]
    at org.h2.engine.SessionRemote.done(SessionRemote.java:607) ~[h2-1.4.199.jar:1.4.199]
    at org.h2.command.CommandRemote.executeUpdate(CommandRemote.java:237) ~
....

Остальное бесполезно, и по причинам конфиденциальности не отображается. Я заверяю , что это все данные, которые вам нужны, и у них есть все вложенные исключения / ошибки.

DAO

@Repository
public class SomeDAOImpl implements ISomeDAO {

    @Autowired
    private JdbcTemplate temp;

public void createRecord(Foo foo) {

        // SQL insert statement
        String sql = "INSERT INTO Foo(name, typeOfPlan, email, website, phoneNum, username, password) " +
                "VALUES(" + "\'" + foo.getName() + "\'" + ", " + "\'" + foo.getTypeOfPlan() + "\'" + ", " + "\'" + foo.getEmail() + "\'" + ", " +
                "\'" + foo.getWebsite() + "\'" + ", " + "\'" + foo.getPhoneNum() + "\'" + ", " + "\'" + foo.getUsername() + "\'" +
                ", " + "\'" + foo.getPassword() + "\'" + ");";

        // Updates the table with the new record
        // Error here
        temp.update(sql);
    }
}

POJO

@JsonIgnoreProperties(ignoreUnknown = true)
public class Foo {

    private String name;
    private String typeOfPlan;
    private String email;
    private String website;
    private String phoneNum;
    private String username;
    private String password;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTypeOfPlan() {
        return typeOfPlan;
    }

    public void setTypeOfPlan(String typeOfPlan) {
        this.typeOfPlan= typeOfPlan;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getWebsite() {
        return website;
    }

    public void setWebsite(String website) {
        this.website = website;
    }

    public String getPhoneNum() {
        return phoneNum;
    }

    public void setPhoneNum(String phoneNum) {
        this.phoneNum = phoneNum;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

Как это исправить и не допустить этого?

РЕДАКТИРОВАТЬ:

Мой DDL для моих таблиц:

create table Foo3 (
    ID INT AUTO_INCREMENT,
    foo1 VARCHAR(30) NOT NULL,
    foo2 VARCHAR(10) NOT NULL,
    foo3 VARCHAR(50) NOT NULL,
    PRIMARY KEY(ID)
);

create table Foo2 (
    ID INT AUTO_INCREMENT,
    name VARCHAR(64) NOT NULL,
    PRIMARY KEY(ID),
    FOREIGN KEY (ID) REFERENCES Foo3(ID)
);

create table Foo (
    ID INT AUTO_INCREMENT,
    name VARCHAR(64) NOT NULL,
    typeOfPlan VARCHAR(30) NOT NULL,
    email VARCHAR(35) NOT NULL,
    website VARCHAR(40),
    phoneNum VARCHAR(35) NOT NULL,
    username VARCHAR(35) NOT NULL,
    password VARCHAR(35) NOT NULL,
    PRIMARY KEY(ID),
    FOREIGN KEY (ID) REFERENCES Foo2(ID)
);

Ответы [ 2 ]

0 голосов
/ 03 июля 2019

Исправлено обновление моего DDL, я обнаружил, что неправильно сделал FOREIGN KEY.

Вот обновленная версия:

create table Foo3 (
    ID INT AUTO_INCREMENT PRIMARY KEY,
    foo1 VARCHAR(30) NOT NULL,
    foo2 VARCHAR(10) NOT NULL,
    foo3 VARCHAR(50) NOT NULL
);

create table Foo2 (
    ID INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(64) NOT NULL,
    Foo3_ID INT NULL,
    CONSTRAINT FK_FOO2_FOO3_ID FOREIGN KEY(FOO3_ID) REFERENCES FOO3(ID)
);

create table Foo (
    ID INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(64) NOT NULL,
    typeOfPlan VARCHAR(30) NOT NULL,
    email VARCHAR(35) NOT NULL,
    website VARCHAR(40),
    phoneNum VARCHAR(35) NOT NULL,
    username VARCHAR(35) NOT NULL,
    password VARCHAR(35) NOT NULL,
    Foo2_ID INT NULL,
    CONSTRAINT FK_FOO_FOO2_ID FOREIGN KEY(FOO2_ID) REFERENCES Foo2(ID)
);

Мне нужно было добавить *Свойство 1007 * разрешает пустые ссылки FK, и мне пришлось добавить CONSTRAINT, чтобы сделать FOREIGN KEY пригодным для использования.

0 голосов
/ 02 июля 2019

Вы пытаетесь вставить новую запись в таблицу FOO, например, INSERT INTO Foo, но согласно определению вашей таблицы у вас есть ссылка на существующую запись в таблице Foo2 (а таблица Foo2 имеет ссылку на существующую запись в таблице Foo3) ... Таким образом, вам придется сначала создать ссылочные записи в этих таблицах в следующем порядке:

  1. Создать запись в таблице Foo3
  2. Создать запись в таблице Foo2, которая ссылается нав запись Foo3
  3. Создать запись в таблице Foo, которая ссылается на запись Foo2

ВАЖНОЕ ПРИМЕЧАНИЕ: Пожалуйста, просмотрите реляционный дизайн таблиц.Похоже, что вы смешиваете PRIMARY KEY и FOREIGN KEY в одном столбце таблицы с именем "ID".В идеале каждая таблица должна иметь свой собственный столбец первичного ключа и внешний ключ (и) в отдельном столбце (ах).

...