前提・実現したいこと
java8+Spring+Hibernateを使用して問い合わせ一覧(メッセージ送信者一覧)のような画面を作っています。
メッセージのやり取りをしている人の一覧を表示する際に、同じuserIdをgroup byしてメッセージが新しい順に取得したいのですが、Hibernateでうまく書けません。
実現したい取得結果
|user_id|user_name|created_at|
|:--|:--|:--|
|10|鈴木三郎|2019-02-08 19:54:14|
|3|山田太郎|2019-02-07 13:25:30|
|5|佐藤次郎|2019-02-06 16:12:34|
テーブルは以下です。
supportテーブル
|message_id|from_id|to_id|message|created_at|
|:--|:--|:--|
|1|3|0|問い合わせです。|2019-02-03 19:00:40|
|2|10|0|メッセージ内容|2019-02-04 02:42:41|
|3|10|0|問い合わせ内容|2019-02-05 16:12:34|
|4|5|0|メッセージ内容|2019-02-06 16:12:34|
|5|3|0|メッセージ内容|2019-02-07 13:25:30|
|6|10|0|メッセージ内容|2019-02-08 19:54:14|
usersテーブル
ECサイトなので関係ない住所とかありますが、問い合わせ一覧では名前が取れればと思います。
またsupportのfrom_idがuser.userIdとなっています。
|user_id|mail_address|login_pass|user_name|user_type_id|tel|postal_code|address_level1|address_level2|address_line1|address_line2|updated_at|created_at|
|:--|:--|:--|
|3|||山田太郎|
|5|||佐藤次郎|
|10|||鈴木三郎|
SQLで書くと以下です。
MySQL
1SELECT t1.*,user_name FROM support AS t1 2 inner join users on t1.from_id=users.user_id 3INNER JOIN 4 (SELECT from_id, MAX(created_at) AS maxDate FROM support GROUP BY from_id) AS t2 5ON t1.created_at = t2.maxDate AND t1.from_id = t2.from_id;
試したこと
Java
1 @SuppressWarnings("unchecked") 2 public List<Support> findByList() throws Exception { 3 DetachedCriteria maxCreateAt = DetachedCriteria.forClass(Support.class, "t1") 4 .setFetchMode("user", FetchMode.JOIN) 5 .setProjection( 6 Projections.projectionList() 7 .add(Projections.max("createdAt")) 8 .add(Projections.groupProperty("user.userId"))); 9 10 return getSession().createCriteria(Support.class) 11 .add(Property.forName("createdAt").eq(maxCreateAt)) 12 .addOrder(Order.desc("createdAt")) 13 .list(); 14 }
発生している問題・エラーメッセージ
Hibernate: select this_.message_id as message_1_8_0_, this_.from_id as from_id2_8_0_, this_.to_id as to_id3_8_0_, this_.message as message4_8_0_, this_.created_at as created_5_8_0_ from support this_ where this_.created_at = ( select max(t1_.created_at) as y0_, t1_.from_id as y1_ from support t1_ group by t1_.from_id ) order by this_.created_at desc WARN : org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 1241, SQLState: 21000 ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Operand should contain 1 column(s) WARN : org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Warning Code: 1241, SQLState: 21000 WARN : org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Operand should contain 1 column(s) 重大: Servlet.service() for servlet [appServlet] in context with path [/shop] threw exception [Request processing failed; nested exception is org.hibernate.exception.DataException: could not extract ResultSet] with root cause [木 2 07 21:45:49 JST 2019]
試したこと
group byで取得できる特定のカラムのみを指定するのがちょっと理解ができないです。
hibernateだと以下のxmlで設定すると、
SupportとUsersをJOINした取得して結果をgroup byしてエラーになっている?のではないかと思うのですが。。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.example.shop.domain"> <class name="Support" table="support"> <id name="messageId" column="message_id"> <generator class="native" /> </id> <many-to-one name="user" column="from_id" /> <property name="toId" column="to_id" type="integer" /> <property name="message" column="message" type="string" /> <property name="createdAt" column="created_at" type="timestamp" /> </class> </hibernate-mapping>
以下を参考にいろいろやってみたのですがどうしてもうまくかけず。。
https://access.redhat.com/documentation/ja-jp/red_hat_jboss_web_server/1.0/html/hibernate_core_reference_guide/querycriteria-projection
6時間ぐらいハマって、降参状態です。
hibernateでの書き方をご教授お願いします。
補足情報(FW/ツールのバージョンなど)
Java8
org.springframework 4.2.0.RELEASE
org.hibernate 4.3.10.Final
あなたの回答
tips
プレビュー