Hibernate:打印日志消息时出现 OutOfMemoryError 持久化 Blob

发布于 2024-08-12 02:55:21 字数 1263 浏览 3 评论 0原文

我有一个 Hibernate 实体:

@Entity
class Foo {
    //...
    @Lob
    public byte[] getBytes() { return bytes; }
    //....
}

我的 VM 配置的最大堆大小为 512 MB。当我尝试保留一个具有 75 MB 大对象的对象时,我收到 OutOfMemoryError。

堆栈跟踪中的方法名称(StringBuilder、ByteArrayBlobType.toLoggableString、pretty.Printer.toString)表明 hibernate 正在尝试写入包含我的对象的非常大的日志消息。

我关于休眠使用这么多内存的原因正确吗?解决这个问题最简单的方法是什么?

java.lang.OutOfMemoryError: Java heap space
at java.lang.AbstractStringBuilder.<init>(AbstractStringBuilder.java:44)
at java.lang.StringBuilder.<init>(StringBuilder.java:81)
at org.hibernate.type.ByteArrayBlobType.toString(ByteArrayBlobType.java:117)
at org.hibernate.type.ByteArrayBlobType.toLoggableString(ByteArrayBlobType.java:127)
at org.hibernate.pretty.Printer.toString(Printer.java:53)
at org.hibernate.pretty.Printer.toString(Printer.java:90)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:97)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.jboss.seam.persistence.HibernateSessionProxy.flush(HibernateSessionProxy.java:181)

I have a Hibernate Entity:

@Entity
class Foo {
    //...
    @Lob
    public byte[] getBytes() { return bytes; }
    //....
}

My VM is configured with a maximum heap size of 512 MB. When I try to persist an object which has a 75 MB large object, I get an OutOfMemoryError.

The names of the methods in the stack trace (StringBuilder, ByteArrayBlobType.toLoggableString, pretty.Printer.toString) suggest that hibernate is trying to write a very large log message that contains my object.

Am I correct about why hibernate is using so much memory? What is the simplest way to work around this problem?

java.lang.OutOfMemoryError: Java heap space
at java.lang.AbstractStringBuilder.<init>(AbstractStringBuilder.java:44)
at java.lang.StringBuilder.<init>(StringBuilder.java:81)
at org.hibernate.type.ByteArrayBlobType.toString(ByteArrayBlobType.java:117)
at org.hibernate.type.ByteArrayBlobType.toLoggableString(ByteArrayBlobType.java:127)
at org.hibernate.pretty.Printer.toString(Printer.java:53)
at org.hibernate.pretty.Printer.toString(Printer.java:90)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:97)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.jboss.seam.persistence.HibernateSessionProxy.flush(HibernateSessionProxy.java:181)

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

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

发布评论

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

评论(4

一杯敬自由 2024-08-19 02:55:21

我解决了这个问题。关闭日志记录确实解决了问题,但我不明白,当在 JBoss 应用程序服务器下运行时,服务器自己的 log4j.xml 文件会覆盖我在应用程序的类路径中放置的任何内容。

我打开 /jboss-4.2.3.GA/server/default/conf/log4.xml,并插入以下内容:

<category name="org.hibernate">
    <priority value="ERROR"/>
</category>

这解决了我所看到的问题。

I solved the problem. Turning off logging did fix the problem, but I didn't understand that when running under the JBoss application server, the server's own log4j.xml file overrides whatever I put the in classpath of the application.

I opened up /jboss-4.2.3.GA/server/default/conf/log4.xml, and inserted this:

<category name="org.hibernate">
    <priority value="ERROR"/>
</category>

This fixes the issue I am seeing.

落叶缤纷 2024-08-19 02:55:21

第一个测试是看看这是否确实是日志记录问题。您使用什么记录器?如果是 log4j,那么您可以尝试在 log4j.properties 文件中使用以下行来关闭 Hibernate 的所有日志记录:

log4j.logger.org.hibernate=关闭

这可能不是您的应用程序运行的最终、理想的方式,但它可能会帮助您测试日志记录是否是问题所在。

The first test is to see if it really is a logging issue. What logger are you using? If it's log4j, then you can try to turn off all logging from Hibernate with the following line in your log4j.properties file:

log4j.logger.org.hibernate=OFF

That might not be the ultimate, ideal way for your app to operate, but it might help you test whether logging is the issue.

自此以后,行同陌路 2024-08-19 02:55:21

漂亮的打印机可能会将字节转换为十六进制表示法(例如“0x55 0xF3 ...)”,因此对于 blob 中的每个字节,您将获得 4 个字节的输出,因此 300M 的输出,以及缓冲,以及 VM 中的其他内容可能会让你超出极限。

The pretty printer is probably converting the bytes to hex notation (e.g. '0x55 0xF3 ...)', so for each byte in the blob you get 4 bytes of output so 300M of output, that and buffering, with other stuff in your VM probably puts you over the limit.

骄傲 2024-08-19 02:55:21

如果您尝试以下两个 Hibernate 属性会怎样?

hibernate.show_sql=false
hibernate.format_sql=false

What if you try the following two Hibernate properties?

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