【问题标题】:Grails/Groovy domain classes inheritance castGrails/Groovy 域类继承转换
【发布时间】:2012-07-11 09:13:20
【问题描述】:

我已经在 Grails 中为我的域类建模,如下所示。

abstract class Profile{
}

class Team extends Profile{
}

class User extends Profile{
}

class B{
    static hasMany = [profiles: Profile]
}

稍后在控制器中,当我从 B 类中获取所有配置文件时,在某些情况下,我想将一些配置文件转换为 Team 或 User,但我不能,因为我得到了 java.lang.ClassCastException 或GroovyCastException,尽管它们被保存为 Team 或 User(具有数据库中的属性类)。以下是我尝试过的方法:

def team1 = b.profiles.toList()[0] as Team

def team1 = (Team)b.profiles.toList()[0]

当我不编写任何类型时它就可以工作,只是使用它,因为它在动态语言中是正常的。

def team1 = b.profiles.toList()[0]

但是我永远不知道我在使用哪个类。 groovy 或 gorm 中是否有将父类转换为子类的方法?

【问题讨论】:

  • 没有discriminator 供gorm 在UserTeam 之间选择。 gorm 应该如何决定使用哪个实现?
  • 它保存到数据库中的同一个表中,并带有一个类属性,该属性指示它是哪个类。

标签: grails inheritance groovy grails-orm


【解决方案1】:

答案是,因为真正的 GORM/Hibernate 实例是一个代理对象。所以不能直接转换为实体类。

无论如何这可能会有所帮助:

def team1 = b.profiles.toList()[0]
if(team1.instanceOf(Team)) {
    // I am an instance of Team
    // do something here.
}

【讨论】:

  • 它正在工作,但实际上这不是我的问题。我的问题是是否有办法将基类显式转换为子类。
  • 不,因为休眠代理不一定是 Java 意义上的 instanceof 子类。代理类是b.profiles(即Profile)的已声明类型的动态生成的子类。 This article 有血淋淋的细节,它(以及同系列的其他文章)非常值得一读。
  • 总是有GrailsHibernateUtil.unwrapIfProxy,它将删除代理包装器并为您提供真实对象(然后您可以投射)但如果尚未加载真实对象,则必须访问数据库.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多