Java 子表JPA的持久化问题

Java 子表JPA的持久化问题,java,mysql,spring,hibernate,spring-data-jpa,Java,Mysql,Spring,Hibernate,Spring Data Jpa,我在MySQl中有一个OneToMany关系,我使用JPA映射它。从数据库中检索信息时,它工作得很好,但在持久化子表时,我遇到了一个问题。 --MySQL工作台正向工程 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; SET @OLD_SQL_MODE=@@SQL_MODE, SQL_M

我在MySQl中有一个OneToMany关系,我使用JPA映射它。从数据库中检索信息时,它工作得很好,但在持久化子表时,我遇到了一个问题。

--MySQL工作台正向工程

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

-- -----------------------------------------------------
-- Schema mydb
-- -----------------------------------------------------

-- -----------------------------------------------------
-- Schema mydb
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8 ;
USE `mydb` ;

-- -----------------------------------------------------
-- Table `mydb`.`course`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`course` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NULL,
  `descr` VARCHAR(45) NULL,
  PRIMARY KEY (`id`))
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`topic`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`topic` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NULL,
  `descr` VARCHAR(45) NULL,
  `course_id` INT NOT NULL,
  PRIMARY KEY (`id`, `course_id`),
  INDEX `fk_topic_course_idx` (`course_id` ASC) VISIBLE,
  CONSTRAINT `fk_topic_course`
    FOREIGN KEY (`course_id`)
    REFERENCES `mydb`.`course` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

@Entity
@Table(name = "course", schema = "mydb")
public class Course implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 1886462862094528507L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;
    @Column(name = "name")
    private String name;
    @Column(name = "descr")
    private String descr;

    @OneToMany(mappedBy = "course", fetch = FetchType.EAGER) //name of object in Topic entity  
    @JsonManagedReference
        private Set<Topic> topic; 
}


@Entity
@Table(name="topic", schema = "mydb")
public class Topic implements Serializable {


    /**
     *
     */
    private static final long serialVersionUID = -365302645107748753L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false)
    private int id;
    @Column(name = "name")
    private String name;
    @Column(name = "descr")
    private String descr;


    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="course_id") //name of the foreign key. Must pay attention here 
    @JsonBackReference
    private Course course;
}
2019-11-14 13:11:27.013错误18916---[nio-8081-exec-2]o.a.c.c.c.[/].[dispatcherServlet]:路径为[]的上下文中Servlet[dispatcherServlet]的Servlet.service()引发异常[请求处理失败;嵌套异常为org.springframework.dao.DataIntegrityViolationException:无法执行语句;SQL[n/a];约束[null];嵌套异常是org.hibernate.exception.ConstraintViolationException:无法执行语句],其根本原因是

java.sql.SQLIntegrityConstraintViolationException:列“课程id”不能为null


出现此错误是因为您使用的是
@GeneratedValue
,没有附加规范。默认情况下,Hibernate将尝试访问名为
。Hibernate sequence
的序列

由于您使用的是mysql,因此可以注释:

@GeneratedValue(strategy = GenerationType.IDENTITY)
这将导致hibernate使用mysql的
AUTO_INCREMENT
而不是sequence

您还需要在创建架构时使用
AUTO_INCREMENT
定义列

在持久化之前,您还缺少对
课程
实体的引用:

topic.setCourse(entityManager.getReference(Course.class, courseId));

courseId
这是作为json传递的
course\u id

这是怎么回事?一个实体,这也是一个存储库?我强烈建议至少读一读jpa。Andronicus,@repository注释是错误的。谢谢你的建议,我已经删除了它。这些注释不是用于扩展讨论的这段对话已经结束了。
topic.setCourse(entityManager.getReference(Course.class, courseId));