Spring,Spring Data JPA:org.hibernate.hql.internal.ast.QuerySyntaxException:Test未映射

4

当我在Spring Data JPA Reposiotry中创建一个使用@Query注释的方法,并且Spring Data JPA对其进行验证时,出现了org.hibernate.hql.internal.ast.QuerySyntaxException: Test is not mapped

Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Test is not mapped [SELECT t from Test t]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1750)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:331)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.8.0_40]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [rt.jar:1.8.0_40]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.8.0_40]
    at java.lang.reflect.Method.invoke(Method.java:497) [rt.jar:1.8.0_40]
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:344)
    at com.sun.proxy.$Proxy125.createQuery(Unknown Source)
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:86)
    ... 47 more

代码库长这样:

public interface TestRepository extends JpaRepository<Test, Long>{

   Test findByDescriptionContaining(String text); //works

   @Query("SELECT t from Test t") //fails
   Test getOr();

}

有趣的是,我可以使用Spring Data JPA方法名称解析功能,并且这些查询有效。此外,当我向实体添加新字段并将hbm2ddl.auto设置为更新时,更改会持久保存到数据库。但是,使用@Query注释的查询无法正常工作。
我的持久化配置如下:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.company", entityManagerFactoryRef = "localContainerEntityManagerFactoryBean")
@ComponentScan("com.company")
public class PersistenceJPAConfig {

   private static final Logger LOGGER = LoggerFactory.getLogger(PersistenceJPAConfig.class);

   @Bean
   @DependsOn("dataSource")
   public JdbcTemplate jdbcTemplate() {
      return new JdbcTemplate(dataSource());
   }

   @Bean
   @DependsOn("dataSource")
   public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
      return new NamedParameterJdbcTemplate(dataSource());
   }

   @Bean
   public MailSender mailSender(){
      final MailSenderImpl mailSenderImpl = new MailSenderImpl();
      mailSenderImpl.setDataSource(dataSource());
      return mailSenderImpl;
   }

   @Bean
   public DataSource dataSource() {
      HikariConfig config = new HikariConfig();
      config.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
      config.setJdbcUrl("jdbc:sqlserver://localhost;DatabaseName=mydb");
      config.setUsername("user");
      config.setPassword("pass");
      config.setPoolName("HikariCpConnectionPool");
      config.setMaximumPoolSize(50);
      config.setMinimumIdle(2);
      return new HikariDataSource(config);
   }

   @Bean
   @DependsOn({"dataSource"})
   public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean() {
      LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
      em.setDataSource(dataSource());
      em.setPackagesToScan(new String[]{
         "com.company.**.*"
      });
      em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
      em.setJpaProperties(additionalProperties());
      return em;
   }

   @Bean
   public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
      return new PersistenceExceptionTranslationPostProcessor();
   }

   @Bean
   public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
      return new JpaTransactionManager(entityManagerFactory);
   }

   private Properties additionalProperties() {
      Properties properties = new Properties();
      properties.setProperty("hibernate.hbm2ddl.auto", "update");
      properties.setProperty("hibernate.dialect", "org.hibernate.dialect.SQLServer2012Dialect");
      properties.setProperty("hibernate.show_sql", "false");
      properties.setProperty("hibernate.format_sql", "false");
      properties.setProperty("hibernate.use_sql_comments", "false");
      properties.setProperty("hibernate.id.new_generator_mappings", "false");
      properties.setProperty("hibernate.enable_lazy_load_no_trans", "true");
      properties.setProperty("hibernate.generate_statistics", "false");
      return properties;
   }

}

更新:测试实体。基础实体具有@Id Long id并且是@MappedSuperClass

@Entity(name = "test")
public class Test extends BaseEntity{

   public Test() {
   }

   @Column(name = "description")
   private String description;

Test类是否使用了@Entity注解? - Buhake Sindi
是的,它带有@Entity注释。 - Robert Niestroj
你把 Test 实体放在哪个包里了? - Omkar Puttagunta
包名是:com.company.test。然而,我发现当我有packagesToScancom.company.**.*时,它将搜索com.company.下面的所有包。 - Robert Niestroj
我建议您遵循您的建议并扫描com.company内的所有类(例如,@ComponentScan("com.company.*"))。 - Buhake Sindi
显示剩余2条评论
4个回答

21
@Entity(name = "test")
public class Test extends BaseEntity { ... }

在实体中,您指定了一个name属性来覆盖默认命名(使用类的名称)。因此,您的查询是错误的,您的查询期望一个名为Test的实体,但该实体不可用。
你有两个可能的解决方案:
  1. 删除name属性并保留查询。
  2. 将查询更改为select t from test t(注意t而不是T)。
随后,您的返回类型也是错误的,它将返回一组元素而不是单个元素。因此,请将其更改为List<Test>

1
你说得对。我以为 name 定义了数据库中的表名。我忘记了 @Table 注解可以做到这一点。我有四年的 JPA 经验 ;) 接受。 - Robert Niestroj

1

在setPackagesToScan属性中删除*,并简单地使用- em.setPackagesToScan(new String[]{"com.company"});


非常感谢,我的情况是进行了重构,将实体类移动到更具体的包中,并且setPackagesToScan也被修改为查看该包。尽管项目的某些部分没有移动到新的包中,结果导致我收到有关未知实体类型的错误。 - mr.nothing

1

如果数据库中表的名称为test,则可以像下面这样使用:

@Entity
@Table(name="test")

0
使用 List 来获取所有对象。
@Query("SELECT t from Test t") //fails
List<Test> getOr();

因为SELECT t from Test t会从数据库中获取所有行。


请问您说什么? - Bhuwan Prasad Upadhyay
我已经将存储库中的方法更改为 List<Test> getOr();,但它仍然无法正常工作 - 我仍然收到相同的错误。 - Robert Niestroj
设置 properties.setProperty("hibernate.show_sql", "true"); 然后查看查询语句,找出出现问题的查询。 - Bhuwan Prasad Upadhyay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接