やりたいこと
- docker + spring boot で、簡単なCRUDのrestAPIを作成したいと考えています
問題
- curlコマンドでPOSTすると、リクエストパラメータをいれているにも関わらず、nullエラーのようなものが返ってきます
具体的なエラー部分
- アプリを実行後、ターミナルで
curl -X POST -H "Content-Type: application/json" -d '{"name":"aaa", "message":"bbb"}' localhost:8080/tweet
としたところ、Internal Server Error
が返ってきました。 - アプリのデバッグログには以下のようなログが出てきました
// 返ってきたエラー 2020-05-28 10:55:59.693 DEBUG 8975 --- [nio-8080-exec-6] org.hibernate.SQL : select next_val as id_val from hibernate_sequence for update 2020-05-28 10:55:59.696 DEBUG 8975 --- [nio-8080-exec-6] org.hibernate.SQL : update hibernate_sequence set next_val= ? where next_val=? 2020-05-28 10:55:59.704 DEBUG 8975 --- [nio-8080-exec-6] org.hibernate.SQL : insert into tweet (message, name, id) values (?, ?, ?) 2020-05-28 10:55:59.707 WARN 8975 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1048, SQLState: 23000 2020-05-28 10:55:59.707 ERROR 8975 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper : Column 'message' cannot be null 2020-05-28 10:55:59.712 ERROR 8975 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause java.sql.SQLIntegrityConstraintViolationException: Column 'message' cannot be null ~~~
やったこと
- 下記のServiceクラスのコードを書き換えて、idだけにしたり、
nullable = true
にして試したりしましたが、エラーは治りませんでした - dockerとの接続がうまく行っていないのかと思いましたが、urlは問題なさそうなのでそこでエラーは発生しない
- 手動でmySQLに
tweet
テーブルを作成し、id
,name
,message
の値もいれてPOSTしてみたけど、エラー変わらず - 手動で値をいれた状態でGETしたところ、データが入っているにも関わらず
[{}]
と空のレスポンスが返ってきた - その際のデバッグログのSQL文を直接DBで叩いたら、正常にデータが取得できた
// 0_などはhibernateが出力するエイリアスらしいので、それを削除してDBに接続して以下を実行したら、正常に値が帰ってきた select tweet0_.id as id1_0_, tweet0_.message as message2_0_, tweet0_.name as name3_0_ from tweet tweet0_
- POST時に値をいれてリクエストしているのに、nullだと認識されてしまっているのが原因かと考えているのですが、有効な対処が見つからず難儀しています、、、
コード
dockerイメージ
yml
1// docker-compose.yml 2 3version: "3" 4services: 5 database: 6 image: mysql:5.7 7 command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci 8 environment: 9 MYSQL_ROOT_PASSWORD: hoge 10 MYSQL_DATABASE: testdb 11 volumes: 12 - /tmp/test_mysql:/var/lib/mysql 13 ports: 14 - 3306:3306
Spring Bootのapplication.yml
spring: datasource: sqlScriptEncoding: UTF-8 driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/testdb?useSSL=false&requireSSL=false username: root password: hoge # アプリケーション起動時にデータベースを初期化しないようにする jpa: hibernate: ddl-auto: update # spring boot起動時にDBにテーブル作成できない問題の対応 properties: hibernate: dialect: org.hibernate.dialect.MySQL57Dialect logging: level: sql: debug
Spring Bootコード
java
1// Tweet.java 2// Entityクラス 3 4@Entity 5@Data 6@NoArgsConstructor 7@AllArgsConstructor 8@Table(name = "tweet") 9public class Tweet { 10 11 @Id 12 @GeneratedValue 13 @Column 14 private int id; 15 16 @Column(nullable = false) 17 private String name; 18 19 @Column(nullable = false) 20 private String message; 21 22}
java
1// TweetRepository.java 2// Repositoryクラス 3 4@public interface TweetRepository extends JpaRepository<Tweet,Integer>{}
java
1// TweetService.java 2// Serviceクラス 3 4@Service 5@Transactional 6public class TweetService { 7 @Autowired 8 TweetRepository tweetRepository; 9 10 public Tweet postTweet(Tweet tweet){ 11 return tweetRepository.save(tweet); 12 } 13 14 public List<Tweet> getTweet(){ 15 return tweetRepository.findAll(); 16 } 17}
java
1// TweetController.java 2// コントローラー 3 4@RestController 5@RequestMapping("tweet") 6public class TweetController { 7 @Autowired 8 TweetService tweetService; 9 10 @RequestMapping(method = RequestMethod.POST) 11 Tweet postTweet(@RequestBody Tweet tweet) { 12 return tweetService.postTweet(tweet); 13 } 14 15 @RequestMapping(method = RequestMethod.GET) 16 List<Tweet> getTweet() { 17 return tweetService.getTweet(); 18 } 19}
回答1件
あなたの回答
tips
プレビュー