Mariomario85
Mariomario85

Reputation: 1

Inheritance with SINGLE_TABLE strategy in JPA and @Discriminator in getter

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

Answers (1)

James
James

Reputation: 18379

What JPA provider are you using? Sounds like a bug. This should work with EclipseLink.

Upvotes: 0

Related Questions