【问题标题】:Spring, Spring Data JPA: org.hibernate.hql.internal.ast.QuerySyntaxException: Test is not mappedSpring,Spring Data JPA:org.hibernate.hql.internal.ast.QuerySyntaxException:测试未映射
【发布时间】:2016-03-13 02:14:28
【问题描述】:

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

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;
   }

}

UPDATE:测试实体。基本实体具有@Id Long id 并且是@MappedSuperClass

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

   public Test() {
   }

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

【问题讨论】:

  • Test 类是否用@Entity 注释?
  • 是的,它是用@Entity注解的。
  • 你把Test实体放在哪个包里
  • 包是:com.company.test。但是我发现当我有packagesToScancom.company.**.* 时,它会搜索com.company. 下的所有包
  • 另外,将Test类的代码提供给我们。

标签: spring hibernate spring-data spring-data-jpa


【解决方案1】:

如果表的名称在数据库中是测试,则使用如下所示

@Entity
@Table(name="test")

【讨论】:

    【解决方案2】:
    @Entity(name = "test")
    public class Test extends BaseEntity { ... }
    

    在您的实体中,您指定一个覆盖默认命名的name 属性(使用类的名称)。因此您的查询是错误的,您的查询需要一个名为 Test 的实体,但该实体不可用。

    您有两种可能的解决方案

    1. 删除name 属性并保持查询不变。
    2. 将查询更改为select t from test t(注意t 而不是T)。

    随后您的返回类型也是错误的,因为它将返回元素集合而不是单个元素。所以把它改成List&lt;Test&gt;

    【讨论】:

    • 去他妈的。你说的对。我认为name 定义了数据库中的表名。我忘记了 @Table 注释是这样做的。 4 年 JPA 经验 ;) 接受。
    【解决方案3】:

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

    【讨论】:

    • 非常感谢,在我的例子中,有一个重构将实体类移动到更具体的包中,setPackagesToScan 也被更改为查看这个包。虽然项目的某些部分没有移动到新包中,但结果我收到了关于未知实体类型的错误。
    【解决方案4】:

    使用List获取所有对象

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

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

    【讨论】:

    • 请问你说什么?
    • 我将存储库中的方法更改为List&lt;Test&gt; getOr();,但它不起作用 - 我仍然遇到同样的错误。
    • 设置properties.setProperty("hibernate.show_sql", "true"); 然后看看查询出了什么问题。
    猜你喜欢
    • 1970-01-01
    • 2021-12-12
    • 1970-01-01
    • 2017-03-22
    • 2017-05-18
    • 2016-12-18
    • 1970-01-01
    • 2018-05-06
    • 1970-01-01
    相关资源
    最近更新 更多