persistence@glassfish.java.net

RE: map non-entity using _at_SqlResultSetMapping

From: Gordon Yorke <gordon.yorke_at_oracle.com>
Date: Tue, 19 Dec 2006 12:18:29 -0500

Hello Maurice,
    Please file a bug supplying your testcase for the NullPointerException as these should never happen. One thing I would like to note the return type of a NativeQuery will be a list of Object[]. For each ColumnResult an entry will be made in the Object Array with the result value. ColumnResults are not 'mapped' to any objects by the Persistence Provider you will need to take the results from the native query and create the VirtualBatch in your code.
    Alternatively if you can re-create the query in JPAQL you can leverage the constructor expression and have TopLink build VirtualBatch objects directly using a 'full' constructor.
--Gordon

-----Original Message-----
From: Maurice Marrink [mailto:marrink_at_gmail.com]
Sent: Tuesday, December 19, 2006 7:56 AM
To: persistence_at_glassfish.dev.java.net
Subject: map non-entity using @SqlResultSetMapping


Hi,

I have a simple entity and need to collect some aggregated data on it.
Preferably i want this result returned as a simple pojo.

It looks like @SqlResultSetMapping could do the trick but so far i
keep getting the following stacktrace

java.lang.NullPointerException
     at oracle.toplink.essentials.queryframework.ResultSetMappingQuery.buildObjectsFromRecords(ResultSetMappingQuery.java:144)
     at oracle.toplink.essentials.queryframework.ResultSetMappingQuery.executeDatabaseQuery(ResultSetMappingQuery.java:199)
     at oracle.toplink.essentials.queryframework.DatabaseQuery.execute(DatabaseQuery.java:609)
     at oracle.toplink.essentials.queryframework.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:536)
     at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2218)
     at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:937)
     at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:909)
     at oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:346)
     at oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.getResultList(EJBQueryImpl.java:447)
     at nl.introweb.pgn.logic.MeldingDAOBean.search(MeldingDAOBean.java:51)

which seems to indicate a mapping problem :)

So far all the examples i have seen put the @SqlResultSetMapping on
the entity instead of using a throw away pojo. If someone with a
better understanding of jpa could point me in the right direction i
would be grateful.

My persistent entity is declared as follows
@Entity
public class Melding implements Serializable
{
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
        @Lob
        private String xmlBericht;
        private String PGN;
        private int status;
        private Date statusDatum;
        private boolean validatieAfgekeurd;
        private boolean idAfgekeurd;
        private Date binnengekomenDatum;
        private Date validatieDatum;

        @ManyToOne
        private Instelling instelling;

        @OneToMany(mappedBy="melding")
        private List<Signaal> validatieResultaten;
....
}

The query in my ejb is as follows
Query query = em.createNativeQuery("select melding.binnengekomenDatum
datum, count(melding.binnengekomenDatum) aantalLeerlingen,
instelling.verwachtAantalLeerlingen, 0 score from Melding melding
inner join instelling on melding.instelling_id=instelling.id where
melding.instelling_id = #instelling group by
melding.binnengekomenDatum,
instelling.verwachtAantalLeerlingen","virtualBatch");
query.setParameter("instelling", instellingId);
return query.getResultList();

And the pojo i would like to map my result to
@SqlResultSetMapping(name="virtualBatch",
columns={_at_ColumnResult(name="datum"),_at_ColumnResult(name="aantalLeerlingen"),_at_ColumnResult(name="verwachtAantalLeerlingen"),_at_ColumnResult(name="score")})
public class VirtualBatch implements Serializable
{
        private static final long serialVersionUID = 1L;
        private Date datum;
        private int aantalLeerlingen;
        private int verwachtAantalLeerlingen;
        private int score;
}

Thanks,

Maurice