Reputation: 2061
In my Spring application I have an entity called Resource::
@Entity
public class Resource {
List<Resource> list = em.createNativeQuery("select r.* from ...", Resource.class).getResultList();
For one specific purpose, I need a few more fields to be added to the results. So I created a subclass ExtendedResource:
@Entity
public class AreaResource extends Resource {
@Column(name="extra_field")
private Integer extra field;
List<ExtendedResource> list = em.createNativeQuery("select extra_field, r.* from ...", ExtendedResource.class).getResultList();
This works fine when I query for ExtendedResource, but for Resource I get:
org.postgresql.util.PSQLException: The column name DTYPE was not found in this ResultSet.
Is there any way around this, without bothering with a discriminator column? I guess MappedSuperclass
is a solution, but I would like to avoid making extra classes.
Thanks
Upvotes: 8
Views: 15985
Reputation: 1923
The solution is:
Add 0 as dtype
into select fields.
@Entity
@DiscriminatorValue("0")
public class Resource {...}
List<Resource> list = em
.createNativeQuery("select 0 as dtype, r.* from ...", Resource.class)
.getResultList();
0 is the super class DiscriminatorValue, can change to the value what you want.
Upvotes: 0
Reputation: 101
I think you're going to have to define the DiscriminatorColumn.
The default strategy, InheritanceType.SINGLE_TABLE, is used if the @Inheritance annotation is not specified on the root class of the entity hierarchy.
With the single table strategy, the entire class hierarchy is persisted in one big single table. A discriminator column is required to differentiate between which class type is persisted in a particular row
The default name of the column to be used as the discriminator column is DTYPE.
https://docs.oracle.com/javaee/6/api/javax/persistence/DiscriminatorColumn.html https://docs.oracle.com/javaee/6/tutorial/doc/bnbqn.html
Upvotes: 5
Reputation: 24433
A trivial problem, but no way around it without some coding :)
Other than creating a @MappedSuperclass
(which, as you said, is a solution), or creating an entity hierarchy (with DTYPE
), you could call em.createNativeQuery(sql)
without the resulting class, which would give you the result in the form of List<Object[]>
. Then, for each row create a new instance of ExtendedResource
in a loop. If you go for this option, make sure you specify all the columns one by one instead of using *
, to ensure the order in which they are returned.
This way, you might even create a @Transient
extra field in the Resource
class, and eliminate the need for additional class.
It's just a matter of personal preference which of the approaches suites you best. @MappedSuperclass
seems to involve the least amount of coding.
Upvotes: 5