JPA getSingleResult - EntityNotfound Exception

嗨,我试图通过JPA getSingleResult获取一个java实体,但它抛出一个我在API specs找不到的异常

方法:

public static Object getSingleResultOrNull(Query q){
        try{
            return q.getSingleResult();
        }catch(NoResultException| EntityNotFoundException enfex){
            System.out.println(enfex.getMessage());
            enfex.printStackTrace();
            return null;
        }catch(NonUniqueResultException ex){
            ex.printStackTrace();
            throw ex;
        }
    }

来电代码:

tagName = tagName.trim().toLowerCase();
Tags tag = (Tags) getSingleResultOrNull(namedQuery("Tags.findByName")
                                        .setParameter("name", tagName));

标签类:

@Entity @Table(name = "tags") @XmlRootElement @NamedQueries({
    @NamedQuery(name = "Tags.findByName", query = "SELECT t FROM Tags t WHERE t.name = :name")}) 
public class Tags implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "name")
    private String name;

Edit : 添加ProductTags . 类

public class ProductTags implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @JsonIgnore
    @Column(name = "created")
    @Temporal(TemporalType.TIMESTAMP)
    private Date created;
    @JsonIgnore
    @Column(name = "last_updated")
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastUpdated;
    @JsonIgnore
    @Column(name = "last_updated_by")
    private String lastUpdatedBy;
    @JsonIgnore
    @JoinColumn(name = "prod_id", referencedColumnName = "id")
    @ManyToOne(optional = false)
    private Product prod;
    @JoinColumn(name = "tag_id", referencedColumnName = "id")
    @ManyToOne(optional = false)
    private Tags tag;

根据getSingleResult的API规范,只应抛出以下异常:

  • NoResultException - 如果没有结果

  • NonUniqueResultException - 如果有多个结果

  • IllegalStateException - 如果调用Java持久性查询语言UPDATE或DELETE语句

  • QueryTimeoutException - 如果查询执行超过设置的查询超时值,则仅回滚该语句

  • TransactionRequiredException - 如果已设置锁定模式且没有交易

  • PessimisticLockException - 如果悲观锁定失败并且回滚事务

  • LockTimeoutException - 如果悲观锁定失败并且仅回滚该语句

  • PersistenceException - 如果查询执行超过查询超时值集并且回滚事务

但是,我得到了javax.persistence.EntityNotFoundException的一个奇怪的异常:传递给persist的已删除实体:[models.ProductTags#]

对于一个完全(不完全是因为ProductTags有一个Tags对象的外键,但在保存Tags对象的上下文中,我没有看到任何关系 . )无关的实体 .

传递给持久化的已删除实体:[models.ProductTags#] javax.persistence.EntityNotFoundException:在org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1369)org中传递给persist:[models.ProductTags#]的已删除实体.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1315)位于controllers.ProductController的controllers.PowerController.getSingleResultOrNull(PowerController.java:68)的org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:307) . 在router.Routes $$ anonfun $ routes $ 1 $$ anonfun $ applyOrElse $ 4 $$ anonfun $ apply $ 4.apply(Routes.scala:1584)at router.Routes $$ anonfun $ routes $ 1 $ updateProductInfo(ProductController.java:282)在play.core.routing.HandlerInvokerFactory $:在play.core.routing.HandlerInvokerFactory $$匿名$ 4.resultCall(136 HandlerInvoker.scala):$ $ anonfun $ applyOrElse 4 $$ anonfun $ $申请4.适用(1584 Routes.scala) JavaActionInvokerFactory $$ anon $ 14 $$ anon $ 3 $$ anon $ 1.invocation(HandlerInvoker.scala:127)at play.core.j.Ja vaAction $$ anon $ 1.call(JavaAction.scala:70)at play.http.DefaultHttpRequestHandler $ 1.call(DefaultHttpRequestHandler.java:20)at interceptors.ProductAction.call(ProductAction.java:65)at play.db.jpa . TransactionalAction.lambda $在play.db.jpa.TransactionAction $$ Lambda $ 43 / 469822182.apply(未知来源)在play.db.jpa.DefaultJPAApi.withTransaction调用$ 5(TransactionalAction.java:19)(DefaultJPAApi.java:136) at play.db.jpa.JPA.withTransaction(JPA.java:159)at play.db.jpa.TransactionalAction.call(TransactionalAction.java:16)at play.core.j.JavaAction $$ anonfun $ 7.apply(JavaAction) .scala:94)at play.core.j.JavaAction $$ anonfun $ 7.apply(JavaAction.scala:94)at scala.concurrent.impl.Future $ PromiseCompletingRunnable.liftedTree1 $ 1(Future.scala:24)at scala.concurrent .impl.Future $ PromiseCompletingRunnable.run(Future.scala:24)at play.core.j.HttpExecutionContext $$ anon $ 2.run(HttpExecutionContext.scala:40)at play.api.libs.iteratee.Execution $ trampoline $ . 在play.core.j.HttpExecu执行(Execution.scala:70) stepContext.execute(HttpExecutionContext.scala:32)at scala.concurrent.impl.Future $ .apply(Future.scala:31)at scala.concurrent.Future $ .apply(Future.scala:485)at play.core.j .JavaAction.apply(JavaAction.scala:94)at play.api.mvc.Action $$ anonfun $ apply $ 1 $$ anonfun $ apply $ 4 $$ anonfun $ apply $ 5.apply(Action.scala:105)at play.api .mvc.Action $$ anonfun $ apply $ 1 $$ anonfun $ apply $ 5.apply(Action.scala:105)at play.utils.Threads $ .withContextClassLoader(Threads.scala:21)at play . api.mvc.Action $$ anonfun $ apply $ 1 $$ anonfun $ apply $ 4.apply(Action.scala:104)at play.api.mvc.Action $$ anonfun $ apply $ 1 $$ anonfun $ apply $ 4.apply(Action .scala:103)scala.Option.map(Option.scala:145)at play.api.mvc.Action $$ anonfun $ apply $ 1.apply(Action.scala:103)at play.api.mvc.Action $ $ anonfun $ apply $ 1.apply(Action.scala:96)at play.api.libs.iteratee.Iteratee $$ anonfun $ mapM $ 1.apply(Iteratee.scala:524)at play.api.libs.iteratee.Iteratee $ $ anonfun $ mapM $ 1.apply(Iteratee.scala:524)at play.api.libs.iteratee.Iteratee $$ anonfun $ fla tMapM $ 1.apply(Iteratee.scala:560)at play.api.libs.iteratee.Iteratee $$ anonfun $ flatMapM $ 1.apply(Iteratee.scala:560)at atplay.api.libs.iteratee.Iteratee $$ anonfun $ flatMap $ 1 $$ anonfun $ apply $ 14.apply(Iteratee.scala:537)at play.api.libs.iteratee.Iteratee $$ anonfun $ flatMap $ 1 $$ anonfun $在scala.concurrent.impl.Future $ PromiseCompletingRunnable.liftedTree1 $ 1(Future.scala:24)scala.concurrent.impl.Future $ PromiseCompletingRunnable.run(Future.scala:24)申请$ 14.apply(Iteratee.scala:537) at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40)at akka.dispatch.ForkJoinExecutorConfigurator $ AkkaForkJoinTask.exec(AbstractDispatcher.scala:397)at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)at at scala.concurrent.forkjoin.ForkJoinPool $ WorkQueue.runTask(ForkJoinPool.java:1339)scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java: 107)

我知道另一种编写getSingleResultOrNull方法的方法,但在这种情况下我无法找到问题 .

对此有任何帮助表示赞赏 .

回答(2)

2 years ago

我相信你的问题是在以前的某个步骤引起的 . 查看堆栈跟踪,在调用您显示的方法之前就有这一行:

controllers.ProductController.updateProductInfo(ProductController.java:282)

也许你正在更新 updateProductInfo 中的某个对象的状态,而且当你调用 getSingleResultOrNull 方法时,Hibernate正在刷新会话 .

这里有一些类似的情况你也可以看看:Deleted entity passed to persist exception

2 years ago

这是当我查询存在但不在数据库中的实体时发生的情况:

javax.servlet.ServletException: javax.ejb.EJBException: javax.persistence.NoResultException: No entity found for query