Blob 写入 Oracle:大约 15% 被 \00 填充

发布于 2024-08-08 12:57:09 字数 1654 浏览 2 评论 0原文

在 Weblogic 10 下,我使用 Hibernate 将数据存储到多个带有 BLOB 的表中。它总是工作得很好,但客户发现了一些特定情况,其中 15% 的 BLOB 具有正确的大小,但只包含空字符。我不明白是什么让它变得美好或充满空虚。

我正在使用的 BLOB 类型执行以下操作:

public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
    if (value == null) {
        st.setNull(index, sqlTypes()[0]);
        return;
    }

    try {
        Connection conn = st.getConnection();
        if (conn instanceof org.apache.commons.dbcp.DelegatingConnection) {
            log.debug("Delegating connection, digging for actual driver");
            conn = ((org.apache.commons.dbcp.DelegatingConnection)st.getConnection()).getInnermostDelegate();
        }
        OutputStream tempBlobWriter = null;
        BLOB tempBlob = BLOB.createTemporary(conn, true, BLOB.DURATION_SESSION);
        try {
            tempBlob.open(BLOB.MODE_READWRITE);
            tempBlobWriter = tempBlob.setBinaryStream(1L);
            tempBlobWriter.write((byte[])value);
            tempBlobWriter.flush();
        } finally {
            if (tempBlobWriter != null)
                tempBlobWriter.close();
            tempBlob.close();
        }

        st.setBlob(index, (Blob) tempBlob);
    } catch (IOException e) {
        throw new HibernateException(e);
    }
}

我将日志放在那里并可以确认该值 (byte[]) 是正确的。我尝试更改createTemporary参数,但没有成功。

我在 Weblogic 10.0(无法升级)下使用捆绑的 Oracle Thin 驱动程序运行此程序。

线索是工作调用来自 WLS 部署和管理的标准 Web 服务。但是有问题的调用是从与某些带有 JNI 的遗留系统接口的组件一起启动的线程中完成的。除了这些 BLOB 之外,该线程对所有事物都具有魅力。我在插入数据之前得到一个新的会话,并在稍后关闭它。 (会话不会在线程的生命周期内保持打开状态)

我已将 Hibernate 日志级别设置为 DEBUG,但它没有给我任何线索。我开始没有想法了......

Under Weblogic 10, I am using Hibernate to store data into several tables with BLOBs. It's always worked fine but the customer found specific circumstances where 15% of the BLOBs have the correct size but only contain null characters. I can't figure out what makes it good or full of emptiness.

The BLOB type I am using does a:

public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
    if (value == null) {
        st.setNull(index, sqlTypes()[0]);
        return;
    }

    try {
        Connection conn = st.getConnection();
        if (conn instanceof org.apache.commons.dbcp.DelegatingConnection) {
            log.debug("Delegating connection, digging for actual driver");
            conn = ((org.apache.commons.dbcp.DelegatingConnection)st.getConnection()).getInnermostDelegate();
        }
        OutputStream tempBlobWriter = null;
        BLOB tempBlob = BLOB.createTemporary(conn, true, BLOB.DURATION_SESSION);
        try {
            tempBlob.open(BLOB.MODE_READWRITE);
            tempBlobWriter = tempBlob.setBinaryStream(1L);
            tempBlobWriter.write((byte[])value);
            tempBlobWriter.flush();
        } finally {
            if (tempBlobWriter != null)
                tempBlobWriter.close();
            tempBlob.close();
        }

        st.setBlob(index, (Blob) tempBlob);
    } catch (IOException e) {
        throw new HibernateException(e);
    }
}

I put a log in there and can confirm that the value (byte[]) is good. I tried to change the createTemporary parameters, no success.

I am running this under Weblogic 10.0 (can't upgrade that) with the bundled Oracle Thin driver.

A clue is that the working calls come from the standard web service deployed and managed by WLS. But the problematic calls are done from a thread started along with the component that interfaces with some legacy system with JNI. This thread works like a charm for everything except these BLOBs. I am getting a new Session just before inserting the data and closing it a bit after. (The Session does NOT remain open for the lifetime of the thread)

I have set the Hibernate log level to DEBUG but it does not give me any clue. I'm starting to run out of ideas...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

℡寂寞咖啡 2024-08-15 12:57:09

问题解决了。

事实上,我正在做:

  • open session
    • 开放交易
      • 从旧系统中获取第一个项目
      • 将第一项写入数据库(blob)
    • 结束交易
    • 开放交易
      • 从旧系统中获取第二项
      • 将第二项写入数据库(blob)
    • 结束交易
    • ...直到遗留系统不再需要处理
  • 关闭会话

这通常每轮处理 1 到 5 个项目。

但由于 Oracle 驱动程序不使用 JDBC 中处理 blob 的标准方法,因此我们的自定义类型必须创建一个存储在会话中的临时 blob。显然,当您在同一会话中的不同事务中插入 blob 时,它们往往会干扰并导致我的问题。

我通过在每次提交后关闭会话来解决这个问题。我不喜欢它,但我认为这是 Oracle 驱动程序的错误。

Problem solved.

In fact, I was doing:

  • open session
    • open transaction
      • get first item from legacy system
      • write first item to database (blob)
    • close transaction
    • open transaction
      • get second item from legacy system
      • write second item to database (blob)
    • close transaction
    • ... until the legacy system has nothing more to process
  • close session

This would typically process between 1 and 5 items per round.

But because the Oracle driver does not use the standard way of handling blobs in JDBC, our custom type has to create a temporary blob that is stored in the session. And apparently when you're inserting blobs in differents transactions within the same session, they tend to interfere and cause my problem.

I solved it by closing the session after each commit. I do not like it but I consider it being the Oracle driver's fault.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文