4

I use Spring along with Hibernate. In my DAO, I defined a NamedQuery which is not found by the session factory, although I have added the package of that DAO to the packagesToScan.

My DAO:

/**
 * 
 */
package org.lalala.service.mytest;

import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;


import  org.lalala.objects.Unit;


@NamedQueries
({
    @NamedQuery
    (
        name="unit.findById",
        query="from Unit u where u.unitid = :unitId"
    )
})
public class MyTestDaoImpl implements MyTestDao
{

    private SessionFactory sessionFactory;


    public MyTestDaoImpl(SessionFactory sessionFactory)
    {
        super();
        this.sessionFactory = sessionFactory;
    }



    /* (non-Javadoc)
     * @see org.lalala.service.mytest.MyTestDao#getRandomUnit()
     */
    @Override
    public Unit getRandomUnit()
    {
        long unitid = 2891;
        try {
            Session session = sessionFactory.getCurrentSession();
            session.beginTransaction();

            Query query = session.getNamedQuery("unit.findById");
            query.setParameter("unitId", unitid);

            Unit unit = (Unit) query.uniqueResult();

            session.getTransaction().commit();

            return unit;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }
    }    

}

And here the Spring config method for providing a session factory:

@Bean
public AnnotationSessionFactoryBean  getSessionFactory() {
    final AnnotationSessionFactoryBean  sessionFactory = new  AnnotationSessionFactoryBean ();
    sessionFactory.setDataSource(getDataSource());

    String[] packages = new String[]{"org.lalala.avalon.service.mytest"};

    sessionFactory.setAnnotatedPackages(packages);

    Properties properties = new Properties();
    properties.put("hibernate.current_session_context_class", "thread");
    sessionFactory.setHibernateProperties(properties);

    return sessionFactory;
}

And here the exception which is thrown:

org.hibernate.MappingException: Named query not known: unit.findById

Because of some similar stackoverflow questions, I replaced the hibernate @NamedQuery annotation with JPA equivalent. Did not help.

rainer198
  • 3,195
  • 2
  • 27
  • 42

2 Answers2

6

you have to put the named queries on your entity, not on the dao

here is an example

Community
  • 1
  • 1
NimChimpsky
  • 46,453
  • 60
  • 198
  • 311
  • Thanks, I remembered having put them in DAOs in a past JEE project, but I remembered wrong. – rainer198 Oct 14 '11 at 06:05
  • 6
    Nevertheless, I think, it would make sense to allow NamedQueries in DAOs. Sometimes, they get quite complex and support (are part of) some business logic usecase which might not be general enough to put it in the entity. It could also be, that you as developer have third-party entities and you want to write a DAO with specific fetching strategies. Finally, a NamedQuery could be over multiple entity classes and it is not obvious in which one to define it – rainer198 Oct 14 '11 at 06:13
1

If you annotate your DAO with @MappedSuperclass then you can put your NamedQueries in the DAO. Don't forget to add the package of the DAO or the DAO-class itself to the list of annotated packages/classes.

Hans
  • 43
  • 3