2012-02-03 9 views
2

私は単純なことをしようとしています:オブジェクト型パラメータを持つストアドプロシージャを呼び出します。JPA + StoredProcedureCall +オブジェクト型INパラメータ

これは私がDBに持っているものです。

create or replace 
TYPE TEST_TYPE AS OBJECT 
(
    test_field varchar(100) 
) 

CREATE OR REPLACE PROCEDURE TEST_PROC 
(
    PARAM1 IN TEST_TYPE 
) AS 
BEGIN 
END TEST_PROC; 

これは私が私のJavaコードで持っているものです。

@Embeddable 
@Struct(name = "TEST_TYPE", fields = {"TEST_FIELD"}) 
public class TestStruct 
{ 

    private String testField; 

    public String getTestField() { 
     return testField; 
    } 

    public void setTestField(String testField) { 
     this.testField = testField; 
    } 
} 

@PostConstruct 
    public void init() 
    { 

     StoredProcedureCall call = new StoredProcedureCall(); 
     call.setProcedureName("TEST_PROC"); 
     call.addNamedArgument("PARAM1", "PARAM1", Types.STRUCT, "TEST_TYPE", TestStruct.class); 

     DataReadQuery dataReadQuery = new DataReadQuery(call); 
     dataReadQuery.addArgument("PARAM1"); 

     TestStruct testStruct = new TestStruct(); 
     List args = new ArrayList(); 
     args.add(testStruct); 

     Object result = ((EntityManagerImpl)em.getDelegate()).getSession().executeQuery(dataReadQuery,args); 
    } 

これは、私は、実行時に得るものです:

Internal Exception: java.sql.SQLException: Invalid column type 
Error Code: 17004 
Call: BEGIN TEST_PROC(PARAM1=>?); END; 
    bind => [1 parameter bound] 
Query: DataReadQuery() 

私は完全にJPA

での使用の構造体の主題を理解していないと思いますが、私を助けて善良な人々:)で何

ください。これを動作させる最短の方法は?

答えて

1

コードをお送りください。 Springを使用するコールストアドプロシージャでは、StoredProcedureクラスを拡張する必要があります。あなたが完全なコードを送ったら、私はより良く助けることができます。サンプルの擬似コード:

class CustomStoredProcedure extends org.springframework.jdbc.object.StoredProcedure 
{ 
    CustomStoredProcedure() 
    { 
     super([your-data-source], [package-name]); 
     declareParameter(new SqlParameter([your-struct-name]), Types.STRUCT)); 
     compile(); 
    } 

    Map<String, Object> execute([your-parameter]) 
    { 
     return super.execute(inputs); 
    } 
} 

詳細については、完全な状況を説明してください。

+0

これは完全な状況です - 私はちょうどのEclipseLink JPA2.0の実装に共通の問題を解決する方法をテストしています。 BTA AFAIK SpringはJPAを実装していません - 間違っていますか? – czajah

+0

あなたは正しいと言いますが、SpringはJPAを実装していません。私はEclipseLinkを使用しません。私の解決策はjpaの実装から独立しています、それは春のフレームワークによって提供され、正しく動作します。 EclipseLinkのみを使用する場合は、そのドキュメントを読む必要があります。 – MJM

0

コードが正しいように見えます。

構造体に記述子が定義されていることを確認してください。 (すなわちsession.getDescrptor(TestStruct.class))

他のタイプのストアドプロシージャを呼び出すことはできますか?

どのデータベースを使用していますか?プラットフォームを正しくOracleに設定しましたか?

+0

"構造体に記述子が定義されていることを確認する"注釈のために記述子が自動的に作成されることを意味しますか?最近、私はそれらをマニュアルに設定しようとしました: 'ObjectRelationalDataTypeDescriptor d = new ObjectRelationalDataTypeDescriptor(); d.setJavaClass(TestStruct.class); d.descriptorIsAggregate(); d.setStructureName( "TEST_TYPE"); d。addDirectMapping( "TEST_FIELD"、 "getTestField"、 "setTestField"、 "testField"); d.setShouldOrderMappings(false); ((EntityManagerImpl)em.getDelegate())。getServerSession()。addDescriptor(d); ' – czajah

+0

私は、varcharのような単純な型のストアドプロシージャを呼び出すことができます。私はOracle 10と適切なJDBCドライバを使用しています。 – czajah

+0

記述子は注釈から作成する必要がありますが、persistence.xmlのクラスを特定していないか、それ以外の問題があった場合は、チェックすることをお勧めします。コードで定義したときに機能しましたか? – James

0

は、別のクラスによって参照されていない限り、@Structおよび@Embeddable注釈付きクラスの記述子をスキップしているようです。これを有効にする最短の方法は、この前提に基づいた回避策を使用することです。あなたのMETA-INF/persistence.xmlが配置されているジャーに追加のクラスを置く:

@Entity 
public class StructEntitiesWorkaround { 

    @Id 
    private String id; 

    private TestStruct testStruct; 

}