如何在保存 "child" 实体时保留 "parent" 实体?
How to persist "parent" entity when saving a "child" entity?
如何让 Hibernate 保存“parent”实体,例如如果我有来自客户的 CarDescription
CarDescriptionDTO
.
如果我现在想保存那个,例如
Session session = HibernateSession.openSession();
session.beginTransaction();
CarDescription carDescription = ConvertDTO.convertCarDescription(carDescriptionDto);
session.save(carDescription);
如果此时 carDescription
没有设置 Car
,我如何确保创建新的 Car
条目?或者这是我不希望 Hibernate 为我做的事情?
Car.java
@Entity
@Table(name = "car")
public class Car extends AbstractTimestampEntity implements Serializable {
private static final long serialVersionUID = -5041816842632017838L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
// ..
}
如何确保这也创建了一个 Car
条目?
CarDescription.java
@Entity
@Table(name = "car_description")
public class CarDescription extends AbstractTimestampEntity implements Serializable {
private static final long serialVersionUID = 2840651722666001938L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@NotNull
@ManyToOne
private Car car;
// ..
}
有两种方法可以实现。
1) 您可以在 CarDescription
的字段初始值设定项中创建 Car
:
@NotNull
@ManyToOne(cascade = CascadeType.PERSIST)
private Car car = new Car();
您还定义了 CascadeType.PERSIST
,以便 car
与其 CarDescription
一起持久化。这样 CarDescription
默认情况下总是会有 空 汽车。
2) 您可以显式创建并保存 car
:
Session session = HibernateSession.openSession();
session.beginTransaction();
CarDescription carDescription = ConvertDTO.convertCarDescription(carDescriptionDto);
Car car = new Car();
carDescription.setCar(car);
session.save(car);
session.save(carDescription);
这不是好的做法。你不应该级联 entity state transitions from Child to Parents。
更好的方法是始终在填充传入数据之前检查现有实体。
流程将是这样的:
Car car = session.get(Car.class, carId);
if(car == null) {
car = new Car();
session.persist(car);
}
CarDescription carDescription = session.get(CarDescription.class, carDescriptionId);
if(carDescription == null) {
carDescription = new CarDescription();
carDescription.setCar(car);
session.persist(carDescription);
}
CarDescription carDescription = ConvertDTO.convertCarDescription(carDescriptionDto, car, carDescription);
这样您可以确保 car
和 carDescription
在填充传入数据之前与当前会话相关联。仅仅调用 persist 不会触发数据库行插入,因为它需要刷新。如果您在填充数据之前不发出任何查询,则实体将仅被安排刷新并在事务提交时传播到数据库。
如何让 Hibernate 保存“parent”实体,例如如果我有来自客户的 CarDescription
CarDescriptionDTO
.
如果我现在想保存那个,例如
Session session = HibernateSession.openSession();
session.beginTransaction();
CarDescription carDescription = ConvertDTO.convertCarDescription(carDescriptionDto);
session.save(carDescription);
如果此时 carDescription
没有设置 Car
,我如何确保创建新的 Car
条目?或者这是我不希望 Hibernate 为我做的事情?
Car.java
@Entity
@Table(name = "car")
public class Car extends AbstractTimestampEntity implements Serializable {
private static final long serialVersionUID = -5041816842632017838L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
// ..
}
如何确保这也创建了一个 Car
条目?
CarDescription.java
@Entity
@Table(name = "car_description")
public class CarDescription extends AbstractTimestampEntity implements Serializable {
private static final long serialVersionUID = 2840651722666001938L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@NotNull
@ManyToOne
private Car car;
// ..
}
有两种方法可以实现。
1) 您可以在 CarDescription
的字段初始值设定项中创建 Car
:
@NotNull
@ManyToOne(cascade = CascadeType.PERSIST)
private Car car = new Car();
您还定义了 CascadeType.PERSIST
,以便 car
与其 CarDescription
一起持久化。这样 CarDescription
默认情况下总是会有 空 汽车。
2) 您可以显式创建并保存 car
:
Session session = HibernateSession.openSession();
session.beginTransaction();
CarDescription carDescription = ConvertDTO.convertCarDescription(carDescriptionDto);
Car car = new Car();
carDescription.setCar(car);
session.save(car);
session.save(carDescription);
这不是好的做法。你不应该级联 entity state transitions from Child to Parents。
更好的方法是始终在填充传入数据之前检查现有实体。
流程将是这样的:
Car car = session.get(Car.class, carId);
if(car == null) {
car = new Car();
session.persist(car);
}
CarDescription carDescription = session.get(CarDescription.class, carDescriptionId);
if(carDescription == null) {
carDescription = new CarDescription();
carDescription.setCar(car);
session.persist(carDescription);
}
CarDescription carDescription = ConvertDTO.convertCarDescription(carDescriptionDto, car, carDescription);
这样您可以确保 car
和 carDescription
在填充传入数据之前与当前会话相关联。仅仅调用 persist 不会触发数据库行插入,因为它需要刷新。如果您在填充数据之前不发出任何查询,则实体将仅被安排刷新并在事务提交时传播到数据库。