映射Hibernate“自定义”子类

时间:2010-01-12 17:29:20

标签: hibernate mapping subclass

作为一个新的Hibernate用户,我听说为生成的类添加一些辅助方法的好方法是将它们添加到子类中。例如:

// generated via  Hibernate mapping file
public class GeneratedClass {
  long id;
  String someValue;

  // etc, etc.
}

// my own class with pretty printing method
public class MyGeneratedClass extends GeneratedClass {
  public String prettyPrint() {
     return "an object: " + id + "," + someValue;
  }
}

我希望能够做到以下几点:让Hibernate返回MyGeneratedClass类型的对象而不是GeneratedClass,以便我可以直接使用子类。可以用这种方式定义映射文件(即,没有代码覆盖任何自定义代码)?

对于任何可能的解决方案,如果GeneratedClass是类层次结构的一部分(即GeneratedClassTypeA,GeneratedClassTypeB都扩展了GeneratedClass),这种模式是否仍然有效?

我认为另一种方法是创建一个静态工厂方法来从GeneratedClass创建MyGeneratedClass,但这对于大量对象来说似乎效率低下。

提前致谢!

修改

在尝试了联合类策略之后,我意识到由于现有的类层次结构和数据,它在我的情况下不起作用。另外,我无法控制覆盖我的子类的生成(可能是hbm2java中的一个理想特性?)。最后,我确实考虑将代码嵌入到映射文件中,但是覆盖诸如getter和setter之类的东西看起来相当繁琐。

我回顾了这个方法并决定使用注释域对象并避免完全使用hbm2java。它并不完全理想(映射似乎更容易处理),但是从我从各种来源收集的内容来看,它可能是处理我的特定情况的最合适的方式,因为它让我可以自由地使用类型检查来自定义代码并且只处理类文件。

我欢迎对我的解决方案有任何其他想法或评论。

编辑2

下面提出的解决方案,使用

<meta attribute="generated-class">CountryBase</meta>

是原始描述的原始问题的一个很好的解决方案。 但是,我发现使用对象层次结构和使用超类方法对此解决方案不起作用,在这种情况下,注释似乎是更好的选择。

1 个答案:

答案 0 :(得分:1)

  

我希望能做的是   以下内容:让Hibernate返回   MyGeneratedClass类型的对象   而不是GeneratedClass让我   可以直接使用子类。   可以在中定义映射文件   这样吗?

是的,您只需在映射中指定子类:<class name="Subclass" table="table">。然后使用Subclass.class查询实体。

  

对于任何可能的解决方案,如果   GeneratedClass是类的一部分   层次结构(即GeneratedClassTypeA,   GeneratedClassTypeB都扩展了   GeneratedClass),这种模式   还在工作吗?

是。只要映射中定义的属性存在于类中(因为继承),它就应该有效。

  

我想是另一种选择   创建一个静态工厂方法   从中创建MyGeneratedClass   GeneratedClass,但似乎   大量的低效率   对象。

确实

修改

我没有从你的问题中了解到你从映射中生成了类。我以为它是从其他模型生成的,它会吐出映射和类。你的评论澄清了这一点。然后我会尝试使用hibernate inheritance

的方法
<class name="GeneratedClass" abstract="true">
    <id name="id" type="long" column="XXX">
        <generator class="sequence"/>
    </id>
    <property name="zzzz" column="ZZZZ"/>
    ...
    <union-subclass name="SubClass" table="TABLE">
    </union-subclass>
</class>

我没有测试上面的代码片段,但我相信你的场景可以按照这种或那种方式进行映射。 abstract=true可能是多余的,但它表明父超类不应该是实例化的。子类没有其他属性,因此subclass标记为空。

编辑2

您是否也尝试使用<meta attribute="generated-class">CountryBase</meta>?从未使用它,但似乎符合这个目的。请参阅Hibernate Class Generation with hbm2java

中的“使用基类”