質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

Q&A

解決済

1回答

2120閲覧

Specificationで修正した値を対象に抽出するには

mimi_129

総合スコア63

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

0グッド

0クリップ

投稿2021/06/06 04:49

前提・実現したいこと

日付が入ったテーブルから修正した値で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); } }; } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

やりたいことは「actdatetimeが2021/06/08から2021/06/10までのデータを抽出したい」という理解であっていますか?

であればWHERE actdatetime BETWEEN '2021/06/08 00:00:00' AND '2021/06/10 23:59:59'とすればよいので、actdatetimeContainsを以下のようにすればよいかと思います。

java

1public Specification<AccessLog> actdatetimeContains(String actdatetimeFromStr, String actdatetimeToStr) { 2 String actdatetimeFrom = actdatetimeFromStr + " 00:00:00"; 3 String actdatetimeTo = actdatetimeToStr + " 23:59:59"; 4 return (root, query, builder) -> builder.between(root.get("actdatetime"), actdatetimeFrom, actdatetimeTo); 5}

(引数チェックは省略しています。また引数にはyyyy/MM/dd形式の文字列が入ってくる前提です)

投稿2021/06/06 11:02

neko_the_shadow

総合スコア2230

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mimi_129

2021/06/06 11:28

あー、なるほど! その発想は無かったです! とりあえずそれでやってみます! ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問