簡體   English   中英

如何在Hibernate中調用存儲過程?

[英]How to call a stored procedure in Hibernate?

我在Oracle數據庫中有一個存儲過程。

GET_VENDOR_STATUS_COUNT(DOCUMENT_ID IN NUMBER, NOT_INVITED OUT NUMBER, INVITE_WITHDRAWN OUT NUMBER, ...

其他參數是OUT參數。

在我的hbm文件中,我寫了以下內容:

<sql-query name="getVendorStatus" callable="true">
     <return-scalar column="NOT_INVITED" type="string"/>
     <return-scalar column="INVITE_WITHDRAWN" type="string"/>
     <return-scalar column="INVITED" type="string"/>
     <return-scalar column="DISQUALIFIED" type="string"/>
     <return-scalar column="RESPONSE_AWAITED" type="string"/>
     <return-scalar column="RESPONSE_IN_PROGRESS" type="string"/>
     <return-scalar column="RESPONSE_RECEIVED" type="string"/>
     { call GET_VENDOR_STATUS_COUNT(:DOCUMENT_ID , :NOT_INVITED ,:INVITE_WITHDRAWN ,:INVITED ,:DISQUALIFIED ,:RESPONSE_AWAITED ,:RESPONSE_IN_PROGRESS ,:RESPONSE_RECEIVED ) }
</sql-query>

這是我的Java代碼:

 session.getNamedQuery("getVendorStatus").setParameter("DOCUMENT_ID", "DOCUMENT_ID").setParameter("NOT_INVITED", "NOT_INVITED") 

...繼續直到所有參數。

我收到以下SQL異常:

18:29:33,056 WARN [JDBCExceptionReporter] SQL錯誤:1006,SQLState:72000
18:29:33,056錯誤[JDBCExceptionReporter] ORA-01006:綁定變量不存在


請讓我知道在Hibernate中調用存儲過程的確切過程是什么? 我不想使用JDBC可調用語句。

4.1不支持您嘗試的操作(INOUT / OUT參數處理)。 通過4.1 Hibernate的可調用語句支持着重於ResultSet返回。 上游母版已經支持您正在嘗試的內容,並且將成為Hibernate的下一個主要版本(版本為4.2或5.0)的一部分; 在那里,調用函數/過程現在是一流的操作。

現在,您必須直接使用JDBC或通過master來構建Hibernate並使用該新支持。 如果選擇后者,它將看起來像:

StoredProcedureCall call = session.createStoredProcedureCall( "GET_VENDOR_STATUS_COUNT" )
        .registerStoredProcedureParameter( "DOCUMENT_ID", Long.class, ParameterMode.IN )
        .registerStoredProcedureParameter( "NOT_INVITED", String.class, ParameterMode.OUT )
        ...;
call.getRegisteredParameter( "DOCUMENT_ID" ).bindValue( theDocumentId );
StoredProcedureOutputs outputs = call.getOutputs();
String notInvited = (String) outputs.getOutputParameterValue( "NOT_INVITED" );
...

該代碼還很年輕,可能會更改。 例如,當我更頻繁地編寫這些示例時,我認為registerStoredProcedureParameter應該重命名為registerParameterdeclareParameter ,並且它應該返回聲明/注冊的類型化表示形式。 就像是:

interface RegisteredParameter<T> {
    Class<T> getParameterType();
    // only valid for IN or INOUT params
    void bindValue(T value);
}

<T> RegisteredParameter<T> registerParameter(String name, Class<T> type, ParameterMode mode);

這將允許:

StoredProcedureCall call = session.createStoredProcedureCall( "GET_VENDOR_STATUS_COUNT" )
call.registerParameter( "DOCUMENT_ID", Long.class, ParameterMode.IN ).bindValue( theDocumentId );
RegisteredParameter<String> notInvitedParam = call.registerParameter( "NOT_INVITED", String.class, ParameterMode.OUT );
...
String notInvited = outputs.getOutputParameterValue( notInvitedParam );

另外一個好處是,盡早嘗試此方法的人可以在發布它之前幫助塑造它的外觀(此時很難更改)。

使用Hibernate,您必須應用結果類將SP結果轉換為結果,並且返回的列的名稱必須別名為結果類中正確的返回字段。 Hibernate希望SQLServer存儲的proc具有單個返回結果,並且它想知道要創建哪種Object。 在我工作的地方,我們通常返回兩列的單行結果:return_code和message。

例如...

  • return_code = 404,消息=“找不到頁面”

  • return_code = 200,消息=“確定”

像其他任何POJO一樣映射該類,只需確保使其可序列化即可。 例如:

@Entity
public class StoredProc implements Serializable {

  private Integer returnCode;
  private String message;

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "return_code", nullable = false, unique = true)
  public Integer getReturnCode() {
    return returnCode;
  }
  public void setReturnCode(Integer returnCode) {
    this.returnCode = returnCode;
  }

  @Column(name = "message")
  public String getMessage() {
    return message;
  }
  public void setMessage(String message) {
    this.message = message;
  }

}

我似乎還想起了有關Hibernate使用的命名約定的一些一般技巧。 例如,我認為names_with_underscores會轉換為camelCaseFieldNames。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM