英文:
Hibernate org.hibernate.QueryException: not an entity
问题
我正在使用Spring,在JPQL方面还是新手。关于查询(在CustomerOrder类中)我到底做错了什么?尝试了几种方法,但总是得到下面的异常。当我尝试使用@NamedNativeQuery并通过REST端点查询时,会出现语法异常。
第二件事是,我正在使用spring.jpa.hibernate.ddl-auto,这可能是问题所在吗?表应该手动创建吗?
这是第一个类。它是@OneToMany关系:
@Entity
@Table(name = "customer")
public class Customer implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "customer_id")
private Long customerId;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "telephone")
private Long telephone;
@Column(name = "email")
private String email;
@Embedded
private Address address;
@OneToMany(mappedBy = "customer")
@JsonManagedReference
private List<CustomerOrder> orderList = new ArrayList<>();
// 构造函数和其他方法
}
这是关系的第二部分:
@Entity
@Table(name = "customer_order")
@NamedQuery(query =
"SELECT c.customerId, " +
"c.firstName, " +
"c.lastName," +
" c.telephone, " +
"c.email, " +
"c.address.country," +
" c.address.houseNumber, " +
"c.address.apartmentNumber, " +
"c.address.postalCode," +
" c.address.postalCode, " +
"o.orderId, " +
"o.totalPrice, " +
" o.totalQuantity, " +
"o.cartItems " +
"FROM CustomerOrder o JOIN o.customer c", name = "Order.query")
public class CustomerOrder implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "order_id")
private Long orderId;
@ElementCollection
@CollectionTable(name = "cart_items", joinColumns = @JoinColumn(name = "order_id"))
private List<CartItem> cartItems;
@Column(name = "total_price")
private BigDecimal totalPrice;
@Column(name = "total_quantity")
private Integer totalQuantity;
@ManyToOne(cascade = CascadeType.ALL)
@JsonBackReference
@JoinColumn(name = "customer_id")
private Customer customer;
// 构造函数和其他方法
}
仓库:
@Repository
public interface CustomerOrderRepository extends CrudRepository<CustomerOrder, Long> {
@Query(name = "Order.query")
List<FullOrder> findALlOrders();
}
所有数据应映射到的类:
public class FullOrder {
private Long customerId;
private String firstName;
private String lastName;
private Long telephone;
private String email;
private String country;
private Integer houseNumber;
private Integer apartmentNumber;
private String postalCode;
private String city;
private Long orderId;
private BigDecimal totalPrice;
private Integer totalQuantity;
private List<CartItem> cartItems;
// 构造函数、getter和setter等
}
异常:
org.springframework.beans.factory.BeanCreationException: 在lucene.shopbackend.repository.RoleRepository中定义的名称为'roleRepository'的bean创建错误,在JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration上声明的@EnableJpaRepositories中定义; 在设置bean属性'mappingContext'时无法解析对bean'jpaMappingContext'的引用; 嵌套异常是org.springframework.beans.factory.BeanCreationException: 在名称为'jpaMappingContext'的bean中创建错误; 嵌套异常是javax.persistence.PersistenceException: [PersistenceUnit: default] 无法构建Hibernate SessionFactory; 嵌套异常是org.hibernate.HibernateException: 命名查询中的错误:
Order.query失败,原因是: org.hibernate.QueryException: not an entity [SELECT c.customerId, c.firstName, c.lastName, c.telephone, c.email, c.address.country, c.address.houseNumber, c.address.apartmentNumber, c.address.postalCode, c.address.postalCode, o.orderId, o.totalPrice, o.totalQuantity, o.cartItems FROM luke.shopbackend.model.entity.CustomerOrder o JOIN o.customer c]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:342) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
// 更多异常信息...
(这只是异常的一部分,因为限制了字符数。)
英文:
I'm doing this in Spring, new to JPQL. What exactly I'm doing wrong with the query (It's in CustomerOrder class)? Tried to do it in a couple of ways but I always get that exception down there. When I try @NamedNativeQuery and query in through a REST endpoint I get a grammar exception.
The second thing is that I'm using spring.jpa.hibernate.ddl-auto, can this be the case and the tables should be created manually?
This is the first class. It's @OneToMany relationship
@Entity
@Table(name = "customer")
public class Customer implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "customer_id")
private Long customerId;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "telephone")
private Long telephone;
@Column(name = "email")
private String email;
@Embedded
private Address address;
@OneToMany(mappedBy = "customer")
@JsonManagedReference
private List<CustomerOrder> orderList = new ArrayList<>();
public Customer() {
}
public Customer(String firstName, String lastName, Long telephone, String email, Address address) {
this.firstName = firstName;
this.lastName = lastName;
this.telephone = telephone;
this.email = email;
this.address = new Address(address);
}
This is the second part of the relationship
@Entity
@Table(name = "customer_order")
@NamedQuery(query =
"SELECT c.customerId, " +
"c.firstName, " +
"c.lastName," +
" c.telephone, " +
"c.email, " +
"c.address.country," +
" c.address.houseNumber, " +
"c.address.apartmentNumber, " +
"c.address.postalCode," +
" c.address.postalCode, " +
"o.orderId, " +
"o.totalPrice, " +
" o.totalQuantity, " +
"o.cartItems " +
"FROM CustomerOrder o JOIN o.customer c", name = "Order.query")
public class CustomerOrder implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "order_id")
private Long orderId;
@ElementCollection
@CollectionTable(name = "cart_items", joinColumns = @JoinColumn(name = "order_id"))
private List<CartItem> cartItems;
@Column(name = "total_price")
private BigDecimal totalPrice;
@Column(name = "total_quantity")
private Integer totalQuantity;
@ManyToOne(cascade = CascadeType.ALL)
@JsonBackReference
@JoinColumn(name = "customer_id")
private Customer customer;
public CustomerOrder() {
}
public CustomerOrder(List<CartItem> items , CustomerOrderRequest request) {
this.cartItems = new LinkedList<>(items);
this.totalPrice = request.getTotalPrice();
this.totalQuantity = request.getTotalQuantity();
}
Repository:
import java.util.List;
@Repository
public interface CustomerOrderRepository extends CrudRepository<CustomerOrder, Long> {
@Query(name = "Order.query")
List<FullOrder> findALlOrders();
}
And this is the class all the data should be mapped to.
public class FullOrder {
private Long customerId;
private String firstName;
private String lastName;
private Long telephone;
private String email;
private String country;
private Integer houseNumber;
private Integer apartmentNumber;
private String postalCode;
private String city;
private Long orderId;
private BigDecimal totalPrice;
private Integer totalQuantity;
private List<CartItem> cartItems;
const. getters setters etc.
The Exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'roleRepository' defined in luke.shopbackend.repository.RoleRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Cannot resolve reference to bean 'jpaMappingContext' while setting bean property 'mappingContext'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.HibernateException: Errors in named queries:
Order.query failed because of: org.hibernate.QueryException: not an entity [SELECT c.customerId, c.firstName, c.lastName, c.telephone, c.email, c.address.country, c.address.houseNumber, c.address.apartmentNumber, c.address.postalCode, c.address.postalCode, o.orderId, o.totalPrice, o.totalQuantity, o.cartItems FROM luke.shopbackend.model.entity.CustomerOrder o JOIN o.customer c]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:342) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1699) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1444) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:621) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:609) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:51) ~[spring-data-commons-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:36) ~[spring-data-commons-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:898) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:554) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) ~[spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) ~[spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) ~[spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at luke.shopbackend.ShopBackendApplication.main(ShopBackendApplication.java:11) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.3.1.RELEASE.jar:2.3.1.RELEASE]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.HibernateException: Errors in named queries:
Order.query failed because of: org.hibernate.QueryException: not an entity [SELECT c.customerId, c.firstName, c.lastName, c.telephone, c.email, c.address.country, c.address.houseNumber, c.address.apartmentNumber, c.address.postalCode, c.address.postalCode, o.orderId, o.totalPrice, o.totalQuantity, o.cartItems FROM luke.shopbackend.model.entity.CustomerOrder o JOIN o.customer c]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
... 33 common frames omitted
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.HibernateException: Errors in named queries:
Order.query failed because of: org.hibernate.QueryException: not an entity [SELECT c.customerId, c.firstName, c.lastName, c.telephone, c.email, c.address.country, c.address.houseNumber, c.address.apartmentNumber, c.address.postalCode, c.address.postalCode, o.orderId, o.totalPrice, o.totalQuantity, o.cartItems FROM luke.shopbackend.model.entity.CustomerOrder o JOIN o.customer c]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:403) ~[spring-orm-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na]
Caused by: org.hibernate.HibernateException: Errors in named queries:
Order.query failed because of: org.hibernate.QueryException: not an entity [SELECT c.customerId, c.firstName, c.lastName, c.telephone, c.email, c.address.country, c.address.houseNumber, c.address.apartmentNumber, c.address.postalCode, c.address.postalCode, o.orderId, o.totalPrice, o.totalQuantity, o.cartItems FROM luke.shopbackend.model.entity.CustomerOrder o JOIN o.customer c]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:341) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:469) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:391) ~[spring-orm-5.2.7.RELEASE.jar:5.2.7.RELEASE]
... 4 common frames omitted
答案1
得分: 0
如果您想将自定义选择结果绑定到非实体对象,那么您需要执行类似以下的操作:
@Getter
@AllArgsConstructor
class FullOrder {
private Long orderId;
private BigDecimal totalPrice;
}
@Repository
public interface CustomerOrderRepository extends CrudRepository<CustomerOrder, Long> {
@Query(query = "select new full.path.to.class.FullOrder(c.orderId, c.totalPrice) from CustomeOrder c")
List<FullOrder> findALlOrders();
}
Spring Data会调用FullOrder
的构造函数,因此属性顺序和属性类型是要考虑的。
英文:
it you want to bind you custom select result to your non entity object then you have to do something like this
@Getter
@AllArgsConstructor
class FullOrder {
private Long orderId;
private BigDecimal totalPrice;
}
@Repository
public interface CustomerOrderRepository extends CrudRepository<CustomerOrder, Long> {
@Query(query = "select new full.path.to.class.FullOrder(c.orderId, c.totalPrice) from CustomeOrder c")
List<FullOrder> findALlOrders();
}
Spring Data will invoke constuctor of FullOrder
so property order & property type if matter
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论