Reputation: 1
Problem with Inheritance in JPA Entities with SINGLE_TABLE strategy. In getters @Discriminator reduce range of inheritance.
I have the following structure:
@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
}
Problem is following. I have object of class C (assuming inheritance C is also B). When I'm doing:
Something s = Something.findById(11); // Here is listB with elements of type C and B
List<B> listB = s.getListB();
I fetch only objects of class B, none C. But C extends B, so it also should be on the list. Getter constructs such a query:
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]
Problem is that this getter (Something.getListB) reduce this list only to class B (by discriminator B). This results that object class C is not on the list. It is caused by @Discriminator by indicating strict type "t1.type = B". It doesn't allow to put there a set / list like "t1.type IN (B,C)".
Custom JPQL queries are constructs in different way:
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]
and they work as they should. But what about getter?
Interesting is fact that when I change Something class from B class to A class (base for all): @Entity class Something{ @ManyToMany // blah blah private List listA; // getters and setters }
this solves problem. In getter in query:
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]
dissapears "AND t1.type = ?". It works but it disturbs mapping from "real world objects" to "ORM entities". That solution changes, makes worse that abstraction. It is not elegant solution.
Question:
How can I solve this problem?
Can I use custom JPQL query in getter?
How to force that getter to fetch B and C objects?
Do you have another proposition instead of change List to List???
Upvotes: 0
Views: 893
Reputation: 18379
What JPA provider are you using? Sounds like a bug. This should work with EclipseLink.
Upvotes: 0