当前位置:  开发笔记 > 数据库 > 正文

NHibernate - 更改子类型

如何解决《NHibernate-更改子类型》经验,为你挑选了2个好方法。

你如何改变NHibernate中行的子类型?例如,如果我有一个Customer实体和TierOneCustomer的子类,我有一个案例需要将Customer更改为TierOneCustomer,但TierOneCustomer应该具有与原始Customer实体相同的Id(PK).

映射看起来像这样:


  
    
  
  
  ... properties snipped ...

  
    ... more properties ...
  

我正在使用每个类的单表层次结构模型,因此使用plain-sql,只需要对鉴别器(CustomerType)进行sql更新,并设置与该类型相关的相应列.我无法在NHibernate中找到解决方案,所以会感激任何指针.

考虑到这个用例,我也在考虑模型是否正确,但在我沿着这条路走下去之前,我想确保首先按照上述方式进行操作.如果没有,我几乎肯定会考虑改变模型.



1> David Crow..:

简而言之,您可以使用本机SQL更改特定行的鉴别器值.

但是,我认为NHibernate并不打算以这种方式工作,因为鉴别器通常对Java层是"不可见的",其值应该根据持久对象的类最初设置并且永远不会改变.

我建议采用更清洁的方法.从对象模型的角度来看,您尝试将超类对象转换为其子类类型之一,同时不更改其持久化实例的标识,这就是冲突的位置(转换后的对象实际上不应该是同一件事情).两种替代方法是:

根据原始Customer对象中的信息创建TierOneCustomer的新实例,然后删除原始对象.如果您依靠客户的主键进行检索,则需要注意新的PK.

要么

更改您的方法,以便对象类型(鉴别器)不需要更改.您可以使用可以随时自由修改的属性,即Customer.Tier = 1,而不是依赖子类来区分TierOneCustomer和Customer.

以下是可能感兴趣的Hibernate论坛的一些相关讨论:

    我们可以更新Hibernate中的discriminator列吗?

    每类表问题:判别器和属性

    将持久化实例转换为子类



2> yfeldblum..:

你做错了什么.

您要做的是更改对象的类型.你不能用.NET或Java做到这一点.这根本没有意义.对象只是一种具体类型,其具体类型不能从创建对象到对象被销毁时更改(尽管是黑魔法).为了完成您要执行的操作,但是使用您布置的类层次结构,您必须销毁要转换为第一层客户对象的客户对象,创建新的第1层客户对象,并将客户对象中的所有相关属性复制到第一层客户对象.这就是您使用类层次结构在面向对象语言中使用对象的方法.

显然,您拥有的类层次结构并不适合您.当他们成为一线客户时,您不会摧毁现实生活中的客户!所以不要用对象做.相反,考虑到您需要实现的方案,提出一个有意义的类层次结构.您的使用场景包括:

以前不是第一级状态的客户现在变为第一级状态.

这意味着您需要一个可以准确捕获此场景的类层次结构.作为提示,你应该赞成合成而不是继承.这意味着,根据最有效的方法,拥有一个名为IsTierOneproperty的属性或一个名为的属性DiscountStrategy等可能是更好的主意.

NHibernate(和Hibernate for Java)的全部目的是使数据库不可见.为了让您可以本机地使用对象,可以在数据库中神奇地使用数据库来使对象持久化.NHibernate将允许您本地使用数据库,但这不是为NHibernate构建的场景类型.

推荐阅读
依然-狠幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有