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

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

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

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

Java

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

MyBatis

MyBatisはJavaや.NET Frameworkでなどで使用できる、SQL文や、ストアドプロシージャをオブジェクトと紐付けるO/Rマッピングフレームワークです。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

2回答

3268閲覧

画像データをDBに登録したい

退会済みユーザー

退会済みユーザー

総合スコア0

PostgreSQL

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

Java

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

MyBatis

MyBatisはJavaや.NET Frameworkでなどで使用できる、SQL文や、ストアドプロシージャをオブジェクトと紐付けるO/Rマッピングフレームワークです。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

1グッド

0クリップ

投稿2020/07/09 07:13

編集2020/07/09 07:17

前提・実現したいこと

ローカル環境でWEBアプリケーションを作成しており、ユーザーのプロフィール画像を設定できるようにしようと思っています。
その際DBに画像データをバイナリとして登録しておき、そちらを取得しようと考えました。

エラーメッセージ全文

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property='isImage', mode=IN, javaType=class java.lang.Object, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #1 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #1 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: org.postgresql.util.PSQLException: ラージオブジェクトは、自動コミットモードで使うことができません。] with root cause

該当のソースコード(抜粋)

html

1<form method="post" enctype="multipart/form-data" th:action="@{/profile}" th:object="${profileForm}"> 2 <input th:field="*{image}" type="file" multiple/> 3 <input type="submit" value="送信"/> 4</form>

controller

1@PostMapping 2 public ModelAndView profileEditPost(ProfileForm profileForm, ModelAndView mav) { 3 try { 4 InputStream isImage = profileForm.getImage().getInputStream(); 5 profileMapper.updateImage(isImage); 6 } catch (IOException e) { 7 e.printStackTrace(); 8 } 9 return mav; 10 }

Mapper

1<insert id="updateImage"> 2 insert into images ( 3 image 4 ) 5 values ( 6 #{isImage} 7 ) 8</insert>

試したこと

InputStreamではなく、byte[]のままMapperにパラメータを渡そうとしましたが、
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed;
nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException:
Parameter 'isImage' not found. Available parameters are [array]] with root cause
のエラーが出てしまいます。
ちなみにformはnullではありません。

またDBの型もoid、byteaともに試しましたが駄目でした。

MyBatisのHandlerの実装やこちらを参考にしてみましたが、
org.apache.commons.io.IOUtilsがインポートできませんでした。
下記の環境で画像ファイルをDBに登録する方法についてご助力お願いいたします。
バイナリにこだわっているわけではありませんが、staticに保存とかは考えていません。

補足情報(FW/ツールのバージョンなど)

SpringBoot、MyBatis、PostgreSQL

A-pZ👍を押しています

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

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

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

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

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

xebme

2020/07/16 04:32

formで送信するマルチパートの名前は'image'です。エラーメッセージは'isImage'が見つからないだけど、#{image}にしなくても良いのですか?
退会済みユーザー

退会済みユーザー

2020/07/16 04:58

変数名が分かりにくくて申し訳ないです。上記の場合、 InputStream isImage = profileForm.getImage().getInputStream(); このisImageをMapperに渡してます。
xebme

2020/07/16 06:59 編集

Parameter 'isImage' not found.に対応すべきでしょうか、しなくても良いですか。これは本質的な原因ではないのでしょうか?<-- これは間違いです。下のエラーメッセージを見ていました。
guest

回答2

0

mybatis-spring-boot-starter でなく自前で設定してる?
普通にやってみたがデフォルト トランザクションモードだからエラーにならんかったが

  • model / mapper は mybatis-generator で自動生成から変更なし

java

1import java.util.*; 2 3import org.mybatis.spring.annotation.*; 4import org.springframework.beans.factory.annotation.*; 5import org.springframework.http.*; 6import org.springframework.stereotype.*; 7import org.springframework.web.bind.annotation.*; 8import org.springframework.web.multipart.*; 9 10import lombok.*; 11import lombok.extern.slf4j.*; 12 13@Slf4j 14@Controller 15@RequestMapping("/") 16@MapperScan 17public class IndexController { 18 19 @Autowired 20 FilesMapper mapper; 21 22 @ModelAttribute("files") 23 public List<FilesWithBLOBs> getFiles() { 24 FilesExample example = new FilesExample(); 25 return mapper.selectByExampleWithBLOBs(example); 26 } 27 28 @GetMapping 29 public String index() { 30 log.info("GET"); 31 return "index"; 32 } 33 34 @PostMapping 35 @SneakyThrows 36 public String post(@RequestPart("file") MultipartFile file) { 37 log.info("POST"); 38 FilesWithBLOBs files = new FilesWithBLOBs(); 39 files.setFile(file.getBytes()); 40 mapper.insertSelective(files); 41 return "redirect:/"; 42 } 43 44 @ResponseBody 45 @GetMapping(path = "image/{id}", produces = MediaType.IMAGE_PNG_VALUE) 46 public byte[] file(@PathVariable("id") Integer id) { 47 48 FilesKey key = new FilesKey(); 49 key.setId(id); 50 51 FilesExample example = new FilesExample(); 52 example.or(example.createCriteria().andIdEqualTo(id)); 53 54 return mapper.selectByExampleWithBLOBs(example).get(0).getFile(); 55 } 56}

sql

1CREATE SEQUENCE files_seq; 2 3CREATE TABLE files ( 4 id INT NOT NULL DEFAULT nextval('files_seq'), 5 file BYTEA NOT NULL, 6 PRIMARY KEY (id) 7);

xml

1<?xml version="1.0" encoding="UTF-8"?> 2<!DOCTYPE generatorConfiguration 3 PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" 4 "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> 5 6<generatorConfiguration> 7 8 <context id="default" defaultModelType="hierarchical"> 9 10 <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/> 11 12 <commentGenerator> 13 <property name="suppressDate" value="true"/> 14 </commentGenerator> 15 16 <jdbcConnection 17 driverClass="org.postgresql.Driver" 18 connectionURL="jdbc:postgresql://localhost:5432/spring" 19 userId="spring" 20 password="spring"/> 21 22 <javaModelGenerator 23 targetProject="${targetProject}" 24 targetPackage="${entity}" /> 25 26 <javaClientGenerator 27 targetProject="${targetProject}" 28 targetPackage="${mapper}" 29 type="ANNOTATEDMAPPER"/> 30 31 <table tableName="files"/> 32 33 </context> 34</generatorConfiguration>

yml

1server: 2 port: 9100 3 4spring: 5 datasource: 6 url: jdbc:postgresql://localhost:5432/spring 7 username: spring 8 password: spring 9 10 flyway: 11 enabled: true 12 encoding: UTF-8 13 clean-on-validation-error: true
plugins { id 'org.springframework.boot' version '2.3.1.RELEASE' id 'io.spring.dependency-management' version '1.0.9.RELEASE' id 'java' } group = 'com.example.spring.fileupload' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' configurations { mybatisGenerator { extendsFrom runtimeOnly } compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.flywaydb:flyway-core' implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'org.postgresql:postgresql' annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' annotationProcessor 'org.projectlombok:lombok' testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } mybatisGenerator 'org.mybatis.generator:mybatis-generator-core:1.3.5' mybatisGenerator 'tk.mybatis:mapper:4.1.5' } test { useJUnitPlatform() } task mybatisGenerator { group 'mybatis' doLast { File xml = new File("$projectDir", 'mybatis-generator.xml') File src = new File("$projectDir", 'src/main/java') ant.properties['targetProject'] = src.getAbsolutePath() ant.properties['entity']='com.example.spring.fileupload.entity'; ant.properties['mapper']='com.example.spring.fileupload.mapper'; ant.taskdef( name: 'mbgenerator', classname: 'org.mybatis.generator.ant.GeneratorAntTask', classpath: configurations.mybatisGenerator.asPath ) ant.mbgenerator( overwrite: true, configfile: xml, verbose: true) { propertyset { propertyref(name: 'targetProject') propertyref(name: 'entity') propertyref(name: 'mapper') } } } }

投稿2020/07/15 14:12

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2020/07/16 02:16 編集

詳細を提示していただきありがとうございます。 '''mybatis-spring-boot-starter'''で設定しているのですが、自分の理解が追い付いてないのが 一番の原因だと思います。すいません。 よろしければ、'''mapper.selectByExampleWithBLOBs(example);'''で 何をされてるのか教えていただけますでしょうか。
退会済みユーザー

退会済みユーザー

2020/07/16 02:23

mybatis-generator で作成された Interface(実装は mybatis 任せ)ですね。 実装クラスとしては保持されていません。
退会済みユーザー

退会済みユーザー

2020/07/16 03:01

"select" から始まる通り SELECT ~ が発行されるので本筋ではないです
退会済みユーザー

退会済みユーザー

2020/07/16 03:36

selectの部分もですが、どちらかというと List<FilesWithBLOBs> getFiles(){}が分かっていません。 post時にfileをsetしていると思うのですが、こちらはなにをしているのでしょうか? 分かりづらくてすいません。
退会済みユーザー

退会済みユーザー

2020/07/16 04:36 編集

更新には関係ない @ModelAttribute が 外部メソッド、フィールドに設定されている場合はそのコントローラーで共通に利用できる。
guest

0

以下参考
4. ラージオブジェクト

最後に「executeUpdate」メソッドを呼び出しデータを格納しますが、注意点として必ずAutoCommitモードをオフにしなければなりません(1行目)。これはPostgreSQLのJDBCドライバの制約です。

投稿2020/07/09 07:23

編集2020/07/10 00:32
sazi

総合スコア25184

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

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

sazi

2020/07/15 14:14 編集

マイナス評価の方、理由を教えてくれると嬉しいのですが。
退会済みユーザー

退会済みユーザー

2020/07/10 00:16

あれじゃね、MyBatis じゃないからとか
sazi

2020/07/10 00:34 編集

MyBaitsだと > AutoCommitモードをオフにしなければなりません。これはPostgreSQLのJDBCドライバの制約です。 という所が理由にならないという事なんでしょうか。 言いたいところを強調しておきました。
退会済みユーザー

退会済みユーザー

2020/07/13 12:57

ばたばたして確認するのが遅れてしまい申し訳ありません。 回答ありがとうございます。 @Transactionを利用することでラージオブジェクトに格納することはできたみたいです。 ただ、おっしゃられている通りMyBatisにて実装できませんでした。 またリマインドさせていただきたいと思います。
A-pZ

2020/07/15 10:29

これ環境に依存するものだと思われるので、以下の情報も追加していただくと問題が解決するかもしれません。 * SpringBootとMybatisのバージョン。もしspring-boot-starter系を使っているならそちらのバージョン。 * SpringBootからPostgreSQLへ接続するときの接続設定 * Mybatisの設定ファイル * PostgreSQLのバージョンと、PostgreSQLそのものに定義している自動コミットの設定 * データ登録対象のテーブル定義 ちなみに私が試したところ(SpringBoot-2.3.1+PostgreSQL12のデフォルト設定)、byteaの項目に画像データを登録しても、このような例外は発生せず、登録が正常に完了しました。
sazi

2020/07/15 14:18

そもそもエラーが「ラージオブジェクトは、自動コミットモードで使うことができません。」となっているんだから、一番に疑うのはそれだと思うんですよね。 低評価した人は精髄反射したんだろうか(と、煽ってみる)
退会済みユーザー

退会済みユーザー

2020/07/15 14:45

@A-pZ おそらく starter 使わずに自前で設定してる
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問