Spring、Spring 数据 JPA:org.hibernate.hql.internal.ast.QuerySyntaxException:未映射测试
Spring, Spring Data JPA: org.hibernate.hql.internal.ast.QuerySyntaxException: Test is not mapped
当我在 Spring Data JPA Reposiotry 中创建一个使用 @Query
annontation 和 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 数据 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;
使用List
获取所有对象
@Query("SELECT t from Test t") //fails
List<Test> getOr();
因为SELECT t from Test t
从数据库中获取所有行。
删除 setPackagesToScan 属性 中的 *
并简单地使用 - em.setPackagesToScan(new String[]{"com.company"});
@Entity(name = "test")
public class Test extends BaseEntity { ... }
在您的实体中,您指定一个 name
属性来覆盖默认命名(使用 class 的名称)。因此,您的查询是错误的,您的查询需要一个名为 Test
的实体,但该实体不可用。
您有 2 种可能的解决方案
- 删除
name
属性并保持查询不变。
- 将查询更改为
select t from test t
(注意 t
而不是 T
)。
随后您的 return 类型也是错误的,因为它将 return 元素的集合而不是单个元素。所以将其更改为 List<Test>
.
如果 table 的名称在数据库中为 test
,请按如下方式使用
@Entity
@Table(name="test")
当我在 Spring Data JPA Reposiotry 中创建一个使用 @Query
annontation 和 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 数据 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;
使用List
获取所有对象
@Query("SELECT t from Test t") //fails
List<Test> getOr();
因为SELECT t from Test t
从数据库中获取所有行。
删除 setPackagesToScan 属性 中的 *
并简单地使用 - em.setPackagesToScan(new String[]{"com.company"});
@Entity(name = "test")
public class Test extends BaseEntity { ... }
在您的实体中,您指定一个 name
属性来覆盖默认命名(使用 class 的名称)。因此,您的查询是错误的,您的查询需要一个名为 Test
的实体,但该实体不可用。
您有 2 种可能的解决方案
- 删除
name
属性并保持查询不变。 - 将查询更改为
select t from test t
(注意t
而不是T
)。
随后您的 return 类型也是错误的,因为它将 return 元素的集合而不是单个元素。所以将其更改为 List<Test>
.
如果 table 的名称在数据库中为 test
,请按如下方式使用@Entity
@Table(name="test")