4

我被迫进入使用休眠 createNativeQuery 返回对象数组列表的情况。

我的查询从中返回值的(许多)列之一是 CLOB。

返回的 Object 是 com.sun.Proxy 对象。

在这里 看到了一个问题

getClass().getInterfaces()

用于标识它是一个被返回的 WrappedClob。

但是,鉴于我现在在我的 Java 代码中有这个代理对象,我如何将它转换成有用的东西……比如字符串?

4

3 回答 3

7

以下代码有助于取消代理 clob

链接对我有帮助,只需在代码中添加一点妆容 :D

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Clob;
import java.sql.SQLException;
    /**
         * Unproxy clob.
         *
         * @param proxy the proxy
         * @return the string
         * @throws InvocationTargetException the invocation target exception
         * @throws IntrospectionException the introspection exception
         * @throws IllegalAccessException the illegal access exception
         * @throws SQLException the SQL exception
         * @throws IOException Signals that an I/O exception has occurred.
         */
        public static String unproxyClob(Object proxy)
            throws InvocationTargetException, IntrospectionException, IllegalAccessException, SQLException, IOException {
            try {
                BeanInfo beanInfo = Introspector.getBeanInfo(proxy.getClass());
                for (PropertyDescriptor property : beanInfo.getPropertyDescriptors()) {
                    Method readMethod = property.getReadMethod();
                    if (readMethod.getName().contains(GET_WRAPPED_CLOB)) {
                        Object result = readMethod.invoke(proxy);
                        return clobToString((Clob) result);
                    }
                }
            } catch (InvocationTargetException | IntrospectionException | IllegalAccessException | SQLException | IOException exception) {
                LOGGER.fatal(exception);
                throw exception;
            }
            return null;
        }

        /**
         * Clob to string.
         *
         * @param data the data
         * @return the string
         * @throws SQLException the SQL exception
         * @throws IOException Signals that an I/O exception has occurred.
         */
        public static String clobToString(Clob data) throws SQLException, IOException {
            StringBuilder sb = new StringBuilder();
            Reader reader = data.getCharacterStream();
            BufferedReader br = new BufferedReader(reader);
            String line;
            while (null != (line = br.readLine())) {
                sb.append(line);
            }
            br.close();

            return sb.toString();
        }
于 2016-10-27T12:12:11.627 回答
0

你可以试试这段代码。可能它并不完美,但它对我有用:) 我正在使用它将常规 clob 转换为字符串,因此如果您使用 getWrappedClob() 解开 clob 对象,它也应该可以工作

Clob clob = wrappedClob.getWrappedClob();
String result = null;
Long length = clob.length();
char[] char_array = new char[length.intValue()];
Reader characterStream = clob.getCharacterStream();
try {
    int read = characterStream.read(char_array, 0, length.intValue());
    result = new String(char_array);
} catch (IOException e) {
    log.error("Exception during read from CLOB: " + e);
}
于 2015-06-02T10:02:57.120 回答
0

这不是对 OP 问题的直接回答,因为我不必处理“WrappedClob”的实例。但由于我仍然收到相同的误导性错误消息,我希望有人觉得这很有用:

对我来说,问题是,H2 和 Postgres 的“Clob to String”的休眠实现方式不同。因此,虽然我的测试运行良好,但应用程序会在运行时崩溃。为了解决这个问题,我在不同的环境中实例化了不同的 ClobReader bean。生产环境将使用 Postgres 的 bean 实现,而测试代码使用 H2 bean。

public interface ClobReader {
    String clobToString(Object clob) throws SQLException, IOException;
}


@Bean
public ClobReader clobReaderPostgres() {
    return new ClobReader() {
        @Override
        public String clobToString(final Object clob) {
            if (clob == null) {
                return null;
            }
            return clob.toString();
        }
    };
}


@Bean
@Primary
public ClobReader clobReaderH2() {
    return new ClobReader() {
        @Override
        public String clobToString(final Object obj) throws SQLException, IOException {
            final Clob clob = (Clob) obj;
            try (final Reader reader = clob.getCharacterStream()) {
                try (final StringWriter stringWriter = new StringWriter()) {
                    IOUtils.copy(reader, stringWriter);
                    return stringWriter.toString();
                }
            }
        }
    };
}
于 2021-01-15T16:57:02.603 回答