1

開発済みのスプリング ブート Web アプリケーションに機能を追加する作業を行っています。子エンティティを持つ主エンティティはレコードです。いくつかの列/変数があり、それを独自の別のエンティティ (CustomerOrder) にし、レコードと 1 対 1 の関係で存在させたいと考えています。要約する:

記録 {

-事1

-事 2

-事 3

}

現在は次のようになっています。

顧客注文 {

-事1

-事 2

-事 3

}

レコード { CustomerOrder }

作成したものに問題があります。CustomerOrder モデルの関連データは次のとおりです。

@Entity
@Table(name="customer_orders")
public class CustomerOrder {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    ... other columns

    @OneToOne(orphanRemoval = true, cascade = CascadeType.ALL, mappedBy="customerOrder", fetch = FetchType.EAGER)
    private Record record;


}

次に、Record モデルの関連データを次に示します。

@Entity
@Table(name="records")
public class Record extends Auditable<String> implements Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    ... other columns

    @OneToOne
    @JoinColumn(name="customer_order_id", nullable = false, unique = true)
    private CustomerOrder customerOrder;
}

ユーザーがUIでレコードを作成しようとすると、レコードをPOSTしようとすると問題が発生します。レコードの POST メソッドは次のとおりです。

    @PostMapping
    public ResponseEntity<?> saveRecord(@RequestBody Record recordBody, BindingResult result) {
        if(!result.hasErrors()) {
            if(recordBody.getHardwareItems().isEmpty()) {
                record = recordsService.save(recordBody);
            } else {
                // Save the record first, recordId is required on hardwareItems
                // TODO: investigate Spring Hibernate/JPA rules - is there a way to save parent before children to avoid a null recordId
                CustomerOrder customerOrder = recordBody.getCustomerOrder();
                recordBody.setCustomerOrder(new CustomerOrder());
                customerOrder.setRecord(record);
                customerOrder = customerOrdersService.save(customerOrder);
                record = recordsService.save(recordBody);
            }
        } else {
            return new ResponseEntity<>(result.getAllErrors(), HttpStatus.BAD_REQUEST);
        }
        // Return the location of the created resource
        uri = ServletUriComponentsBuilder.fromCurrentRequest().path("/{recordId}").buildAndExpand(record.getId()).toUri();
        return new ResponseEntity<>(uri, HttpStatus.CREATED);
    }

私が受け取るエラーは次のとおりです。

2021-02-19 02:35:50.989  WARN 31765 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1364, SQLState: HY000
2021-02-19 02:35:50.989 ERROR 31765 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper   : Field 'record_id' doesn't have a default value

まだ永続化されていない Record オブジェクトに依存する CustomerOrder オブジェクトを保存しようとしているので、これは少なくとも私には理にかなっています。では、CustomerOrder オブジェクトを保存できるように、注文を変更したり、Record オブジェクトを作成して永続化したりするにはどうすればよいでしょうか?

また、私は mysql を使用しており、これが既に持っている移行スクリプトです。ここで customer_orders テーブルに何か追加する必要がありますか?

-- Add a sample user
INSERT IGNORE INTO users (first_name, last_name, email, password, enabled, role)
VALUES ('Sample', 'User', 'sample@email.com', 'sample password', true, 'ROLE_ADMIN');

-- Customer Reference Values
INSERT IGNORE INTO customers (name) VALUES ('value1');
INSERT IGNORE INTO customers (name) VALUES ('value2');
INSERT IGNORE INTO customers (name) VALUES ('value3');
INSERT IGNORE INTO customers (name) VALUES ('value4');
INSERT IGNORE INTO customers (name) VALUES ('value5');
INSERT IGNORE INTO customers (name) VALUES ('value6');
INSERT IGNORE INTO customers (name) VALUES ('value7');
INSERT IGNORE INTO customers (name) VALUES ('value8');

Records テーブルと CustomerOrders テーブルの mysql スクリプトは次のとおりです。

-- -----------------------------------------------------
-- Table `myapp`.`records`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `myapp`.`records` (
  `id` BIGINT NOT NULL AUTO_INCREMENT,
  `customer_order_id` BIGINT NOT NULL,
  `record_id` BIGINT NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `UK_7m7wsqy68b7omkufvckoqv2hf` (`customer_order_id` ASC) VISIBLE,
  INDEX `FKta31a9q1llknlo2n0jw741987` (`customer_id` ASC) VISIBLE,
  CONSTRAINT `FK3q3clytyrx7s8edp9ok821j3`
    FOREIGN KEY (`customer_order_id`)
    REFERENCES `myapp`.`customer_orders` (`id`),
  CONSTRAINT `FKta31a9q1llknlo2n0jw741987`
    FOREIGN KEY (`customer_id`)
    REFERENCES `myapp`.`customers` (`id`))
ENGINE = InnoDB
AUTO_INCREMENT = 27
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;


-- -----------------------------------------------------
-- Table `myapp`.`customer_orders`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `myapp`.`customer_orders` (
  `id` BIGINT NOT NULL AUTO_INCREMENT,
  `record_id` BIGINT NOT NULL,
  `record_id_test` BIGINT NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `UK_ilew9pg8y4qnyhmjg38k1fev2` (`record_id_test` ASC) VISIBLE,
  INDEX `FK5rpb3u59bblj7h70wjr5mvb01` (`record_id` ASC) VISIBLE,
  CONSTRAINT `FK5rpb3u59bblj7h70wjr5mvb01`
    FOREIGN KEY (`record_id`)
    REFERENCES `myapp`.`records` (`id`),
  CONSTRAINT `FKk7a0g7djyhymr54ehoftkhyfw`
    FOREIGN KEY (`record_id_test`)
    REFERENCES `myapp`.`records` (`id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
4

5 に答える 5