2011-01-18 1 views
6

Ciao ho una routine Oracle memorizzatoCome chiamare la procedura memorizzata da sospensione?

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

resto tutti i parametri sono parametri OUT.

Nel file di HBM ho scritto -

<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> 

in Java ho scritto -

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

... continua fino a che tutti i parametes.

io sono sempre l'eccezione SQL

 
    18:29:33,056 WARN [JDBCExceptionReporter] SQL Error: 1006, SQLState: 72000 
    18:29:33,056 ERROR [JDBCExceptionReporter] ORA-01006: bind variable does not exist 

prega fatemi sapere cosa è il processo esatto di chiamare una stored procedure da Hibernate. Non voglio usare l'istruzione callable JDBC.

+0

Fare riferimento al [documento ufficiale] (http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Web_Platform/5/html/Hibernate_Core_Reference_Guide/sp_query.html) sull'utilizzo di stored procedure e limitazioni [qui] (http : //docs.redhat.com/docs/en-US/JBoss_Enterprise_Web_Platform/5/html/Hibernate_Core_Reference_Guide/sp_query.html) –

risposta

1

Con Hibernate è necessario applicare una classe risultato per trasformare i risultati SP in e i nomi delle colonne restituite devono essere aliasati nei campi di restituzione corretti nella classe risultato. Hibernate richiede che i proc memorizzati da SQLServer abbiano un unico risultato di ritorno e voglia sapere quale tipo di oggetto creare. Dove lavoro di solito restituiamo un risultato a riga singola di due colonne: return_code e message.

Per esempio ...

  • return_code = 404, message = "Pagina non trovata"

  • return_code = 200, message = "OK"

La classe è mappato come qualsiasi altro POJO, assicurati di renderlo Serializzabile. Ad esempio:

@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; 
    } 

} 

Mi sembra anche di ricordare un po 'di generale hokeyness in relazione alla convenzione di denominazione utilizzata da Hibernate. Penso che names_with_underscores siano tradotti per esempio in camelCaseFieldNames.

5

Quello che si sta tentando (gestione dei parametri INOUT/OUT) non è supportato in 4.1. Attraverso il supporto delle dichiarazioni callable di 4.1 di Hibernate si concentra sui ritorni ResultSet. Vi è il supporto per ciò che state provando già sul master upstream e farà parte della prossima versione principale di Hibernate (che sarà sia 4.2 che 5.0); lì, chiamare funzioni/procedure è ora un'operazione di prima classe.

Per ora, è necessario utilizzare direttamente JDBC o creare Hibernate dal master e utilizzare tale nuovo supporto. Se si opta per il successivo, sarebbe simile a:

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"); 
... 

Quel codice è ancora giovane e probabilmente cambierà.Ad esempio, mentre scrivo questi esempi più spesso, penso che registerStoredProcedureParameter debba essere rinominato come registerParameter o declareParameter e che debba restituire una rappresentazione tipizzata della dichiarazione/registrazione; qualcosa di simile:

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); 

che sarebbe quindi consentire:

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); 

Come bonus aggiuntivo, la gente provare questo presto arrivare per aiutare forma ciò che questo appare come prima di essere rilasciato (a quel punto è molto più difficile da cambiare).

+0

Devo chiarire quando dico che la gestione dei parametri INOUT/OUT non è attualmente supportata. Puoi infatti avere parametri INOUT/OUT, devono solo restituire ResultSet e puoi avere un solo parametro che restituisce risultati per chiamata. –

+0

Grazie per le informazioni fornite nella risposta, le funzionalità di cui sopra sono disponibili sull'ultima versione di ibernazione (4.3.6). Funziona perfettamente quando la stored procedure restituisce un set di risultati, ma più set di risultati sono problemi, potresti per favore indicare l'URL per la documentazione delle caratteristiche sopra. Non riesco a trovarlo su google –