10

これは私のPostgreSQL関数です:

salvarArquivoGeometricoCasoZeroPOINT
(dimensao text,tableName text,tuplas text[],srid text)

これにはパラメーターがあり、JPQLからtext[]Javaを渡したいと思います。String[]

public String salvarGeometriaCaso0(String[] tuplas,FileDto arquivo){
        Query query =
        em().createNativeQuery("select 
salvarArquivoGeometricoCasoZeroPOINT(?1,?2,?3,?4)");
        query.setParameter(1,arquivo.getGeo());//String
        query.setParameter(2,arquivo.getTable());/String
        query.setParameter(3,tuplas);//String[]
        query.setParameter(4,arquivo.getSrid());//String
        return (String) query.getSingleResult();//function returns a Text, so cast to String
}

上記のコードは例外を除いて失敗します:

ERROR] Internal Exception: org.postgresql.util.PSQLException: Can not infer a SQL
type to use for an instance of [Ljava.lang.String;. 
Use setObject () with an explicit Types value to specify the type to use.

そのため、EclipseLinkから関数を呼び出す方法がわかりません。

4

4 に答える 4

7

私はそれに答えるのがとても遅いです。

このソリューションは、postgreSQLの組み込み関数を使用した一種の回避策であり、私にとっては間違いなく機能しました。

リファレンスブログ

1)文字列配列をカンマ区切り文字列に変換します

Java8を使用している場合、それは非常に簡単です。他のオプションはここにあります

String commaSeparatedString = String.join(",",stringArray); // Java8 feature

2)PostgreSQL組み込み関数string_to_array()

ここで他のpostgreSQL配列関数を見つけることができます

// tableName ( name text, string_array_column_name text[] )

String query = "insert into tableName(name,string_array_column_name ) values(?, string_to_array(?,',') )";


int[] types = new int[] { Types.VARCHAR, Types.VARCHAR};

Object[] psParams = new Object[] {"Dhruvil Thaker",commaSeparatedString };

jdbcTemplate.batchUpdate(query, psParams ,types); // assuming you have jdbctemplate instance
于 2016-09-06T20:15:43.567 に答える
6

String []型のJava配列を渡してテストすると、PreparedStatement.setObject(...)報告する動作が得られます。PgJDBCは、パラメータPreparedStatement.setObject()の有無にかかわらず、への引数としてJava配列を受け入れないようTypes.ARRAYです。

コンプライアンス

JDBC仕様の16.5「配列オブジェクト」は、JDBCArrayが部分的に存在するため、クライアントが大きな配列をメモリにコピーする必要がなく、参照によって使用できることを示しています。生のJava配列をパラメーターとして受け入れるためにJDBCドライバーが必要かどうかはよくわかりません。すべてのスペックコードは参照しており、スペックは、アレイが付録Bおよび他の場所java.sql.Arrayのインターフェイスを介してマッピングされていることを明確にしています。Arrayクイック検索/読み取りでは、生のJava配列をパラメーターとして渡すか、結果として返す以外の言及は見つかりませんでした。byte[]

ただし、§16.5.4では、JDBC4.2ドラフト仕様は次のようになっています。

A Java array may be passed as an input parameter by calling the method
PreparedSatement.setObject.

ただし、残りのコードはすべてArrayオブジェクトを参照しています。Array「Javaアレイ」という意味ですか?それとも、次のような生のネイティブJava配列を意味しString[]ますか?

クライアントはをjava.sql.Array介してインターフェイスを使用することになっているように見えるConnection.createArrayOf(...)ので、EclipseLinkはおそらく間違ったことをしています。

それについて何をしますか

java.sql.Arrayオブジェクトを介して配列をJDBCに渡す一般的に指定されているメソッドを使用することを期待して、EclipseLinkを2.4に更新してみてください。

@ArrayEclipseLink拡張機能でマッピングに注釈を付ける必要がある場合もあります。このフォーラムスレッドre2.3およびバグ361701も参照してください。

EclipseLinkの動作をオーバーライドするには、独自のタイプハンドラーを実装する必要があるようです。PgJDBCを介して配列パラメータを正しく設定するには、次を使用する必要があります。

    Array sqlArray = conn.createArrayOf("text", strArray);
    pstmt.setArray(1, sqlArray);
    pstmt.executeUpdate();

...ここで、connとはそれぞれpstmtajava.sql.Connectionとaであり、はインスタンスです。PreparedStatementstrArrayString[]

eclipselinkwikiのカスタムデータ型を参照してください。

ちなみに、配列のデータ型を指定するために文字列型名を使用することは、createArrayOfが存在することを考えると、一種の狂気のようですjava.sql.Types。移植性がはるかに難しくなります。上記のコードは(たとえば)Oracleでは実行されません。これは、Oracleが型名として使用したくVARCHARないためです。text


注:単体テストorg/postgresql/test/jdbc2/ArrayTest.javaにはがArrayTest.testSetArray()あり、166行目で次のようにテストされます。

    pstmt.setObject(1, arr);
    pstmt.executeUpdate();

...ただし、のタイプarrjava.sql.Array、ではありませんint[]。これはJDBC配列型であり、通常のJava配列ではありません。

于 2012-08-22T02:17:20.013 に答える
1

EclipseLinkはバグ361701を修正していないよう です。@CraigRingerが言及しました。

String []をパラメーターとして渡す唯一の方法は、EclipseLinkなしでJDBCを使用することです。コードを確認してください。

Connection con = ConnectionHelper.getConnection();
        Array tArray = con.createArrayOf("text", tuplas);
        PreparedStatement pstm =
        con.prepareStatement("select salvarArquivoGeometricoCasoZeroPOINT(?,?,?,?)");
        pstm.setString(1,arquivo.getGeoType());
        pstm.setString(2,arquivo.getTable());
        pstm.setArray(3,tArray);
        pstm.setString(4,arquivo.getSrid());
        rs = pstm.executeQuery();

ConnectionHelperそれは私のjava.sql.Connectionクラスです。

皆さんの助けに感謝します:@CraigRingerと@MattBall、ありがとう。

于 2012-08-22T18:59:42.973 に答える
0

jdbcTemplate.update代わりに誤って使用したときにこのエラーが発生しましたjdbcTemplate.batchUpdate

于 2019-03-11T14:59:06.673 に答える