2011-01-18 17 views
6

Cześć Mam procedurę Oracle przechowywaneJak wywołać procedurę składowaną przez hibernację?

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

resztę wszystkie parametry są poza parametry.

W pliku HBM pisałem -

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

w Javie pisałem -

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

... dalej do wszystkich parametes.

otrzymuję sql wyjątku

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

Proszę dać mi znać, jaki jest dokładny proces wywoływania procedury przechowywanej z hibernacji. Nie chcę używać instrukcji wywoływalnej JDBC.

+0

Skorzystaj z ich [oficjalnego dokumentu] (http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Web_Platform/5/html/Hibernate_Core_Reference_Guide/sp_query.html) na temat korzystania z procedur i ograniczeń przechowywanych [tutaj] (http : //docs.redhat.com/docs/en-US/JBoss_Enterprise_Web_Platform/5/html/Hibernate_Core_Reference_Guide/sp_query.html) –

Odpowiedz

1

Hibernate trzeba zastosować klasę wynik przekształcenia wyników SP i nazwy kolumn, które zwracają muszą być aliasem do odpowiednich pól w obie strony w swojej klasie wynik. Hibernate chce SQLServer przechowywane procs mieć jeden wynik zwrotu i chce wiedzieć, jaki rodzaj obiektu do utworzenia. Gdzie pracuję zazwyczaj zwracamy wynik w postaci pojedynczego wiersza z dwiema kolumnami: return_code i message.

Na przykład ...

  • kod_powrotu = 404, message = "Nie znaleziono strony"

  • kod_powrotu = 200, message = "OK"

klasie jest odwzorowywany jak każdy inny POJO, tylko pamiętaj, aby nadać mu serializowalność. Na przykład:

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

} 

Wydaje mi się również, że przypominają pewną ogólną histerynę w odniesieniu do konwencji nazewnictwa używanej przez Hibernate. Myślę, że names_with_underscores są na przykład tłumaczone na camelCaseFieldNames.

5

Co próbujesz (INOUT/OUT obsługi parametrów) nie jest obsługiwane w 4.1. Poprzez obsługę instrukcji 4.1 Hibernate koncentruje się na zwrotach ResultSet. Istnieje wsparcie dla tego, co próbujesz już wprowadzić na serwerze głównym i będzie częścią następnej głównej wersji Hibernate (która będzie 4.2 lub 5.0); tam wywoływanie funkcji/procedur jest teraz operacją pierwszej klasy.

Teraz trzeba użyć JDBC bezpośrednio lub zbudować Hibernate od pana i wykorzystać te nowe wsparcie. Jeśli wybierzesz opcję późniejszą, będzie wyglądać następująco:

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

Ten kod jest wciąż młody i prawdopodobnie ulegnie zmianie.Na przykład, kiedy piszę te przykłady częściej, myślę, że registerStoredProcedureParameter powinna zostać przemianowana na registerParameter lub declareParameter i że powinna zwrócić typową reprezentację deklaracji/rejestracji; coś takiego:

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

które następnie umożliwiają:

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

Jako dodatkowy bonus, ludzie próbują to wcześnie uzyskać pomoc kształt, jak to wygląda przed nią jest zwolniony (w którym momencie go jest o wiele trudniej zmienić).

+0

Powinienem wyjaśnić, kiedy mówię o obsłudze parametrów INOUT/OUT aktualnie nieobsługiwanych. Możesz w rzeczywistości mieć parametry INOUT/OUT, po prostu muszą zwracać ResultSets i możesz mieć tylko jeden parametr zwracający wyniki dla każdego połączenia. –

+0

Dzięki za informacje zawarte w odpowiedzi, Wydaje się, że wyżej wymienione funkcje są dostępne w najnowszej wersji systemu hibernacji (4.3.6). Działa to doskonale, gdy procedura składowana zwraca jeden zestaw wyników, ale wiele zestawów wyników są problemy, może wskazać adres URL dla powyższej dokumentacji funkcji. Nie mogę znaleźć w Google. –

Powiązane problemy