回答編集履歴

3

修正

2020/03/15 14:19

投稿

rubytomato
rubytomato

スコア1752

test CHANGED
File without changes

2

修正

2020/03/15 14:19

投稿

rubytomato
rubytomato

スコア1752

test CHANGED
@@ -404,7 +404,7 @@
404
404
 
405
405
  Message message = new Message();
406
406
 
407
- message.setMessageContent(messageForm.getMessageContent());
407
+ message.setMessageContent(messageContent);
408
408
 
409
409
  message.setMessageTime(new Date());
410
410
 

1

追記

2020/03/15 14:19

投稿

rubytomato
rubytomato

スコア1752

test CHANGED
@@ -87,3 +87,345 @@
87
87
  }
88
88
 
89
89
  ```
90
+
91
+
92
+
93
+ **追記**
94
+
95
+
96
+
97
+ 以下は私だったらこう実装するという意味の内容です。なのでこうしなければならないという訳ではなく、あくまで参考程度のものです。また、コード全体ではなく必要な個所だけ抜粋しています。
98
+
99
+
100
+
101
+ エンティティクラス
102
+
103
+
104
+
105
+ ```java
106
+
107
+ @Entity
108
+
109
+ @NamedQuery(name="Message.findAll", query="SELECT m FROM Message m")
110
+
111
+ public class Message implements Serializable {
112
+
113
+
114
+
115
+ @Id
116
+
117
+ @GeneratedValue(strategy=GenerationType.IDENTITY)
118
+
119
+ @Column(name="message_id")
120
+
121
+ // フィールドの型にプリミティブ型は使用しない
122
+
123
+ //private long messageId;
124
+
125
+ private Long messageId;
126
+
127
+
128
+
129
+ //処理のないデフォルトコンストラクタは書かない
130
+
131
+ //public Message() {
132
+
133
+ //}
134
+
135
+
136
+
137
+ public void setSenderUser(User senderUser) {
138
+
139
+ this.senderUser = senderUser;
140
+
141
+ this.senderUser.addSendMessage(this);
142
+
143
+ }
144
+
145
+
146
+
147
+ public void setReceiverUser(User receiverUser) {
148
+
149
+ this.receiverUser = receiverUser;
150
+
151
+ this.receiverUser.addReceiveMessage(this);
152
+
153
+ }
154
+
155
+
156
+
157
+ }
158
+
159
+ ```
160
+
161
+
162
+
163
+ ```java
164
+
165
+ @Entity
166
+
167
+ //Transactionalアノテーションはトランザクション境界を考えて付与する
168
+
169
+ //@Transactional
170
+
171
+ @NamedQuery(name="User.findAll", query="SELECT u FROM User u")
172
+
173
+ public class User implements Serializable {
174
+
175
+
176
+
177
+ @Id
178
+
179
+ @Column(name="user_id")
180
+
181
+ // フィールドの型にプリミティブ型は使用しない
182
+
183
+ //private int userId;
184
+
185
+ private Integer userId;
186
+
187
+
188
+
189
+ @OneToMany(mappedBy="senderUser")
190
+
191
+ //意味の通じにくいフィールド名は避ける
192
+
193
+ //private List<Message> messages1;
194
+
195
+ private List<Message> sendMessages;
196
+
197
+
198
+
199
+ @OneToMany(mappedBy="receiverUser")
200
+
201
+ //意味の通じにくいフィールド名は避ける
202
+
203
+ //private List<Message> messages2;
204
+
205
+ private List<Message> receiveMessages;
206
+
207
+
208
+
209
+ //処理のないデフォルトコンストラクタは書かない
210
+
211
+ //public User() {
212
+
213
+ //}
214
+
215
+
216
+
217
+ public void addSendMessage(Message message) {
218
+
219
+ if (this.sendMessages == null) {
220
+
221
+ this.sendMessages = new ArrayList<>();
222
+
223
+ }
224
+
225
+ this.sendMessages.add(message);
226
+
227
+ }
228
+
229
+
230
+
231
+ public void addReceiveMessage(Message message) {
232
+
233
+ if (this.receiveMessages == null) {
234
+
235
+ this.receiveMessages = new ArrayList<>();
236
+
237
+ }
238
+
239
+ this.receiveMessages.add(message);
240
+
241
+ }
242
+
243
+
244
+
245
+ }
246
+
247
+ ```
248
+
249
+
250
+
251
+ リポジトリインターフェース
252
+
253
+ (※`MessageReposioty`は`MessageRepository`のtypoです)
254
+
255
+
256
+
257
+ ```java
258
+
259
+ //不要なアノテーションは付与しない
260
+
261
+ //@Repository
262
+
263
+ //Transactionalアノテーションはトランザクション境界を考えて付与する
264
+
265
+ //@Transactional
266
+
267
+ public interface MessageRepository extends JpaRepository<Message, Long> {
268
+
269
+ //プリミティブ型を避ける
270
+
271
+ //List<Message> findBySenderUser_UserId(int userId);
272
+
273
+ //List<Message> findByReceiverUser_UserId(int userId);
274
+
275
+ List<Message> findBySenderUser_UserId(Integer userId);
276
+
277
+ List<Message> findByReceiverUser_UserId(Integer userId);
278
+
279
+
280
+
281
+ //可能な限りネイティブクエリを避ける
282
+
283
+ //今回はsaveメソッドで十分なので使用しない
284
+
285
+ //@Modifying
286
+
287
+ //@Query(value = "insert into message (sender_user_id,receiver_user_id,message_content) "
288
+
289
+ // + "VALUES (:senderUserId,:receiverUserId,:messageContent)", nativeQuery = true)
290
+
291
+ //@Transactional
292
+
293
+ //void sendMessage(@Param("senderUserId") int senderUserId, @Param("receiverUserId") int receiverUserId,
294
+
295
+ // @Param("messageContent") String messageContent);
296
+
297
+
298
+
299
+ }
300
+
301
+ ```
302
+
303
+
304
+
305
+ コントローラクラス
306
+
307
+
308
+
309
+ ```java
310
+
311
+ @Controller
312
+
313
+ @RequestMapping("profile")
314
+
315
+ public class MessageController {
316
+
317
+
318
+
319
+ //コンストラクタインジェクションを利用する
320
+
321
+ //@Autowired
322
+
323
+ //UserRepository userRepository;
324
+
325
+ //@Autowired
326
+
327
+ //MessageRepository messageRepository;
328
+
329
+
330
+
331
+ private final UserRepository userRepository;
332
+
333
+ private final MessageRepository messageRepository;
334
+
335
+
336
+
337
+ public MessageController(UserRepository userRepository, MessageRepository messageRepository) {
338
+
339
+ this.userRepository = userRepository;
340
+
341
+ this.messageRepository = messageRepository;
342
+
343
+ }
344
+
345
+
346
+
347
+ //送信時の処理
348
+
349
+ @PostMapping("/{userId}/message")
350
+
351
+ // トランザクション境界をここに設定する(この例では)
352
+
353
+ // 本来ならサービスクラスを実装しそのメソッドにトランザクション境界を設定する
354
+
355
+ @Transactional(readOnly = false, timeout = 10)
356
+
357
+ String sendMessage(@Validated MessageForm messageForm,
358
+
359
+ // バリデーションを行うのならBindingResultでその結果を受け取る
360
+
361
+ BindingResult result,
362
+
363
+ @AuthenticationPrincipal LoginUserDetails userDetails,
364
+
365
+ @PathVariable("userId") Integer userId
366
+
367
+ // 使用しない引数は定義しない
368
+
369
+ /* Model model */) {
370
+
371
+
372
+
373
+ if (result.hasErrors()) {
374
+
375
+ // バリデーションエラー時の処理
376
+
377
+ }
378
+
379
+
380
+
381
+ //User senderUser = userDetails.getUser();
382
+
383
+ User senderUser = userRepository.findById(userDetails.getUser().getUserId()).orElseThrow();
384
+
385
+
386
+
387
+ //安易にnullを返さない。検索できなかったときにどうするか仕様を決めておく。
388
+
389
+ //User receiverUser = userRepository.findById(userId).orElse(null);
390
+
391
+ User receiverUser = userRepository.findById(userId).orElseThrow();
392
+
393
+
394
+
395
+ //int senderUserId = senderUser.getUserId();
396
+
397
+ //int receiverUserId = receiverUser.getUserId();
398
+
399
+
400
+
401
+ String messageContent = messageForm.getMessageContent();
402
+
403
+
404
+
405
+ Message message = new Message();
406
+
407
+ message.setMessageContent(messageForm.getMessageContent());
408
+
409
+ message.setMessageTime(new Date());
410
+
411
+ message.setSenderUser(senderUser);
412
+
413
+ message.setReceiverUser(receiverUser);
414
+
415
+ messageRepository.save(message);
416
+
417
+
418
+
419
+ //リポジトリのsaveメソッドで永続化するので使用しない
420
+
421
+ //messageRepository.sendMessage(senderUserId, receiverUserId, messageContent);
422
+
423
+ return "redirect:/profile/" + userId + "/message";
424
+
425
+ }
426
+
427
+
428
+
429
+ }
430
+
431
+ ```