2

您能否描述在代表模型中实体的POJO中包含OID(通常是数据库行标识符)的优缺点?

事实上,我不是在谈论与 equals/hashcode 等相关的问题,我应该更好地描述我的问题(我的错误:))...

我们有一些代表业务对象的实体类(如产品、目录等......)。有时他们有一个“企业 id”,例如可以通过其唯一的 ProductId 找到产品(它有 3 个字段:id、类型、存储库)。

在我们的数据库中,除了 3 个业务列(id、type、repository)之外,Product 表还有一个代理主键列 (OID),以方便外键引用并减少连接子句。

Product/ProductId 类是我们向其他应用程序公开的 API 的一部分。例如,他们可以调用:

productManager.findProductById(ProductId productId);

问题是,知道我们的客户应该使用 ProductId 标识符,是否应该将 OID 包含在 Product 或 ProductId 类中。

优点:

  • 我可以使用 OID 进行另一个查找,例如

    Product p = productManager.findProductById(ProductId productId);
    Catalog c = productManager.findAllCatalogsContainingProduct(p.getOid());
    

我们习惯于通过 ProductId 在应用程序中查找很多内容,因此这可以节省每次往返数据库的时间,以避免找到与 ProductId 匹配的 OID。

缺点:

  • 我刚刚向客户公开了 OID(希望他不要使用它而不是业务密钥!!)

你能列出其他优点和缺点吗?

4

2 回答 2

1

数据库行标识符 = 主键?如果是这样,则没有优点或缺点,您必须拥有它,否则您无法将 POJO 关联回其相应的数据库行。

要检索产品和目录,标准的 SQL 方法是进行联接。例如,使用我的 DAL,我可以:

SearchCriteria sc = new SearchCriteria();
sc.AddBinding("ProductId", productId);
List<Entity> Products = SQL.Read(sc, new Product(new Catalog());

或者

List<Entity> Products = SQL.Read(sc, new Catalog(new Product());

这样就不需要向调用者透露任何信息,也不需要往返。

于 2008-12-31T17:34:31.900 回答
0

如果您的 equals() 或 hashCode() 的实现基于标识符,您可能会遇到问题,因为它最初可能为 null,然后在对象持久化后更改。见下文:

http://java.sun.com/javase/6/docs/api/java/util/Set.html

注意:如果将可变对象用作集合元素,则必须非常小心。如果对象的值以影响等于比较的方式更改,而对象是集合中的一个元素,则不指定集合的​​行为。此禁令的一个特殊情况是不允许集合包含自身作为元素。

假设您的 hashCode() 实现基于标识符,而 equals() 在其比较中使用 hashCode()。如果您将对象添加到 Set 并且其标识符为 null,则等于比较将以一种方式执行。如果您随后将对象保存在集合中,则其标识符值可能会更改,从而更改 equals() 和 hashCode() 的行为。如上所述,这打破了 Set 的“合同”。

这有点极端,但值得注意。

于 2008-12-31T17:38:48.350 回答