前提・実現したいこと
日付が入ったテーブルから修正した値でwhere句を生成し、SELECTしたいです。
テーブル「accesslog」のカラム「actdatetime」には、
「2021/04/11 14:14:51」の様な文字列が入っています。
これから「yyyy/mm/dd」の形式でwhere句を生成したいので、
cast(replace(left(actdatetime, 10), '/', '') as integer)の様にして、
受け取った値(例:20210611 等)でSQLを発行したいです。
crietialqueryでネイティブなSQLを書いたりしたら実現できるのですが、
specificationおよびpageableと組み合わせてやりたいので上手くいきません。
root.get()の中で対象のカラムを指定してwhere句を生成すると思うのですが、
この部分で対象カラムに対して下記ソースの様に修正した値でSQLを発行するのは出来ないのでしょうか?
また代替案がありましたら、ご教授お願いします。
発生している問題・エラーメッセージ
java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name [cast(replace(left(actdatetime, 10), '/', '') as integer)] on this ManagedType [com.example.demo.accesslog.AccessLog] at org.hibernate.metamodel.model.domain.internal.AbstractManagedType.checkNotNull(AbstractManagedType.java:147) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final] at org.hibernate.metamodel.model.domain.internal.AbstractManagedType.getAttribute(AbstractManagedType.java:118) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final] at org.hibernate.metamodel.model.domain.internal.AbstractManagedType.getAttribute(AbstractManagedType.java:43) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final] at org.hibernate.query.criteria.internal.path.AbstractFromImpl.locateAttributeInternal(AbstractFromImpl.java:111) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final] at org.hibernate.query.criteria.internal.path.AbstractPathImpl.locateAttribute(AbstractPathImpl.java:204) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final] at org.hibernate.query.criteria.internal.path.AbstractPathImpl.get(AbstractPathImpl.java:177) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final] at com.example.demo.accesslog.AccessLogSpecifications$1.toPredicate(AccessLogSpecifications.java:24) ~[classes/:na] at org.springframework.data.jpa.repository.support.SimpleJpaRepository.applySpecificationToCriteria(SimpleJpaRepository.java:762) ~[spring-data-jpa-2.3.3.RELEASE.jar:2.3.3.RELEASE] at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:693) ~[spring-data-jpa-2.3.3.RELEASE.jar:2.3.3.RELEASE] at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:651) ~[spring-data-jpa-2.3.3.RELEASE.jar:2.3.3.RELEASE] at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:443) ~[spring-data-jpa-2.3.3.RELEASE.jar:2.3.3.RELEASE] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
該当のソースコード
package com.example.demo.accesslog; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import org.apache.commons.lang.StringUtils; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Component; @Component public class AccessLogSpecifications { public Specification<AccessLog> actdatetimeContains(String actdatetimeFromStr, String actdatetimeToStr) { int actdatetimeFrom = StringUtils.isBlank(actdatetimeFromStr) ? 0 : Integer.parseInt(actdatetimeFromStr.replace("/", "")); int actdatetimeTo = StringUtils.isBlank(actdatetimeToStr) ? 0 : Integer.parseInt(actdatetimeToStr.replace("/", "")); return actdatetimeFrom != 0 && actdatetimeTo != 0 ? null : new Specification<AccessLog>() { @Override public Predicate toPredicate(Root<AccessLog> root, CriteriaQuery<?> query, CriteriaBuilder cb) { return cb.between(root.get("cast(replace(left(actdatetime, 10), '/', '') as integer)"), actdatetimeFrom, actdatetimeTo); } }; } }
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/06/06 11:28