Java 在QueryDSL中使用相同的q对象时,对象已被使用

Java 在QueryDSL中使用相同的q对象时,对象已被使用,java,hibernate,querydsl,Java,Hibernate,Querydsl,大家好,我有一个带有QUeryDSL 3.6.0的Hibernate项目,当我的服务类中只有findAll()方法时,一切都正常。但当我添加findByID时,会出现一个错误 public class ArticleServiceImpl extends ArticleService { QArticle article = QArticle.article; @Override public List<Article> f

大家好,我有一个带有QUeryDSL 3.6.0的Hibernate项目,当我的服务类中只有findAll()方法时,一切都正常。但当我添加findByID时,会出现一个错误

    public class ArticleServiceImpl extends ArticleService {

        QArticle article = QArticle.article;

        @Override
        public List<Article> findAll() {
            return query.from(article).fetchAll().list(article);
        }

        public Article findById(@Nonnull final long id) {
            return query.from(article).where(article.id.eq(id)).uniqueResult(article);
        }
    }
会发生什么?我发现查询是不安全的。但是如何在这两种不同的方法中使用Q类呢

编辑:


它是来自ArticleService的受保护变量。

每当对
from()
子句中相同的
QEntity
进行可重复调用时,就会引发此异常,该子句用于
JPAQuery()
的相同实例

这里有一个例子(免责声明:这将是一个非常非常愚蠢的例子,只是为了说明问题)

假设我们有一个名为
MyEntity
的实体,我们试图从数据库中获取两个
MyEntity
,第一个结果是给定的
id
,第二个结果是id+1

public List<MyEntity> findMyDumbEntities(long id) {    
      QMyEntity qMyEntity = QMyEntity.myEntity;
      JPAQuery jpaQuery = new JPAQuery(entityManager);
      MyEntity myFirstEntity = jpaQuery.from(qMyEntity).where(qMyEntity.id.eq(id)).uniqueResult(qMyEntity);
      MyEntity mySecondEntity = jpaQuery.from(qMyEntity).where(qMyEntity.id.eq(id+1)).uniqueResult(qMyEntity);

      return Arrays.asList(myFirstEntity, mySecondEntity);    
}
为什么??因为我们有一个
JPAQuery
实例,并且我们正在重复对同一实体的调用(我们有两个
jpqQuery.from(qMyEntity)
)。为了解决这个问题,我们只需要在每次查询某个内容时获取JPAQuery实例,因此我们需要将代码更改为

public List<MyEntity> findMyDumbEntities(long id) {        
          QMyEntity qMyEntity = QMyEntity.myEntity;
          MyEntity myFirstEntity = new JPAQuery(entityManager).from(qMyEntity).where(qMyEntity.id.eq(id)).uniqueResult(qMyEntity);
          MyEntity mySecondEntity = new JPAQuery(entityManager).from(qMyEntity).where(qMyEntity.id.eq(id+1)).uniqueResult(qMyEntity);

          return Arrays.asList(myFirstEntity, mySecondEntity);        
}
例如,每次新建JPAQuery时所得到的更改

protected JPQLQuery jpaQuery() {
    return new JPAQuery(entityManager);
}
然后在您的服务实现中

@Override
public List<Article> findAll() {
      return jpaQuery().from(article).fetchAll().list(article);
}

public Article findById(@Nonnull final long id) {
      return jpaQuery().from(article).where(article.id.eq(id)).uniqueResult(article);
}
@覆盖
公共列表findAll(){
从(article.fetchAll().list(article)返回jpaQuery().from;
}
公共文章findById(@Nonnull final long id){
返回jpaQuery().from(article).where(article.id.eq(id)).uniqueResult(article);
}

如何构造查询实例?@Timo我编辑了我的帖子。好吧,这可以解决我的问题,但我仍然不明白为什么不发生这种情况,例如在中,然后在您的示例中的服务实现中,我们有一个Q类型的对象-article,它在findAll()和findById(@Nonnull final long id)方法之间共享。那么为什么还没有使用文章呢?问题不在于生成的Q-type对象,而是我们将该QType对象与同一个JPAQuery实例一起使用了两次(我更新了我的答案以便更清楚)。实际上,您将始终拥有一个Q-type对象,并且将在任何地方重用它,但是对于同一个JPAQuery()实例,您不能多次重用它。希望有帮助。
public List<MyEntity> findMyDumbEntities(long id) {        
          QMyEntity qMyEntity = QMyEntity.myEntity;
          MyEntity myFirstEntity = new JPAQuery(entityManager).from(qMyEntity).where(qMyEntity.id.eq(id)).uniqueResult(qMyEntity);
          MyEntity mySecondEntity = new JPAQuery(entityManager).from(qMyEntity).where(qMyEntity.id.eq(id+1)).uniqueResult(qMyEntity);

          return Arrays.asList(myFirstEntity, mySecondEntity);        
}
protected JPQLQuery query = new JPAQuery(entityManager);
protected JPQLQuery jpaQuery() {
    return new JPAQuery(entityManager);
}
@Override
public List<Article> findAll() {
      return jpaQuery().from(article).fetchAll().list(article);
}

public Article findById(@Nonnull final long id) {
      return jpaQuery().from(article).where(article.id.eq(id)).uniqueResult(article);
}