我测试了一个简单的代码来练习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
,但是外键仍然不在表中。
有什么建议吗?
1条答案
按热度按时间relj7zay1#
好的,修复了。需要在地址之前保留雇员。正确的顺序应该是下面。