JPA中的SINGLE_TABLE策略和getter中的@Discriminator继承

时间:2012-02-02 09:39:59

标签: inheritance jpa entity getter discriminator

具有SINGLE_TABLE策略的JPA实体中的继承问题。在getter @Discriminator中减少继承范围。

我有以下结构:

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="type")
@DiscriminatorValue("A")
class A {
...
}

@Entity
@DiscriminatorValue("B")
class B extends A {
...
}

@Entity
@DiscriminatorValue("C")
class C extends B {
...
}

@Entity
class Something{
@ManyToMany // blah blah
private List<B> listB; // getters and setters
}

问题如下。我有C类的对象(假设继承C也是B)。当我在做的时候:

Something s = Something.findById(11); // Here is listB with elements of type C and B
List<B> listB = s.getListB();

我只获取B类的对象,没有C.但是C扩展了B,因此它也应该在列表中。 Getter构造了这样一个查询:

SELECT t1.id, t1.type, t1.sys_modified_date, t1.sys_created_date, t1.name,  t1.shortName
FROM something_b t0 INNER JOIN A t1 ON t0.listB = t1.id 
WHERE t0.news = ? AND t1.type = ? 
[params=(long) 205, (String) B]

问题是这个getter(Something.getListB)只将这个列表减少到B类(通过鉴别器B)。这导致对象类C不在列表中。它是由@Discriminator通过指示严格类型“t1.type = B”引起的。它不允许放置像“t1.type IN(B,C)”这样的集合/列表。

自定义JPQL查询是以不同方式构造的:

SELECT t1.id, t1.type, t1.sys_modified_date, t1.sys_created_date, t1.name,  t1.shortName
FROM something_b t0 INNER JOIN A t1 ON t0.listB = t1.id 
WHERE t0.news = ? AND t1.type IN (?, ?) 
[params=(long) 205, (String) B, (String) C]

他们按照自己的意愿工作。但是getter呢?

有趣的是,当我将Something类从B类更改为A类(基础为所有)时:     @实体     class Something {     @ManyToMany //等等等等     私人清单A; // getter和setter     }

这解决了问题。在getter中查询:

SELECT t1.id, t1.type, t1.sys_modified_date, t1.sys_created_date, t1.name,  t1.shortName
FROM something_b t0 INNER JOIN A t1 ON t0.listB = t1.id 
WHERE t0.news = ? 
[params=(long) 205]

消失“AND t1.type =?”。它有效,但它干扰了从“真实世界对象”到“ORM实体”的映射。该解决方案发生变化,使抽象变得更糟。这不是优雅的解决方案。

问题:

我该如何解决这个问题?

我可以在getter中使用自定义JPQL查询吗?

如何强制getter获取B和C对象?

你有另一个命题,而不是改变List to List ???

1 个答案:

答案 0 :(得分:0)

您使用的是哪个JPA提供商?听起来像个臭虫。这应该适用于EclipseLink。