如何从java.time使用Instant创建HQL

时间:2017-11-09 20:55:05

标签: spring hibernate jpa hql java-time

我正在使用spring-jpa开发一个小项目。我决定使用java.time来处理日期问题。一切正常,直到我不得不处理HQL。

所以我正在尝试进行此查询:

@Query("SELECT sensor "
            + "FROM TrashSensor sensor "
            + "join sensor.measurementList measurement "
            + "WHERE sensor.id = 100 AND measurement.instantOfMeasure > '2017-01-01'")
    public TrashSensor findTrashSensorByIdCustom();

measurement.instantOfMeasure的类型是来自java.time的Instant。

所以我的WHERE子句的最后一个AND总是返回true,所以我没有得到我需要的过滤器。

如何使用HQL和java.time进行此比较? Hibernate是否支持这个?

1 个答案:

答案 0 :(得分:0)

您可以使用

进行开发

1种方式 - > (在TrashSensorRepository界面中)

@Query("SELECT sensor "
            + "FROM TrashSensor sensor "
            + "join sensor.measurementList measurement "
            + "WHERE sensor.id =:sensorId AND measurement.instantOfMeasure > :instantOfMeasure")
public TrashSensor findTrashSensorByIdCustom(@Param("sensorId") sensorId, @Param("instantOfMeasure") Instant instantOfMeasure);

java.time包中的类型直接映射到相应的SQL类型(自Java 8起)

  • LocalDate映射到DATE
  • LocalTime和OffsetTime映射到TIME
  • Instant,LocalDateTime,OffsetDateTime和ZonedDateTime映射到TIMESTAMP

2路 - > (如果您已为动态运行HQL创建了自定义实用程序类)

// Utility for run custom dynamic HQL query
@Service
@Transactional
public class HibernateQueryService {

    private final Logger log = LoggerFactory.getLogger(HibernateQueryService.class);
    private JpaContext jpaContext;

    public List executeHibernateQuery(String sql, Class entity){
        log.debug("HibernateQuery executing: "+sql);
        Session session = jpaContext.getEntityManagerByManagedType(Article.class).unwrap(Session.class);
        return session.createQuery(sql, entity).getResultList();
    }
}
// Custom converter
public class CustomConverter{    

public static Timestamp toTimestamp(Instant time){
        return time != null ? Timestamp.from(time) : null;
    }

    public static Instant toInstant(Timestamp timestamp){
        return timestamp != null ? timestamp.toInstant() : null;
    }

}
// Solution

public class Solution2{


    public static makeIt(){

        boolean isFirst = true;

        String query = "SELECT sensor "
            + "FROM TrashSensor sensor "
            + "join sensor.measurementList measurement ";            

        if(sensor.id != null){
            query += isFirst ? "WHERE " : "AND ";
            query += "sensor.id="+sensor.id+" ";
            isFirst = false;
        }

        if(measurement.instantOfMeasure != null){
            query += isFirst ? "WHERE " : "AND ";
            query += "measurement.instantOfMeasure > "+toTimestamp(measurement.instantOfMeasure)+" ";            
        }

        List<TrashSensor> hibernateQueryService.executeHibernateQuery(query, TrashSensor.class);

    }


}