java - 一对多的连接列为 null hibernate

标签 java sql spring spring-data-jpa spring-data

我正在学习hibernate,我尝试在hibernate中实现一对多关系(带有mysql的spring boot和spring jpa),但我遇到了一个运行时错误,我花了3个小时。

一对多关系中两个表的连接列为空

一对多中的一个:(部门可以有多个员工)

package com.example.hibernateDemo.models;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "departments")
public class Department {

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

    @Column(name = "category")
    private String category;

    @OneToMany(mappedBy = "department", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Employee> employees;

    @Column(name = "number_of_employees")
    private int numberOfEmployees;

    public Department() {
    }
    // getters and setters as well as one more constructor

一对多中的多个员工:

package com.example.hibernateDemo.models;

import javax.persistence.*;

@Entity
@Table(name = "employees")
public class Employee {

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

    @Column(name = "name")
    private String name;

    @Column(name = "hours_of_work_per_day")
    private int hoursOfWorkPerDay;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="department_id", nullable=false, referencedColumnName = "id")
    private Department department;

    public Employee() {
    }
    // getters and setters as well as constructor

应用程序属性:

## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url = jdbc:mysql://localhost:3306/demo
spring.datasource.username = ?{username}
spring.datasource.password = ?{password}
## Hibernate Properties
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto = update

SpringBoot应用程序:

import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

import java.util.ArrayList;
import java.util.List;

@SpringBootApplication
@ComponentScan
@EnableJpaRepositories("com.example.hibernateDemo.Repositories") // important for enabling JpaRepository
public class HibernateDemoApplication {


    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(HibernateDemoApplication.class, args);
        List<Employee> employeeList = new ArrayList<>();
        employeeList.add(new Employee("david", 8));
        employeeList.add(new Employee("jordan", 12));
        Department department = new Department("software engineers", employeeList);
        DepartmentRepository serviceDepartment = context.getBean(DepartmentRepository.class);
        serviceDepartment.save(department);
        System.out.println("inserted");
    }

}

控制台输出:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.5.RELEASE)

2020-03-25 19:54:08.563  INFO 7935 --- [           main] c.e.h.HibernateDemoApplication           : Starting HibernateDemoApplication on abu with PID 7935 (/home/yoav/hibernateDemo/target/classes started by yoav in /home/yoav/hibernateDemo)
2020-03-25 19:54:08.566  INFO 7935 --- [           main] c.e.h.HibernateDemoApplication           : No active profile set, falling back to default profiles: default
2020-03-25 19:54:09.352  INFO 7935 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2020-03-25 19:54:09.446  INFO 7935 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 84ms. Found 5 JPA repository interfaces.
2020-03-25 19:54:10.539  INFO 7935 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2020-03-25 19:54:10.554  INFO 7935 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-03-25 19:54:10.554  INFO 7935 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.31]
2020-03-25 19:54:10.635  INFO 7935 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-03-25 19:54:10.635  INFO 7935 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1938 ms
2020-03-25 19:54:10.984  INFO 7935 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2020-03-25 19:54:11.043  INFO 7935 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 5.4.12.Final
2020-03-25 19:54:11.354  INFO 7935 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
2020-03-25 19:54:11.543  INFO 7935 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2020-03-25 19:54:12.593  INFO 7935 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2020-03-25 19:54:12.655  INFO 7935 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
2020-03-25 19:54:17.417  INFO 7935 --- [           main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2020-03-25 19:54:17.442  INFO 7935 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2020-03-25 19:54:20.370  WARN 7935 --- [           main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2020-03-25 19:54:20.629  INFO 7935 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-03-25 19:54:20.983  INFO 7935 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2020-03-25 19:54:20.984  INFO 7935 --- [           main] c.e.h.HibernateDemoApplication           : Started HibernateDemoApplication in 13.242 seconds (JVM running for 13.636)
2020-03-25 19:54:21.238  WARN 7935 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1048, SQLState: 23000
2020-03-25 19:54:21.238 ERROR 7935 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : Column 'department_id' cannot be null
Exception in thread "main" org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:298)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528)
 // AND MORE A LOT MORE

最佳答案

您必须同步子端的关系:

public static void main(String[] args) {
    ApplicationContext context = SpringApplication.run(HibernateDemoApplication.class, args);
    List<Employee> employeeList = new ArrayList<>();
    employeeList.add(new Employee("david", 8));
    employeeList.add(new Employee("jordan", 12));
    Department department = new Department("software engineers", employeeList);
    employeeList.forEach(e -> e.setDepartment(department)); // this line was missing
    DepartmentRepository serviceDepartment = context.getBean(DepartmentRepository.class);
    serviceDepartment.save(department);
    System.out.println("inserted");
}

子方是关系的所有者,因为那是外键所在的位置。

关于java - 一对多的连接列为 null hibernate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60854628/

相关文章:

Java old gen 不断增长——需要帮助解释 Java GC 输出

java - 如何等待 10 秒而不锁定 android 中的应用程序 UI

php - 加入多对一

sql - PostgreSQL 与 json 数组中的模式反向 LIKE

java - 不要针对特定​​的 URL 和 HTTP 方法调用 Spring Security 预身份验证过滤器

java - 比较 TreeMap 中的值

java - Jackson 自定义反序列化器在阅读列表时创建空 pojo

mysql - 在 SQL 中向现有超过 600 万条记录的表添加额外列

java - 无法使用上下文 :property-placeholder (Spring) 获取属性

java - 在 JUnit 中使用 @RunWith 有解决方法吗?