3

I have Hibernate JPA application. I keep getting "java.lang.IllegalArgumentException: No query defined for that name [Singer.findAll]" in the function from DAO class, even though I defined the name in @NamedQuery correctly. Here are my Entity class

package ch8.entities;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "singer")
@NamedQueries({
        @NamedQuery(name = Singer.FIND_BY_ID,
                query = "select distinct s from Singer s "
                        + "left join fetch s.albums a "
                        + "left join fetch s.instruments i "
                        + "where s.id = :id"),

        @NamedQuery(name = Singer.FIND_ALL_WITH_ALBUM,
                query = "select distinct s from Singer s "
                        + "left join fetch s.albums a "
                        + "left join fetch s.instruments i"),

        @NamedQuery(name = Singer.FIND_ALL,
                query = "select s from Singer s")
})
@SqlResultSetMapping(name = "singerResult",
        entities = @EntityResult(entityClass = Singer.class))
public class Singer implements Serializable {
    private Long id;
    private String firstName;
    private String lastName;
    private Date birthDate;
    private Long version;
    private Set<Album> albums = new HashSet<>();
    private Set<Instrument> instruments = new HashSet<>();
    public static final String FIND_ALL = "Singer.findAll";
    public static final String FIND_BY_ID = "Singer.findById";
    public static final String FIND_ALL_WITH_ALBUM = "Singer.findAllWithAlbum";

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "FIRST_NAME")
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @Column(name = "LAST_NAME")
    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "BIRTH_DATE")
    public Date getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    @Version
    @Column(name = "VERSION")
    public Long getVersion() {
        return version;
    }

    public void setVersion(Long version) {
        this.version = version;
    }

    @OneToMany(mappedBy = "singer", cascade = CascadeType.ALL, orphanRemoval = true)
    public Set<Album> getAlbums() {
        return albums;
    }

    public void setAlbums(Set<Album> albums) {
        this.albums = albums;
    }

    @ManyToMany
    @JoinTable(name = "singer_instrument",
    joinColumns = @JoinColumn(name = "SINGER_ID"),
    inverseJoinColumns = @JoinColumn(name = "INSTRUMENT_ID"))
    public Set<Instrument> getInstruments() {
        return instruments;
    }

    public void setInstruments(Set<Instrument> instruments) {
        this.instruments = instruments;
    }

    @Override
    public String toString () {
        return "Singer - Id: " + id + ", First name: "
                + firstName + ", Last name: " + lastName
                + ", Birthday: " + birthDate;
    }

    public boolean addAlbum(Album album) {
        if (albums == null) {
            albums = new HashSet<Album>();
            albums.add(album);
            return true;
        }
        if (albums.contains(album))
            return false;
        albums.add(album);
        return true;
    }

    public boolean removeAlbum(Album album) {
        if (album == null)
            return false;
        if (!albums.contains(album))
            return false;
        albums.remove(album);
        return true;
    }
}

and DAO class

package ch8.dao;

import ch8.entities.Singer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.Collection;

@Transactional
@Repository("singerDao")
public class SingerDao implements Dao<Singer> {
    @PersistenceContext
    private EntityManager entityManager;

...some other functions...

    @Override
    @Transactional(readOnly = true)
    public Collection<Singer> findAll() {
        return entityManager.createNamedQuery(Singer.FIND_ALL, Singer.class).getResultList();
    }

...some other functions...

}

I suggest it might be something with class mapping, because regular createQuery(String, Class) doesn`t work as well.

5
  • a priori everything seems correct, could you perform the test by putting a string "test" both in the name of the named query definition and in the createNamedQuery method? Commented Jun 16, 2020 at 16:06
  • If I understood you correctly, you are talking about something like this @NamedQuery(name = "test", query = "select s from Singer s") and return entityManager.createNamedQuery("test", Singer.class).getResultList(); In this case the result is the same (java.lang.IllegalArgumentException: No query defined for that name [test]) Commented Jun 18, 2020 at 14:08
  • In your persistence.xml you set transaction-type="RESOURCE_LOCAL" to your persistence-unit? you put this property <property name="hibernate.archive.autodetection" value="class, hbm" /> to autodetect? Commented Jun 18, 2020 at 14:28
  • I am writing my code according to the example from Pro Spring 5: An In-Depth Guide to the Spring Framework and Its Tools (5th edition). There is no persistance.xml in it Commented Jun 19, 2020 at 11:18
  • the moment you use @PersistenceContext private EntityManager entityManager you need to have the persistence unit defined somewhere, try to see how to configure your persistence.xml. To do this, you must define a bean in your applicationContext of the following class org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager, another of the following class org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean with the previous one as property and another of the next class org.springframework.orm.jpa.JpaTransactionManager with the previous one as property Commented Jun 19, 2020 at 14:26

1 Answer 1

1

Thanks to the advice of JLazar0 I found the way to fix my problem. As always, the problem was not because of wrong logic, misconfiguration or persistance. The reason why I kept getting "No query defined for that name", even though everything seemed to be fine, is because I had wrong name of package in LocalContainerEntityManagerFactoryBean.setPackagesToScan(). After small correction in the method argument my code passed all of the tests. Anyway, thanks for everyone who tried to help

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.