问题 ORM继承


有没有人  想要并在ORM工具上使用继承支持,如果是,您认为哪一个提供最好的支持?

或者ORM继承是“天上的馅饼”概念?


3216
2018-02-27 14:25


起源

ORM继承是什么意思? - Mladen Prajdic
能够从其他实体类派生实体类。 - Otávio Décio


答案:


我很喜欢这个问题。我已经使用ORM工具(Toplink,现在是eclipselink,Hibernate)一段时间,我一直认为这是JPA文档中引用的,但我从来没有真正需要它。基本上我的理念是ORM只是为了阻止你编写tedius代码来提取数据库的记录。这确实是一个巨大的节省时间,它可以防止你犯下愚蠢的错误。当然你可以用这个做一些奇特的东西,但为什么不把它保存到控制器(如果你跟随MVC)而不是把它粘在模型中?


5
2018-02-27 14:34



那么你会说传统的“每桌一类”方法适用于大多数情况吗? - Otávio Décio
在我的情况下,这是我一直找到的。使用继承只会混淆映射IMO,而不是任何有用的玩具。 - GBa


我已经使用了Hibernate的继承(以及一些使用Django),并且非常遗憾。

对于域类,“基于继承的组合”原则尤其如此。虽然我同意在某些情况下继承在模型级别有​​意义,但在大多数情况下,继承将为您提供一个非常静态的域模型,其中一个对象将无法更改为另一个类。

我还发现大多数开发人员对数据库级别的继承概念不满意,因此维护变得更加复杂。

最后,还有一些技术问题,比如Hibernate设置的代理将隐藏对象的实际类。它使“实例”表现得很苛刻。当然,你可能会说“实例”是代码气味,也许这是另一个暗示,组成可能是一个更好的解决方案......


6
2018-02-27 14:48



看起来像每个表的直接类(有组合)是从我在这里阅读的方式。感谢您的见解。 - Otávio Décio
不同意。如果您记住,您无法将实体从一个类更改为另一个类,这是一种非常强大的技术,因为它允许您将常用的OOP知识应用于其他关系模型。 - Mauricio Scheffer
至于检查代理背后的实际类型,它非常臭...使用访问者或多态: hibernate.org/280.html - Mauricio Scheffer
当然,继承的良好构成也是常见的OOP知识,但有时继承更方便(哦不,我听到火焰战即将来临!;-))无论如何,它是你可以(或不)使用的另一种工具。 - Mauricio Scheffer
@mausch - 如果你使用的是ORM工具,你会认为继承“必不可少”或者只是“很高兴”吗? - Otávio Décio


如果你的意思是域类中的继承,我会一直使用NHibernate和/或Castle ActiveRecord,它们支持三种映射策略:


3
2018-02-27 14:32



谢谢,我会检查出来的。 - Otávio Décio
@Mauricio我正在研究一个我们将调用的记录类型的项目 Master。大约有17种类型的主记录,大多数具有相似的数据字段,但每个可能有一个或两个唯一字段。我之前的人使用继承来创建一个包含17个实体子类的Master实体类。起初这看起来很棒,但在使用它一段时间后,我想知道是否一个 Master 允许空值的表可能不会更好(例如,数据库中现在有17个不同的表,我不能轻易地将一种类型更改为另一种类型)。我真的很感激你的想法。 - theblang
@mattblang嗨Matt,不要将域类中的继承与映射策略混淆。您可以将17个子类映射到单个表或单个表,请查看NHibernate文档以供参考。如果您需要将一种类型更改为另一种类型,您已经注意到一般的继承,特别是每个类的表,都不能很好地工作。 - Mauricio Scheffer


如果您正在编写复杂的商业软件,那么您需要它。

假设您希望能够向个人或组织销售产品。在销售订单上,买方将是一个或另一个。没有继承你怎么做?

继承,你会做这样的事情:

@Entity
@Inheritance
public abstract class Party {

  @Id
  private Long id;

  ...
}

@Entity
public class Individual extends Party {
  ...
}

@Entity
public class Organization extends Party {
  ...
}

@Entity
public class SalesOrder {

  private Party buyer;

  ...
}

然后你可以这样做:

salesOrder.setBuyer(someOrganization) 要么 salesOrder.setBuyer(someIndividual)


1
2018-02-03 05:10