隐藏已删除的对象

时间:2009-08-20 09:33:18

标签: java hibernate jpa

我有以下用例:有一个名为Template的类,我可以使用该类创建ActualObject类的实例(ActualObject从模板中复制其初始数据)。 Template类有一个Product:s。

列表

现在有了棘手的部分,用户应该可以从数据库中删除产品,但这些删除可能不会影响模板的内容。换句话说,即使删除了产品,模板仍然可以访问它。这可以通过向产品添加“已删除”标志来解决。如果删除了产品,则可能无法从数据库中显式搜索,但可以隐式获取它(例如,通过Template类中的引用)。

这背后的想法是,当从模板创建ActualObject时,将在用户界面中通知用户“模板X具有带参数A,B和C的产品Z,但此产品已被删除并且不能在ActualObject Z“中添加。”

我的问题是如何将这些删除的对象标记为已删除。在有人建议只更新删除标志而不是执行实际的删除查询之前,我的问题并不那么简单。删除标志及其行为应该存在于所有POJO中,而不仅仅存在于Product中。这意味着我将遇到级联问题。例如,如果我删除了一个模板,那么也应该删除产品,并且每个产品都有一个对价格对象的引用,该对象也应该被删除,每个Price都可以引用VAT对象等等。所有这些级联对象都应标记为已删除。

我的问题是如何以合理的方式实现这一目标。浏览每个对象(正在被删除),检查每个字段以查找应该删除的引用,通过它们的引用等是非常费力的,并且容易出错。

我正在使用Hibernate,我想知道Hibernate是否会有任何这样的内置功能。我想到的另一个想法是使用hibernate拦截器将实际的SQL删除查询修改为更新查询(我甚至不能100%确定这是可能的)。我唯一担心的是Hibernate是否依赖于外键中的级联,换句话说,级联删除是由数据库完成的,而不是由休眠完成的。

5 个答案:

答案 0 :(得分:2)

  

我的问题是我应该如何标记这些   已删除的对象已删除。

我认为你已经选择了一种非常复杂的方法来解决这个问题。引入ProductTemplate会更容易。将所需的所有必需属性放入此对象中。此外,您还需要一个Product实例的引用。而不是标记Product,您可以删除它(并删除所有其他实体,如价格)。当然,您应该在ProductTemplate中清除参考。当您创建ActualObject的实例时,您将能够通过适当的消息通知用户。

答案 1 :(得分:1)

我认为你试图让事情变得比它们应该复杂得多......无论如何,你要做的是处理Hibernate 事件,看看 Hibernate Reference的第12章,您可以选择使用拦截器事件系统。 无论如何......祝你好运:)

答案 2 :(得分:1)

public interface Deletable {
  public void delete();
}

让所有可删除对象都实现此接口。在他们的实现中,更新deleted标志并让他们也调用他们孩子的delete()方法 - 这意味着孩子也必须Deletable

当然,在实施时,您必须手动确定哪些孩子是Deletable。但这至少应该是直截了当的。

答案 3 :(得分:0)

如果我了解您要求的内容,则在模板和产品之间添加@OneToMany关系,并选择级联规则,您将能够删除给定模板的所有关联产品。在您的产品类中,您可以按照建议添加“已删除”标记。您的服务/ dao图层将利用此已删除的标记,例如您可以利用getProdcuts(boolean includeDeleted)类型概念来确定是否应包含“已删除”记录以进行返回。通过这种方式,您可以控制最终用户看到的内容,但仍然可以向内部业务用户公开完整功能。

答案 4 :(得分:0)

要删除的标志应该是Template Class本身的一部分。这样,您创建的所有对象都有一种标记为活动或已删除的方式。要删除的Object的标记应该更高到基类。