不断收到“java.lang.IllegalArgumentException:没有为该名称定义查询”,即使我有具有适当名称的@NamedQuery

Posted

技术标签:

【中文标题】不断收到“java.lang.IllegalArgumentException:没有为该名称定义查询”,即使我有具有适当名称的@NamedQuery【英文标题】:Keep getting "java.lang.IllegalArgumentException: No query defined for that name" even though I have @NamedQuery with an appropriate name 【发布时间】:2020-06-15 14:58:53 【问题描述】:

我有 Hibernate JPA 应用程序。我在 DAO 类的函数中不断收到“java.lang.IllegalArgumentException: No query defined for that name [Singer.findAll]”,即使我在 @NamedQuery 中正确定义了名称。这是我的实体类

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;
    

和DAO类

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...


我建议它可能与类映射有关,因为常规的 createQuery(String, Class) 也不起作用。

【问题讨论】:

先验一切似乎都是正确的,您能否通过在命名查询定义的名称和 createNamedQuery 方法中都放置一个字符串“test”来执行测试? 如果我理解正确的话,你在谈论类似@NamedQuery(name = "test", query = "select s from Singer s")return entityManager.createNamedQuery("test", Singer.class).getResultList(); 在这种情况下结果是相同的(java.lang.IllegalArgumentException: No query defined for that name [测试]) 在您的 persistence.xml 中,您将 transaction-type="RESOURCE_LOCAL" 设置为您的持久性单元?你把这个属性 来自动检测? 我正在根据 Pro Spring 5: An In-Depth Guide to the Spring Framework and Its Tools (5th edition) 中的示例编写代码。里面没有persistance.xml 当您使用@PersistenceContext private EntityManager entityManager 时,您需要在某处定义持久性单元,尝试查看如何配置您的 persistence.xml。为此,您必须在以下类 org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager 的 applicationContext 中定义一个 bean,以下类 org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean 的另一个,前一个作为属性,另一个下一个类 org.springframework.orm.jpa.JpaTransactionManager 与前一个作为属性 【参考方案1】:

感谢 JLazar0 的建议,我找到了解决问题的方法。与往常一样,问题不是因为错误的逻辑、错误配置或持久性。尽管一切似乎都很好,但我一直收到“没有为该名称定义查询”的原因是因为我在 LocalContainerEntityManagerFactoryBean.setPackagesToScan() 中的包名称错误。在方法参数的小修正后,我的代码通过了所有测试。 无论如何,感谢所有试图提供帮助的人

【讨论】:

以上是关于不断收到“java.lang.IllegalArgumentException:没有为该名称定义查询”,即使我有具有适当名称的@NamedQuery的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot 的 YML 文件中创建条件属性?

为啥我不断收到 OverwriteModelError?

我在 Python 中不断收到“21 行错误”[关闭]

为啥我不断收到此空指针未知来源错误?

我不断从 npm 收到 `errno 4058`

我不断收到语法错误c#