简体   繁体   中英

JPA criteria API uses SQL server convert function

My DB has 'm_date' which is of string type and stores dates as "dd-MM-yyyy" format. Now I want to fetch the records from the table with the help of the JPA criteria query between filters. Now since, m_date stores string dates, I can't directly use criteriaBuilder.between function. but before that, I need to convert it into Date using SQL in-build function CONVERT(date, m_date, 103). I tried something like to get the string dates converted to Date.

SQL query goes something like this

SELECT myId from table where status='PENDING' and CONVERT(date, m_date,103) between fromDate and toDate)

Criteria API

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<MyEntity> criteriaQuery = criteriaBuilder.createQuery(MyEntity.class);
Root<MyEntity> root = criteriaQuery.from(MyEntity.class);

Predicate statusPredicate = cb.equal(root.get("status"), cb.literal("PENDING"));

Expression<String> convertFunction = cb.function("CONVERT", String.class, cb.literal("date"), root.get("mDate"), cb.literal(103));
Predicate datePredicate = cb.between(convertFunction, fromDate, toDate); // fromDate and toDate coming from request...

CriteriaQuery<MyEntity> myQuery = criteriaQuery.select(root.get("myId")).where(statusPredicate, datePredicate);

TypedQuery<MyEntity> query = entityManager.createQuery(myQuery);
return query.getResultList();

I am getting error something like this

Hibernate: select myentity_0.my_id as col_0_0_ from table where myentity_0.status=? and (CONVERT(?,myentity.m_date,103) between ? and ?)
com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near '@P1'.

can someone please help me, how i can put 'date' as first parameter of convert function? I am stuck since so long. Help would be really appreciated. Thanks in advance.

You should be able to use root.get("mDate").as(java.sql.Date.class) instead. If that doesn't work, you will have to create a custom SQLFunction eg convert_date in Hibernate and call that:

Expression<Date> convertFunction = cb.function("convert_date", Date.class, root.get("mDate"));

which should render the SQL you desire. Could look something like this:

public class ConvertDateFunction implements SQLFunction {

    @Override
    public boolean hasArguments() {
        return true;
    }

    @Override
    public boolean hasParenthesesIfNoArguments() {
        return true;
    }

    @Override
    public Type getReturnType(Type firstArgumentType, Mapping mapping) throws QueryException {
        return StandardBasicTypes.DATE;
    }

    @Override
    public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) throws QueryException {
        return "convert(date," + args.get(0) + ",103)";
    }
}

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