Hibernate -Address表字段中的外键为空

cuxqih21  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(148)

我测试了一个简单的代码来练习Hibernate实体,它有两个实体:雇员和地址。一个雇员可以有多个地址。因此,雇员与地址是一对多关系。地址与雇员是多对一关系。

员工实体

import lombok.*;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Set;

@Entity
@Table(schema = "hibernate_entity_demo", name="employee")
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Employee implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

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

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

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

    @OneToMany(mappedBy = "employee")
    private Set<Address> addressSet;

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", fname='" + fname + '\'' +
                ", lastname='" + lastname + '\'' +
                ", email='" + email + '\'' +
                ", address='" + addressSet+
                '}';    
    }
}

地址实体

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(schema = "hibernate_entity_demo", name="address")
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Address implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

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

    @ManyToOne
    @JoinColumn(name="employee_id")
    private Employee employee;

    @Override
    public String toString() {
        return "Address{" +
                "id=" + id +
                ", city='" + city + '\'' +
                ", employee='" + employee.getFname() + " "+ employee.getLastname() +
                "'}";
    }
}

我的架构

CREATE SCHEMA IF NOT EXISTS hibernate_entity_demo;

CREATE TABLE IF NOT EXISTS hibernate_entity_demo.employee (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    first_name VARCHAR(32) ,
    last_name VARCHAR(32) ,
    email VARCHAR(32)
);

CREATE TABLE IF NOT EXISTS hibernate_entity_demo.address (
    id          INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    city        VARCHAR(32),
    employee_id INT ,
    FOREIGN KEY (employee_id) REFERENCES hibernate_entity_demo.employee(id)
)

我的hibernate.cfg.xml文件

<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_entity_demo</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">create</property>

我认为我已经正确地设置了所有内容,所以我运行了以下代码,在其中我创建了实体并将其持久化:

tx = session.beginTransaction();

Employee emp = Employee.builder()
        .fname("John").lastname("Doe").
        email("example@gmail.com").build();
Address addr = Address.builder().city("Los Angeles").employee(emp)
        .build();
emp.setAddressSet(new HashSet<Address>(Arrays.asList(addr)));
session.persist(addr);
session.persist(emp);

问题
一切都运行得很好,但有一个问题。Address表中的employee_id字段为空。这是我直接查看数据库时得到的结果。

员工表

| 标识符|电邮|名字|姓氏|
| - -|- -|- -|- -|
| 一个|example@gmail.com|若翰|多伊|

地址表

| 标识符|城市|雇员标识|
| - -|- -|- -|
| 一个|洛杉矶||
我的期望
我希望我的表看起来像这样,而id为1的地址的employee_id为1。

员工表

| 标识符|电邮|名字|姓氏|
| - -|- -|- -|- -|
| 一个|example@gmail.com|若翰|多伊|

地址表

| 标识符|城市|雇员标识|
| - -|- -|- -|
| 一个|洛杉矶|一个|
我试过将hbm2ddl.auto更改为update,但没有成功。我还试过运行下面的代码来查看地址的雇员是否正确。

Employee e1 = session.get(Employee.class,1);
Address a1 = session.get(Address.class, 1);
System.out.println(e1);
System.out.println(a1);

输出为:

Employee{id=1, fname='John', lastname='Doe', email='example@gmail.com', address='[Address{id=1, city='Los Angeles', employee='John Doe'}]}
Address{id=1, city='Los Angeles', employee='John Doe'}

正如您所看到的,当我打印出来时,Address a1具有正确的Employee e1,但是外键仍然不在表中。
有什么建议吗?

relj7zay

relj7zay1#

好的,修复了。需要在地址之前保留雇员。正确的顺序应该是下面。

session.persist(emp);
session.persist(addr);

相关问题