Hibernate: OutOfMemoryError persisting Blob when printing log message

蓝咒 提交于 2019-12-08 11:21:19

问题


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)

回答1:


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.




回答2:


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.




回答3:


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.




回答4:


What if you try the following two Hibernate properties?

hibernate.show_sql=false
hibernate.format_sql=false


来源:https://stackoverflow.com/questions/1750470/hibernate-outofmemoryerror-persisting-blob-when-printing-log-message

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!