Hibernate Сохраненные результаты процедуры - PullRequest
4 голосов
/ 02 июня 2010

Я вынужден управлять полем автоинкремента из кода. Я решил написать хранимую процедуру, чтобы сделать это для меня. Идея состоит в том, чтобы иметь процедуру, которая вставляет новую строку и возвращает автоматически увеличенное значение Java, чтобы я мог работать с ним дальше. Вот что я имею до сих пор. Я не знаю, что изменить, чтобы заполнить пробелы, чтобы все это заработало.

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE addNewMSO
    @sourceApplication char(8), 
    @selectionStatusDate datetime = NULL,
    @sysLstUpdtUserId char(10)
AS
BEGIN
    SET NOCOUNT ON;

    Declare @newVal int
    SET @newVal = (select max(seqNo) from MemberSelectedOptions) + 1

    INSERT INTO MemberSelectedOptions
       ([SourceApplication]
       ,[SeqNo]
       ,[SelectionStatusDate]
       ,[SysLstUpdtUserId])
 VALUES
      (@sourceApplication
       ,@newVal
       ,@selectionStatusDate
       ,@sysLstUpdtUserId)

END
GO

Тогда в моем коде Java есть следующее.

@NamedNativeQuery(name="addNewMSO", 
  query="exec addNewMSO :sourceApplication :selectionStatusDate :sysLstUpdtUserId", callable=true)

И мой DAO называет это так ...

Query q = session.getNamedQuery("addNewMSO");
q.setParameter("sourceApplication", mso.getSourceApplication());
q.setParameter("selectionStatusDate", mso.getSelectionStatusDate());
q.setParameter("sysLstUpdtUserId", mso.getSysLstUpdtUserId());
q.executeUpdate();

Даже в этом случае это не работает, потому что я получаю ошибку «Чистые собственные скалярные запросы еще не поддерживаются». Поэтому я понятия не имею, куда идти дальше. Я прочитал документы Hibernate, но я не знаю, как получить возвращаемое значение от SP. Но я до сих пор не могу даже назвать это ... тьфу!

TIA для всех помощи.

Ответы [ 2 ]

5 голосов
/ 02 июня 2010

Если ваш SP не возвращает набор результатов, то, боюсь, вам придется использовать session.getConnection() и сырой JDBC. Согласно документации Hibernate:

16.2.2. Использование хранимых процедур для запроса

Hibernate3 обеспечивает поддержку запросы с помощью хранимых процедур и функции. Большинство из следующих документация эквивалентна для обоих. Хранимая процедура / функция должна возвращать набор результатов как первый выходной параметр, чтобы иметь возможность работать с Hibernate . (...)

16.2.2.1. Правила / ограничения для использования хранимых процедур

Вы не можете использовать хранимые процедуры с Hibernate, если вы не следуете некоторым правила процедуры / функции. Если они это сделают не следовать этим правилам, они не можно использовать с Hibernate. Если ты еще хотите использовать эти процедуры у вас есть выполнить их через session.connection(). Правила отличается для каждой базы данных, так как поставщики базы данных имеют разные хранятся семантика / синтаксис процедуры.

Запросы хранимых процедур не могут быть разбит на страницы с setFirstResult()/setMaxResults().

Рекомендуемая форма звонка стандартная SQL92: { ? = call functionName(<parameters>) } или { ? = call procedureName(<parameters>}. Собственный синтаксис вызова не поддерживается.

(...)

Для сервера Sybase или MS SQL применяются следующие правила:

  • Процедура должна возвращать набор результатов. Обратите внимание, что поскольку эти серверы могут вернуть несколько результирующих наборов и обновить рассчитывает, Hibernate будет повторять результаты и принять первый результат, который является результатом набора в качестве возвращаемого значения. Все остальное будет отброшено.
  • Если вы можете включить SET NOCOUNT ON в вашей процедуре, это, вероятно, будет более эффективным, но это не требование.
0 голосов
/ 04 июня 2010

Отказ от ответственности: Я НИКОГДА не знаком ни с HIBERNATE, ни с Java, но из того, что я прочитал выше, вам, похоже, нужен хотя бы один набор результатов, чтобы это работало !? Учитывая тег SQL-2005, я предполагаю, что ваш код написан на T-SQL, поэтому я хотел бы отметить, что ваш код «некорректен» в том отношении, что он МОЖЕТ (да, очень малый шанс, но все же) случиться что другое соединение вставляет новую запись в таблицу между моментом выбора @newval и моментом фактической вставки. Эту проблему можно решить, используя блокировку, или IMHO, проще, поместив INSERT и SELECT в одну инструкцию. Добавление ISNULL () также гарантирует, что если вам когда-нибудь понадобится перезапустить с пустой таблицей, хранимая процедура все равно будет функционировать, как и ожидалось, даже если у нее нет начального значения для добавления.

CREATE PROCEDURE addNewMSO
@sourceApplication char(8), 
@selectionStatusDate datetime = NULL,
@sysLstUpdtUserId char(10)
AS
BEGIN
SET NOCOUNT ON;

INSERT INTO MemberSelectedOptions
   ([SourceApplication]
   ,[SeqNo]
   ,[SelectionStatusDate]
   ,[SysLstUpdtUserId])
OUTPUT (inserted.[SeqNo])
 SELECT [SourceApplication]   = @sourceApplication,
    [SeqNo]               = ISNULL((SELECT max([SeqNo]) FROM MemberSelectedOptions), 0) + 1,
    [SelectionStatusDate] = @selectionStatusDate,
    [SysLstUpdtUserId]    = @sysLstUpdtUserId
END

Предложение OUTPUT вернет вновь вставленное значение в наборе записей, которое, если я правильно понимаю ограничения HIBERNATE, поможет вам как на , что поддерживается , так и , что необходимо .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...