开发者

Hibernate: OutOfMemoryError persisting Blob when printing log message

开发者 https://www.devze.com 2022-12-11 12:35 出处:网络
I have a Hibernate Entity: @Entity class Foo { //... @Lob public byte[] getBytes() { return bytes; } //....

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(ByteArrayBlob开发者_运维问答Type.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 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.


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.


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.


What if you try the following two Hibernate properties?

hibernate.show_sql=false
hibernate.format_sql=false
0

精彩评论

暂无评论...
验证码 换一张
取 消