一对多的连接列为空休眠
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一对多的连接列为空休眠相关的知识,希望对你有一定的参考价值。
[我正在学习休眠,并且尝试在休眠中实现一对多关系(使用mysql和spring jpa的spring boot),并且遇到了我花了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
application.properties:
## 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
SpringBootApplication:
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");
}
子方是关系的所有者,因为这是外键所在的位置。
以上是关于一对多的连接列为空休眠的主要内容,如果未能解决你的问题,请参考以下文章