我正在映射遗留数据库,其中一个表使用鉴别器列使用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特定扩展)中优雅地映射这个?我可以使用的唯一解决方案是放弃继承并将列映射为普通字段,在特殊情况下在内部对该值进行切换,但这感觉不自然且有点脏。
答案 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;
}
}
然后为您的类编写定制器并使用它们进行注释。