Search code examples
postgresql-9.3jpa-2.1hibernate-4.x

JPA native query with @DiscriminatorFormula throws NullPointerException on Hibernate/Postgres layer


(find the postgres 9.3 and hibernate 4.3.7 versions in the stacktrace below)

My base and one sample subtype entities:

import javax.persistence.Entity;
import org.hibernate.annotations.DiscriminatorFormula;
import javax.persistence.DiscriminatorValue;

@Entity
@DiscriminatorFormula( value = "'test'" )
public abstract class Base {
   @Id String id;
}

@Entity
@DiscriminatorValue( value = "test" )
public class Sub extends Base {
}

Calling

myEntityManager.createNativeQuery( someSql, Base.class ).getResultsList()

results in

java.lang.NullPointerException: null
    at org.postgresql.jdbc2.AbstractJdbc2ResultSet.findColumnIndex(AbstractJdbc2ResultSet.java:2758) ~[postgresql-9.3-1102-jdbc41.jar:na]
    at org.postgresql.jdbc2.AbstractJdbc2ResultSet.findColumn(AbstractJdbc2ResultSet.java:2726) ~[postgresql-9.3-1102-jdbc41.jar:na]
    at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getString(AbstractJdbc2ResultSet.java:2568) ~[postgresql-9.3-1102-jdbc41.jar:na]
    at com.mchange.v2.c3p0.impl.NewProxyResultSet.getString(NewProxyResultSet.java:3326) ~[c3p0-0.9.2.1.jar:0.9.2.1]
    at org.hibernate.type.descriptor.sql.VarcharTypeDescriptor$2.doExtract(VarcharTypeDescriptor.java:74) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:267) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:263) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:258) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.loader.Loader.getInstanceClass(Loader.java:1759) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1587) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.loader.Loader.getRow(Loader.java:1515) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:726) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.loader.Loader.processResultSet(Loader.java:953) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.loader.Loader.doQuery(Loader.java:921) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.loader.Loader.doList(Loader.java:2554) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.loader.Loader.doList(Loader.java:2540) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.loader.Loader.list(Loader.java:2365) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:353) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:1873) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.internal.AbstractSessionImpl.list(AbstractSessionImpl.java:311) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:141) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:573) ~[hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
    at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:449) ~[hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]

Solution

  • As a solution: adding some discriminator column to my sql:

    select
      orig.*, 
      'test' as dtype
    from (
      ... orig sql
    ) orig
    

    and changing the Base to:

    @Entity
    @DiscriminatorColumn( name = "dtype" )
    public abstract class Base { ... }
    

    works fine.