JPA删除。在这种情况下,建议的方法是什么?

时间:2012-08-30 16:43:54

标签: java hibernate jpa orm

这个问题让我很伤心:

让我们说这个非常简单的案例:

(弹簧/休眠/ JPA2 / @ PersistenceContext(类型= PersistenceContextType.TRANSACTION))

我们有DAO实体:

class User{
private Set<Car> carSet;
... usual setters + getters
}

class Car{
private User user;
... usual setters + getters

}

以下哪一项是carId删除汽车的推荐方法及原因(这将在http post请求中完成,除此删除外不会执行其他操作)?

1)简单的删除操作;

Car  car = dao.find(Car.class, carId);
dao.remove(car);

2)首先清理参考文献。这种方法何时推荐?

Car  car = dao.find(Car.class, carId);
car.getUser().getCarSet().remove(car); // this one as far as I know will usually fetch the other cars, and I think is not optimal, am I right?
car.setUser(null);
dao.remove(car);

提前谢谢

2 个答案:

答案 0 :(得分:2)

看起来Car指向User,换句话说,Car有一个指向User的外键属性。因此,删除Car也将删除对User的引用。这也将从用户的车载中删除Car。因此,您需要做的就是选项1.

答案 1 :(得分:1)

简而言之,这取决于关系的拥有方。

为了简化它,让我们假设一个虚拟规则:拥有方总是带有外键的那个(对于整个故事,我会推荐一本好书,如Pro JPA 2: Mastering the Java™ Persistence API)。由于您从@ManyToOneCar之间存在User关系,因此根据我们的虚拟规则,Car是拥有方:

   *---------------*       *--------------*     
   |      CAR      |       |     USER     |     
   *---------------*       *--------------*     
   |  CARD_ID (PK) |   ~-> | USER_ID (PK) |     
   |  USER_ID (FK) | --~   *--------------*     
   *---------------*       

当您移除拥有方时,不必做任何其他事情。

在您的情况下,由于汽车是拥有方,您可以简单地移除汽车,即dao.remove(car);就足够了。

现在让我们考虑相反的情况。假设您需要删除User,即引用的一方。

如果删除与其关联的汽车的用户(假设没有级联行为),则数据库DELETE操作将因FK违规而失败。

tumb的规则是:关系维护是应用程序的责任。这意味着调整关系的相反(拥有)方面的参考。

如果car table中的外键列可以是NULL,则可以在删除用户之前使用car.setUser(null);。这会在您的数据库中留下孤儿车。

如果外键列为NOT NULL,则在删除用户之前,您需要将该车与其他用户关联:

   car.setUser(anotherUser);

或者将汽车从数据库中一起移除:

   dao.remove(car);

正如我所说,关系维护还有很多。 JPA具有@CascadeType s等功能;双向@ManyToMany关系,可以任意选择拥有方;单向@OneToMany(带连接表)等。但我认为这几乎总结了基础知识。