Получение oracle XMLType, хранящегося в виде двоичного XML, из набора результатов в Java

Я описал решение для записи/чтения в столбец Oracle XMLType для Oracle 11g (в частности, 11.2.0.1), если столбец XMLType хранится как CLOB, что является значением по умолчанию для 11.2.0.1.

ССЫЛКА ОТВЕТ: Использование oracle XMLType в сценарии спящего режима java spring < /а>

В SQLDeveloper, если вы просматриваете вкладку SQL в определении таблицы (таблица DDL), она определяет хранилище столбцов XML в 11.2.0.1 следующим образом:

 XMLTYPE COLUMN "ATTRIBUTE_XML2" STORE AS BASICFILE CLOB 

Проблема. В Oracle 11.2.0.2 типом хранения по умолчанию для XMLType является Binary XML, который предпочтительнее из соображений производительности. Это выглядит так:

XMLTYPE COLUMN "ATTRIBUTE_XML2" STORE AS SECUREFILE BINARY XML

ОДНАКО, когда-то сохраненное таким образом, мое упомянутое решение больше не работает для ЧТЕНИЯ столбца XMLType как XML из базы данных. Он возвращает какой-то мусор из xmlType.getStringVal(), который, как я предполагаю, является двоичным кодом XML оракула.

Основная проблема. Я не могу обратно преобразовать формат oracle binxml в допустимый XML-документ.

Я пробовал Oracle BinXMLProcessor, BinXMLStream, BinXMLDecoder и InfosetReader в различные конфигурации, описанные Oracle, но они, похоже, просто читают, а не декодируют его, поэтому возникают ошибки.

Базовый пример в nullSafeGet (см. связанный ответ для контекста).

xmlType = (XMLType) rs.getObject(names[0]);
BinXMLProcessor xp = BinXMLProcessorFactory.createProcessor();
BinXMLStream bstr = xp.createBinXMLStream(xmlType.getInputStream());
BinXMLDecoder xdecode = bstr.getDecoder();
InfosetReader reader = xdecode.getReader();

while (reader.hasNext() && i < 25) {
    i++;
    reader.next();
    logger.debug("1 v:" + reader.getValue() + ", s:" + reader.getStandalone() + ", type: " + reader.getEventType() + ", " + reader.getDataLength());
}

Я пробовал аналогичные подходы, заменяя xmlType.getInputStream() на xmlType.getBlobVal(178), xmlType.getBytesValue(), но все они выдают исключение или возвращают мусорные данные.

Хм.


person Matt M    schedule 29.08.2013    source источник


Ответы (1)


Нашел подвох, и он не связан с кодом.

Правильный nullSafeGet в пользовательском типе Hibernate, как указано в указанном ответе:

public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {

    if (logger.isTraceEnabled()) {
        logger.trace("  nullSafeSet: " + value + ", ps: " + st + ", index: " + index);
    }
    try {
        XMLType xmlType = null;
        if (value != null) {
            xmlType = XMLType.createXML(getOracleConnection(st.getConnection()), (String)value);
        }
        st.setObject(index, xmlType);
    } catch (Exception e) {
        throw new SQLException("Could not convert String to XML for storage: " + (String)value);
    }
}

ПРОБЛЕМА: при использовании столбца SECUREFILE BINARY XML (не CLOB) необходимо использовать самый последний (11.2.0.2+) дистрибутив xdb*.jar, которым в данном случае является xdb6.jar (~ 257кб). Более ранний xdb*.jar (~136 КБ для 10.x) по-прежнему будет работать без каких-либо исключений даже при неправильном декодировании BINARY XML.

TL;DR: Загрузить xdb6 .jar (~257 КБ) со страницы драйверов JDBC для Oracle 11gR2 (11.2.0.3). Старые банки xdb молча терпят неудачу и заставят вас грустить.

person Matt M    schedule 29.08.2013