简体   繁体   中英

Java Spring hibernate HQL where clause not working

I have a HQL query with a JOIN but the where clause (instrPrice.date BETWEEN :dateFrom AND :dateTo ) on the joined entity doesn't work. The query always returns all the records of instrumentPrice instead of limiting the result by the dates.

NamedQuery

@NamedQuery(name = "findAllPrices", 
        query = "SELECT DISTINCT taPat FROM TaPatternInstrument taPat "
                + "LEFT JOIN FETCH taPat.instrument instr "
                + "LEFT JOIN instr.instrumentPriceList instrPrice "
                + "WHERE taPat.id = :taPatternInstrumentId "
                + "AND instrPrice.date BETWEEN :dateFrom AND :dateTo ")

Service which calls the Query

public TaPatternInstrument findAllPrices(int taPatternInstrumentId, LocalDate dateFrom,  LocalDate dateTo) {

   TypedQuery<TaPatternInstrument> typedQuery = createNamedQuery("findAllPrices", 
        TaPatternInstrument.class);
   typedQuery.setParameter("taPatternInstrumentId", taPatternInstrumentId);
   typedQuery.setParameter("dateFrom", dateFrom);
   typedQuery.setParameter("dateTo", dateTo);
   return typedQuery.getSingleResult(); 
}

Entities

public abstract class BaseEntity implements Serializable {

   @Id  
   @Column(name = "id")     
   @GeneratedValue(strategy =
                GenerationType.IDENTITY)
   protected int id; ... 
}

public class TaPatternInstrument extends BaseEntity {

   @ManyToOne(fetch = FetchType.EAGER)
   @JoinColumn(name = "instrument_id", nullable = false, foreignKey = @ForeignKey(name = 
            "tapatterninstrument_instrument_fk"))
   private Instrument instrument;

}


public class Instrument extends BaseEntity {

  @OneToMany(mappedBy = "instrument", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
  private List<InstrumentPrice> instrumentPriceList;

}

Generated SQL

SELECT DISTINCT tapatterni0_.id  AS id1_34_0_, 
...
FROM   tapatterninstrument tapatterni0_ 
       LEFT OUTER JOIN instrument instrument1_ 
                    ON tapatterni0_.instrument_id = instrument1_.id 
       LEFT OUTER JOIN instrumentprice instrument2_ 
                    ON instrument1_.id = instrument2_.instrument_id 
WHERE  tapatterni0_.id = ? 
       AND ( instrument2_.date BETWEEN ? AND ? ) 

The solution is to add a FETCH on instrumentPriceList : LEFT JOIN FETCH instr.instrumentPriceList instrPrice

@NamedQuery(name = "findAllPrices", 
query = "SELECT DISTINCT taPat FROM TaPatternInstrument taPat "
        + "LEFT JOIN FETCH taPat.instrument instr "
        + "LEFT JOIN FETCH instr.instrumentPriceList instrPrice "
        + "LEFT JOIN taPat.taPatternInstrumentPriceList taPatpr "
        + "WHERE taPat.id = :taPatternInstrumentId "
        + "AND instrPrice.date BETWEEN :dateFrom AND :dateTo ")

The FETCH forces Hibernate to retrieve the Entity (InstrumentPrice) immediately at the first DB request. And thus the where clause is taken into account. Without FETCH, the Entity InstrumentPrice is only retrieved from the DB when the method getInstrumentPriceList of the Entity Instrument is called (an additional call to the DB is performed). And with this additional call to the DB, the where clause is not taken into account anymore, thus retrieving all records from Entity instrumentPrice.

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