在选择期间Hibernate重复行

时间:2017-12-15 21:25:44

标签: java hibernate jpa spring-boot orm

几个月前,我开始使用Hibernate 5进行冒险。我正在创建一个需要从数据库视图中获取数据的Spring Boot应用程序。 我创建了一个JPA实体,并编写了负责运行查询并将结果映射到ORM实体的代码。问题是Hibernate在跟踪中生成正确的查询,但返回第一行的副本作为列表。 Hibernate创建的查询如下所示:

select
    revenuesum0_.revenueId as revenueI1_9_,
    revenuesum0_.amount as amount2_9_,
    revenuesum0_.calculatedDate as calculat3_9_,
    revenuesum0_.revenueCalculatedDateId as revenueC4_9_,
    revenuesum0_.categoryName as category5_9_,
    revenuesum0_.timeSpan as timeSpan6_9_,
    revenuesum0_.title as title7_9_,
    revenuesum0_.userId as userId8_9_ 
from
    RevenueSummaryView revenuesum0_ 
where
    revenuesum0_.userId=?;

当我在DBeaver上运行它并在MySQL控制台中运行时,结果集是正确的。当我尝试使用Java JPA Query执行数据时出现问题。负责bug的代码在这里:

    package org.pbt.dao;

    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.pbt.HibernateUtil;
    import org.pbt.model.entity.ExpenseSummaryView;
    import org.pbt.model.filter.Filter;
    import org.springframework.stereotype.Repository;

    import javax.persistence.Query;
    import java.util.List;


    @Repository
    public class ExpenseSummaryViewDAOImpl implements ExpenseSummaryViewDAO {
        private SessionFactory sessionFactory = HibernateUtil.getSessionFactory();


        @Override
        public List<ExpenseSummaryView> getFiltered(Filter filter) {
            Session session = this.sessionFactory.openSession();
            String hql = "FROM ExpenseSummaryView WHERE userId = :userId ";

            if (filter.getStartDate() != null && filter.getEndDate() != null) {
                hql += "AND calculatedDate BETWEEN :startDate AND :endDate ";
            } else if (filter.getStartDate() != null) {
                hql += "AND calculatedDate >= :startDate ";
            } else if (filter.getEndDate() != null) {
                hql += "AND calculatedDate <= :endDate ";
            }

            Query query = session.createQuery(hql);
            query.setParameter("userId", filter.getUserId());

            if (filter.getStartDate() != null && filter.getEndDate() != null) {
                query.setParameter("startDate", filter.getStartDate());
                query.setParameter("endDate", filter.getEndDate());
            } else if (filter.getStartDate() != null) {
                query.setParameter("startDate", filter.getStartDate());
            } else if (filter.getEndDate() != null) {
                query.setParameter("endDate", filter.getEndDate());
            }

            List<ExpenseSummaryView> expenseSummaryViews = (List<ExpenseSummaryView>) query.getResultList();
            session.close();

            return expenseSummaryViews;
        }
    }

在调试整个expenseSummaryViews列表元素具有相同的对象引用。 JPA实体看起来像:

package org.pbt.model.entity;

import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.time.LocalDate;


@Entity
@Table(name = "ExpenseSummaryView")
public class ExpenseSummaryView {
    @Id
    @Column(name = "expenseId")
    private int id;

    @Column(name = "expenseCalculatedDateId", nullable = false)
    private int calculatedDateId;

    @Column(name = "userId", nullable = false)
    private int userId;

    @Column(name = "title", nullable = false)
    private String title;

    @Column(name = "amount", nullable = false)
    private double amount;

    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
    @Column(name = "calculatedDate", nullable = false)
    private LocalDate calculatedDate;

    @Column(name = "categoryName", nullable = false)
    private String categoryName;

    @Column(name = "timeSpan", nullable = false)
    private String timeSpan;


    public int getId() {
        return id;
    }

    public int getCalculatedDateId() {
        return calculatedDateId;
    }

    public int getUserId() {
        return userId;
    }

    public String getTitle() {
        return title;
    }

    public double getAmount() {
        return amount;
    }

    public LocalDate getCalculatedDate() {
        return calculatedDate;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public String getTimeSpan() {
        return timeSpan;
    }

    @Override
    public String toString() {
        return "{id:" + id + ", calculatedDateId:" + calculatedDateId + ", userId:" + userId + ", title:" + title + ", amount:" + amount + ", calculatedDate:" + calculatedDate.toString() + ", categoryName:" + categoryName + "}";
    }
}

值得一提的是,在非常相似的情况下,我使用hibernate从同一个应用程序中的同一个数据库中的另一个视图中获取行并且它正常工作,但在上面的情况下它没有。

有没有人可以提供帮助?

1 个答案:

答案 0 :(得分:1)

问题是因为数据库中没有可用的真实ID,费用ID字段在DB中不是真实ID,更改后,源代码启动正常。