Java “如何坚持”;“家长”;实体在保存“时”;“儿童”;实体?

Java “如何坚持”;“家长”;实体在保存“时”;“儿童”;实体?,java,hibernate,orm,hibernate-mapping,cascade,Java,Hibernate,Orm,Hibernate Mapping,Cascade,如何让Hibernate保存“父”实体,例如,如果我有通过CarDescriptionDTO从客户端发送的CarDescription 如果我现在想保存它,例如 Session session = HibernateSession.openSession(); session.beginTransaction(); CarDescription carDescription = ConvertDTO.convertCarDescription(carDescriptionDto); sess

如何让Hibernate保存“父”实体,例如,如果我有通过
CarDescriptionDTO
从客户端发送的
CarDescription

如果我现在想保存它,例如

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;

    // ..
}
@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;

    // ..
}
如何确保这也会创建一个
Car
条目

CarDescription.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;

    // ..
}
@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) 您可以在
卡片说明
的字段初始值设定项中创建
汽车

@NotNull
@ManyToOne(cascade = CascadeType.PERSIST)
private Car car = new Car();
您还可以定义
CascadeType.PERSIST
,以便
car
与其
CarDescription
一起持久化。这样一来,
CarDescription
在默认情况下将始终有一辆空车

2) 您可以显式地创建和保存
汽车

Session session = HibernateSession.openSession();
session.beginTransaction();

CarDescription carDescription = ConvertDTO.convertCarDescription(carDescriptionDto);

Car car = new Car();
carDescription.setCar(car);

session.save(car);
session.save(carDescription);

这不是好的做法。你不应该离开

更好的方法是在填充传入数据之前始终检查现有实体

流程将如下所示:

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不会触发数据库行插入,因为它需要刷新。如果在填充数据之前没有发出任何查询,则只会在事务提交时安排实体刷新并传播到数据库

“如果此时CardDescription没有设置汽车,我如何确保创建一个新的汽车条目?”因此,您希望自动创建一个
Car
,并将其插入数据库,其所有字段(除了
id
)都为
null
?如果我调用
session.save(CardDescription)),那么
但是
carDescription.car==null
然后我希望Hibernate创建一个新的
car
条目,该条目与
carDescription
关联。我不确定这是否可行,我也不确定这样做是否是个好主意。现在我遇到了一个问题,客户用
car==null
向我发送
carDescription**Dto**
。我不知道更好的方法..所以车里的所有字段(除了
id
carDescription
,如果关联是双向的)都是
null
?需要吗?@DraganBozanovic是的,可以-它只需要提供一个有效的id到
carDescription
。上面没有看到的是,
CarDescription
有另一种fkey
语言,它提供了不同的翻译
Car
只是用来表示“有一辆车”,并提供诸如“颜色”等常见信息。但这些都可以使用默认值。@DraganBozanovic请注意,只有当
Car==null
时才会发生这种情况。情况并非总是如此,例如,如果我只是更新
CarDescription
。你是对的。这是个坏主意。我仍然接受Dragan Bozanovic的回答,因为它回答了我的问题-无论如何,非常感谢你展示了一个更好的方法+1.