java Hibernate JPQL 抛出无法键入更新/删除查询
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30019731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate JPQL throws Update/delete queries cannot be typed
提问by Jan Vladimir Mostert
I'm trying to delete an entity using HQL and it's failing.
我正在尝试使用 HQL 删除一个实体,但它失败了。
TypedQuery<Seller> query = Seller.entityManager().createQuery(
"DELETE FROM Seller AS o WHERE o.company=:company AND o.id=:id", Seller.class);
query.setParameter("company", company);
query.setParameter("id", id);
int result = query.executeUpdate();
The stacktrace I'm getting:
我得到的堆栈跟踪:
Update/delete queries cannot be typed; nested exception is java.lang.IllegalArgumentException: Update/delete queries cannot be typed
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:296)
at org.springframework.orm.jpa.aspectj.JpaExceptionTranslatorAspect.ajc$afterThrowing$org_springframework_orm_jpa_aspectj_JpaExceptionTranslatorAspecta1ac9(JpaExceptionTranslatorAspect.aj:33)
at com.ahp.core.model.Seller.deleteSeller_aroundBody4(Seller.java:111)
at com.ahp.core.model.Seller.deleteSeller(Seller.java:1)
at com.ahp.core.processor.SellerProcessor.delete(SellerProcessor.java:175)
at com.ahp.core.processor.SellerProcessor.consume(SellerProcessor.java:80)
at com.ahp.core.processor.SellerProcessor.consume(SellerProcessor.java:1)
at com.ahp.messaging.processor.AbstractRPCConsumer.onMessage(AbstractRPCConsumer.java:32)
at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:228)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:756)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:679)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access@RooJavaBean
@RooToString
@RooJpaActiveRecord
public class Seller {
...
1(SimpleMessageListenerContainer.java:82)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:167)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1241)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:660)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1005)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:989)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access0(SimpleMessageListenerContainer.java:82)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1103)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.IllegalArgumentException: Update/delete queries cannot be typed
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.resultClassChecking(AbstractEntityManagerImpl.java:363)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:344)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:366)
at com.sun.proxy.$Proxy57.createQuery(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:241)
at com.sun.proxy.$Proxy56.createQuery(Unknown Source)
... 18 more
Seller.java was generated by Spring Roo:
Seller.java 由 Spring Roo 生成:
privileged aspect Seller_Roo_Jpa_Entity {
declare @type: Seller: @Entity;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long Seller.id;
...
Seller_Roo_Jpa_Entity.aj:
Seller_Roo_Jpa_Entity.aj:
privileged aspect Seller_Roo_Jpa_ActiveRecord {
@PersistenceContext
transient EntityManager Seller.entityManager;
...
Seller_Roo_Jpa_ActiveRecord.aj:
Seller_Roo_Jpa_ActiveRecord.aj:
import javax.transaction.Transactional;
...
@Transactional
public static Boolean deleteSeller(Company company, Long id){
Query query = Seller.entityManager().createQuery(
"DELETE FROM Seller AS o WHERE o.company=:company AND o.id=:id");
query.setParameter("company", company);
query.setParameter("id", id);
int result = query.executeUpdate();
return result > 0;
}
I've tried changing the delete method to look like this so that I don't use TypedQuery at all:
我尝试将删除方法更改为如下所示,以便我根本不使用 TypedQuery:
org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:316)
at org.springframework.orm.jpa.aspectj.JpaExceptionTranslatorAspect.ajc$afterThrowing$org_springframework_orm_jpa_aspectj_JpaExceptionTranslatorAspecta1ac9(JpaExceptionTranslatorAspect.aj:33)
...
Caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:311)
at com.sun.proxy.$Proxy58.executeUpdate(Unknown Source)
... 18 more
... but this is giving me another exception:
...但这给了我另一个例外:
Query query = Seller.entityManager().createQuery(
"DELETE FROM Seller AS o WHERE o.company=:company AND o.id=:id");
query.setParameter("company", company);
query.setParameter("id", id);
int result = query.executeUpdate();
My method is annotated with @Transactional
, so I don't see how it is not inside a transaction.
我的方法是用 注释的@Transactional
,所以我看不出它是如何不在事务中的。
This questionand this questionseems to be using HQL to do a delete query, so it must be possible, what am I missing here?
回答by Vlad Mihalcea
Change your DELETE query to:
将您的 DELETE 查询更改为:
##代码##The DML JPQL queries are not typed, because they only return the affected rows and so they don't need a return type.
DML JPQL 查询没有类型化,因为它们只返回受影响的行,因此不需要返回类型。