JPA查询针对不同的参数返回相同的结果 [英] JPA Query Returning Same Result for different Parameter

查看:178
本文介绍了JPA查询针对不同的参数返回相同的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个问题,我的查询方法在foreach循环中,并且每次我传递不同的参数以检索不同的信息时.但是,在循环的第一次迭代之后,查询数据将被缓存(我认为),并为后续循环返回相同的数据.

I'm running into an issue where my query method is in a foreach loop, and each time I'm passing in a different parameter to retrieve different information. However, after the FIRST iteration of the loop, the query data gets cached (I think) and returns the same data for subsequent loops.

这是我的代码:

@Transactional(readOnly = true)
public List<InitiativeReport> getInitiativeReports() throws Exception {
try {
    List<InitiativeReport> ir = new ArrayList<InitiativeReport>();
    List<Initiative> in = initiativeRepository.findAll();
    for(Initiative i : in) {
        i.getTheme().getId(); // lazy initialize

        InitiativeReport report = new InitiativeReport();
        report.setId(i.getId());
        report.setInitiativeId(i.getInitiativeId());
        report.setName(i.getName());
        report.setTheme(i.getTheme());

        // this is the call to the query, which is cached after the first iteration
        List<InitiativeProfileQuestion> q = initiativeProfileQuestionRepository.getQuestionsAndAnswerLogs(i.getInitiativeId());
        report.setQuestions(q);
        ir.add(report);
    }

    return ir;
}
catch (Exception e) {
    throw new Exception(e);
}

这是我的存储库界面:

public interface InitiativeProfileQuestionRepository extends JpaRepository<InitiativeProfileQuestion, Long> {
    @Query("select distinct q from InitiativeProfileQuestion q "
         + "left join fetch q.answers "
         + "left join fetch q.answerLogs al "
         + "where al.initiative.initiativeId = ?1 "
         + "and al.revision = al.initiative.revision 
         + "order by q.question asc")
    public List<InitiativeProfileQuestion> getQuestionsAndAnswerLogs(String initiativeId);
}

这是我的application.yml文件:

Here is my application.yml file:

spring:
    datasource:
        dataSourceClassName: com.mysql.jdbc.jdbc2.optional.MysqlDataSource
        url: jdbc:mysql://localhost/testdb
        username: root
        password: XXXXXXXXX
        driverClassName: com.mysql.jdbc.Driver
        testOnBorrow: true
        validationQuery: SELECT 1
    jpa:
        database-platform: org.hibernate.dialect.MySQLInnoDBDialect
        database: MYSQL
        openInView: false
        show_sql: true
        generate-ddl: false
        hibernate:
            ddl-auto: none
            naming-strategy: org.hibernate.cfg.EJB3NamingStrategy

问题与我在此处找到的帖子非常相似:

The issue is very similar to a post I found here: Native Query (JPA ) not reset and return the same old result

但是,该用户正在使用EntityManager,而我的应用程序中没有EntityManager的实现-我让JPA完成所有工作,并且只包含查询注释.

However, that user is using EntityManager and I have no implementation for EntityManager in my application- I'm letting JPA do all the work and only have query annotations.

任何帮助将不胜感激!

推荐答案

聚会晚了一点,但是对于那些现在发现这个问题的人,这是您需要解决的问题:

Little late to the party but for those finding this now here is what you need to do to solve the issue:

在已开始事务的循环中进行查询时,您需要分离从该循环中的查询返回的,具有相同ID但可能具有不同数据的实体.

When your querying in a loop that has already started a transaction you need to detach the entities returned from queries inside that loop that share the same id but may have different data.

这里有个例子:

@Service
public class ProductService {

    @Autowired
    private ProductRepository productRepository;

    @Autowired
    private ProductWarehouseRepository productWarehouseRepository;

    @Autowired
    private EntityManager entityManager;

    @Transactional
    public List<Product> getProducts(){
        List<Product> products = this.productRepository.findAll();
        products.forEach(product -> {
            List<ProductWarehouse> warehouses = this.productWarehouseRepository.findAllByProductId(product.getId());
            warehouses.forEach(warehouse -> {
                //THIS IS THE IMPORTANT PART
                //You have to detach the entity from the session
                this.entityManager.detach(warehouse);
            });
            product.setWarehouses(warehouses);
        });
        return products;
    }
}

在此示例中,产品A可以在仓库ID 1中,产品B可以在仓库ID中,但是它们在仓库中的可用数量可能不同.

In this example product A can be in warehouse id 1, and so can product B, but they may have different quantities available in the warehouse.

当返回的结果可能在@Id列上发生冲突时,必须从会话中分离实体.这与Hibernate中1级缓存的工作方式有关.您可以查看此链接以获取更多信息 http: //docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/objectstate.html

You have to detach the entities from the session when the results returned may have collisions on the @Id column. This has to do with the way level 1 caching works in Hibernate. You can check out this link for a little more info http://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/objectstate.html

这篇关于JPA查询针对不同的参数返回相同的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆