Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA: The column name DTYPE was not found in this ResultSet

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

like image 500
user3170702 Avatar asked Oct 27 '15 15:10

user3170702


Video Answer


2 Answers

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

like image 26
zmelvin Avatar answered Nov 02 '22 07:11

zmelvin


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.

like image 111
Predrag Maric Avatar answered Nov 02 '22 08:11

Predrag Maric