java - 在 OneToMany 的情况下不会发生数据库插入
问题描述
我想使用@OneToMany 关系在数据库中插入数据,但它不起作用。
我有两个表,其架构如下:
Create Table Instructor (Id int primary key,Name varchar2(50),Email varchar2(15));
创建表 Courses (Course_Id int 主键, Course_Name Varchar2(20) NOT NULL Unique,Instructor_Id int , 外键(Instructor_Id) 引用 Instructor (Id));
当我尝试在数据库中插入时,它没有给我任何错误,但在数据库中它没有反映两个表
培训班:
@Entity
@Table(name = "Courses")
public class Courses {
@Id
@Column(name = "Course_Id ")
private int courseId;
@Column(name = "Course_Name")
private String courseName;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "Instructor_Id")
private Instructor instructor;
public int getCourseId() {
return courseId;
}
public void setCourseId(int courseId) {
this.courseId = courseId;
}
public String getCourseName() {
return courseName;
}
public void setCourseName(String courseName) {
this.courseName = courseName;
}
public Instructor getInstructor() {
return instructor;
}
public void setInstructor(Instructor instructor) {
this.instructor = instructor;
}
}
教练:
@Entity
@Table(name = "Instructor")
public class Instructor {
@Id
@Column(name = "Id")
private int id;
@Column(name = "Name")
private String name;
@Column(name = "Email")
private String email;
@OneToMany(mappedBy = "instructor", cascade = CascadeType.ALL)
private List<Courses> courses;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public List<Courses> getCourses() {
return courses;
}
public void setCourses(List<Courses> courses) {
this.courses = courses;
}
public void setEmail(String string) {
this.email = string;
}
主要课程:
public class HibernateTest {
public static void main(String[] args) {
try (SessionFactory factory = new Configuration().configure("hibernate.cfg.xml")
.addAnnotatedClass(Courses.class).addAnnotatedClass(Instructor.class).buildSessionFactory();) {
//Test Insert
Instructor i1 = new Instructor();
i1.setEmail("test@mail.com");
i1.setId(100);
i1.setName("patcyy");
//List Of Courses
List<Courses> listOfCourses = new ArrayList<>();
Courses c1 = new Courses();
c1.setCourseName("Java");
c1.setCourseId(1);
Courses c2 = new Courses();
c2.setCourseName("C");
c2.setCourseId(2);
listOfCourses.add(c1);
listOfCourses.add(c2);
//adding to instructor
i1.setCourses(listOfCourses);
//insert in DB
inserIntoDb(factory, i1);
} catch (Exception e) {
System.out.println("Exception : " + e);
}
}
/**
*
* @param factory
* @param st
*/
private static void inserIntoDb(SessionFactory factory, Instructor st) {
System.out.println("Inserting into DB");
Session session = factory.getCurrentSession();
session.beginTransaction();
session.save(st);
session.getTransaction().commit();
}
}
日志 :
May 13, 2019 8:35:24 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.4.2.Final}
May 13, 2019 8:35:25 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
May 13, 2019 8:35:25 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
May 13, 2019 8:35:25 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: using driver [oracle.jdbc.driver.OracleDriver] at URL [jdbc:oracle:thin:@localhost:1521:****]
May 13, 2019 8:35:25 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {user=****, password=****}
May 13, 2019 8:35:25 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
May 13, 2019 8:35:25 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections <init>
INFO: HHH000115: Hibernate connection pool size: 1 (min=1)
May 13, 2019 8:35:25 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.Oracle12cDialect
Inserting into DB
Hibernate: select courses_.Course_Id, courses_.Course_Name as Course_Name2_0_, courses_.Instructor_Id as Instructor_Id3_0_ from Courses courses_ where courses_.Course_Id=?
Hibernate: select courses_.Course_Id, courses_.Course_Name as Course_Name2_0_, courses_.Instructor_Id as Instructor_Id3_0_ from Courses courses_ where courses_.Course_Id=?
Hibernate: insert into Instructor (Email, Name, Id) values (?, ?, ?)
更新代码:
package com.patcyy.hibernate;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateTest {
public static void main(String[] args) {
try (SessionFactory factory = new Configuration().configure("hibernate.cfg.xml")
.addAnnotatedClass(Courses.class).addAnnotatedClass(Instructor.class).buildSessionFactory();) {
//Test Insert
Instructor i1 = new Instructor();
i1.setEmail("test@mail.com");
i1.setId(100);
i1.setName("patcyy");
//List Of Courses
List<Courses> listOfCourses = new ArrayList<>();
Courses c1 = new Courses();
c1.setCourseName("Java");
c1.setCourseId(1);
c1.setInstructor(i1);
Courses c2 = new Courses();
c2.setCourseName("C");
c2.setCourseId(2);
c2.setInstructor(i1);
listOfCourses.add(c1);
listOfCourses.add(c2);
//adding to instructor
i1.setCourses(listOfCourses);
//insert in DB
inserIntoDb(factory, i1);
} catch (Exception e) {
System.out.println("Exception : " + e);
}
}
/**
*
* @param factory
* @param st
*/
private static void inserIntoDb(SessionFactory factory, Instructor st) {
System.out.println("Inserting into DB");
Session session = factory.getCurrentSession();
session.beginTransaction();
session.save(st);
session.getTransaction().commit();
}
}
在调试时它正在成功。
配置:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- JDBC Database connection settings -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:patcyy</property>
<property name="connection.username">SYSTEM</property>
<property name="connection.password">patcyy</property>
<!-- JDBC connection pool settings ... using built-in test pool -->
<property name="connection.pool_size">1</property>
<!-- Select our SQL dialect -->
<property name="dialect">org.hibernate.dialect.Oracle12cDialect</property>
<!-- Echo the SQL to stdout -->
<property name="show_sql">true</property>
<!-- Set the current session context -->
<property name="current_session_context_class">thread</property>
</session-factory>
</hibernate-configuration>
解决方案
在这种情况下,我建议使用自己的方法操作数组,在两边写入外键。
将以下方法添加到Instructor
addCourse(Course course) {
if (!courses.contains(course)) {
courses.add(course);
course.setInstructor(this);
}
}
您还可以覆盖 in 的设置instructor
器Course
:
setInstructor(Instructor instructor) {
this.instructor = instructor;
this.instructor.addCourse(this);
}
因此,您正在设置双方的关系。但要小心使用CascadeType.ALL
. 对于复杂的数据模型,这些方法存在无限递归调用的风险。
推荐阅读
- python - 在父类方法上使用子类中指定的装饰器
- mysql - 如何根据不可靠的用户输入数据生成可靠的合成密钥?
- c# - 无法使用特定的隐式方法反序列化泛型类
- homebrew - MAC:没有名称为“brew-cask”的可用公式
- java - 嵌入式 Jetty 9 + OpenJdk jdk8u212-b03 + SSL 使用证书不起作用
- c# - 模拟按键
- python - 如何通过任务调度程序调度 python 脚本从虚拟环境运行
- typescript - 开玩笑地测试异常
- vue.js - vuetify v-select 的 vue-material-dashboard 问题
- python - 使用键和值作为子列表反转字典