JPA(Hibernate)SINGLE_TABLE继承catch-all鉴别器值?

时间:2013-05-10 18:00:17

标签: hibernate jpa single-table-inheritance discriminator

我正在映射遗留数据库,其中一个表使用鉴别器列使用SINGLE_TABLE映射自然地映射到继承层次结构。问题是存在大量的鉴别器值! (此外,偶尔会添加新的应用程序,应用程序应自动在多态查询中选择它们)。从我的应用程序的角度来看,我想以相同的方式处理这些不同类型的绝大多数(即,只是将它们映射到继承层次结构中的基类)。但是,对于少数人,我想映射到一个特定的子类。问题是JPA似乎要求我在基类上提供一个特定的@DiscriminatorValue(否则它会生成一个默认的)。

具体:

@Entity
@Table("products")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "product_type")
@DiscriminatorValue( *anything not specified elsewhere!* )
public class Product {
    ...
    public double calculateMarkup() { ... default impl ... }
}
@Entity
@DiscriminatorValue("ProductA")
public class ProductA extends Product {
    ...
    @Override public double calculateMarkup() { ... specific impl ... }
}

有没有办法在JPA(或Hibernate 3.3特定扩展)中优雅地映射这个?我可以使用的唯一解决方案是放弃继承并将列映射为普通字段,在特殊情况下在内部对该值进行切换,但这感觉不自然且有点脏。

3 个答案:

答案 0 :(得分:1)

  

有没有办法在JPA中优雅地映射

不,不是我所知道的。如果问题是在数据层(即数据或数据库)上引起的,我会尝试在该层上解决它。尝试以下两种方法之一:

  • 在数据库中创建一个与表相同的视图,除了“其他未指定的内容”被映射*到默认的鉴别器
  • Product表上写入一个插入/更新触发器,用于修复每个重新校正的鉴别值*。

*例如,Oracle提供DECODE来将范围A中的值映射到范围B if-then-else-like。

答案 1 :(得分:1)

我使用@DiscriminatorFormula(here)解决了同样的问题。鉴别器公式返回

CASE WHEN (product_type!='ProductA') THEN 'LEGACY'
ELSE product_type

和产品实体有@DiscriminatorValue(' LEGACY')

答案 2 :(得分:0)

使用@ClassExtractor:http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Entities/Inheritance#Example:_Using_ClassExtractor_do_define_inheritance

这样的东西
public class ProductExtractor implements ClassExtractor {
    public void extractClassFromRow(Record row, Session session) {
        if (row.get("product_type").equals("ProductA")) {
            return ProductA.class;
        } 
        return Product.class;
    }
}

然后为您的类编写定制器并使用它们进行注释。