简体   繁体   中英

JPA returning empty result list while DB returns row set

I am trying to run a query to fetch some statistic data from my database. And I'm using JPA . But I faced such a trouble: when I run JPQL query, the empty result set is returned. But when I run SQL , produced with JPA for that JPQL query, I got a single row of data.

Here's what I've got:

The Ticket entity

@Entity
@Table(name="tickets")
public class Ticket extends AbstractEntity {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;

    @Embedded
    private Owner owner;

    @ManyToOne
    @JoinColumn(name="flightId")
    private Flight flight;

    private String status;

    public Ticket() {
        this.status = "AVAILABLE";
    }

The Flight entity

@Entity
@Table(name="flights")
public class Flight extends AbstractEntity {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;

    private String departure;
    private String destination;
    private Date date;
    private float ticketCost;

    @OneToMany(mappedBy="flight", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
    private List<Ticket> tickets = new ArrayList<Ticket>();

The result row class

public class SoldReportRow {
    private String departure;
    private String destination;
    private DateTime date;
    private int ticketsSold;
    private float totalCost;

    public SoldReportRow(Date date, String departure, String destination, Long ticketsSold, Double totalCost) {
        this.departure = departure;
        this.destination = destination;
        this.ticketsSold = ticketsSold.intValue();
        this.totalCost = totalCost.floatValue();
        this.date = new DateTime(date);
    }

The JPQL

SELECT NEW entities.SoldReportRow(f.date, f.departure, f.destination, 
    COUNT(t.id), SUM(f.ticketCost)) 
FROM  Ticket t JOIN t.flight f  
WHERE t.status = 'SOLD' AND t.owner IS NOT NULL AND f.date BETWEEN ? and ? 
GROUP BY f.id

The generated SQL

SELECT t0.DATE, t0.DEPARTURE, t0.DESTINATION, COUNT(t1.ID), SUM(t0.TICKETCOST) 
FROM flights t0, tickets t1 
WHERE ((((t1.STATUS = ?) AND NOT ((((((t1.ADDRESS IS NULL) 
    AND (t1.EMAIL IS NULL)) AND (t1.NAME IS NULL)) AND (t1.OWNERFROM IS NULL)) 
    AND (t1.PHONE IS NULL)))) AND (t0.DATE BETWEEN ? AND ?)) 
    AND (t0.ID = t1.flightId)) GROUP BY t0.ID

So here is what I got when I run JPQL :

JPQL给出了空结果集合

And here is what I got when I run the generated SQL :

SQL只给出一行

UPD: the TicketDAO methods

// ...

protected static EntityManagerFactory factory;
protected static EntityManager em;

static {
    factory = Persistence.createEntityManagerFactory(UNIT_NAME);
}

// ...

public static List<SoldReportRow> soldReportByDate(String from, String to) {
    DateTimeFormatter dfTxt = DateTimeFormat.forPattern("dd/MM/yyyy");
    DateTimeFormatter dfSql = DateTimeFormat.forPattern("yyyy-MM-dd");

    String startDate = dfSql.print(dfTxt.parseDateTime(from));
    String endDate = dfSql.print(dfTxt.parseDateTime(to));

    String query = String.format(
            "SELECT NEW entities.SoldReportRow(f.date, f.departure, f.destination, COUNT(t.id), SUM(f.ticketCost)) FROM " +
            "Ticket t JOIN t.flight f " +
            "WHERE t.status = 'SOLD' AND t.owner IS NOT NULL AND f.date BETWEEN '%s' and '%s' " +
            "GROUP BY f.id",
            startDate, endDate
    );

    return TicketDAO.query(SoldReportRow.class, query);
}

public static <T> List<T> query(Class<T> entityClass, String query) {
    EntityManager entityManager = getEntityManager();
    TypedQuery<T> q = entityManager.createQuery(query, entityClass);
    List<T> entities = null;

    try {
        entities = q.getResultList();
    } finally {
        entityManager.close();
    }

    return entities;
}

public static EntityManager getEntityManager() {
    return factory.createEntityManager();
}

The question is , why does this happen and how to fix that?

Thanks!

After the research, I've found that the trouble was caused by the data at the database. By default, SQLite does not have the DATE column type. And it uses strings to describe timestamps. So for date comparison (just like SELECT ... WHERE date BETWEEN a AND b ) it's better to use UTC date form, not string one ( 1397036688 is the better value than the 2014-03-09 ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM