[{"data":1,"prerenderedAt":636},["ShallowReactive",2],{"post:redirecting-hibernate-logs":3},{"id":4,"title":5,"body":6,"date":622,"description":623,"draft":624,"extension":625,"meta":626,"navigation":455,"path":627,"seo":628,"stem":629,"tags":630,"__hash__":635},"posts\u002Fposts\u002Fredirecting-hibernate-logs.md","Redirecting Hibernate Logs to the CommandBox Console",{"type":7,"value":8,"toc":620},"minimark",[9,19,31,47,50,118,125,135,178,195,205,289,292,307,310,583,594,597,613,616],[10,11,12,13,18],"p",{},"In my last blog post, I covered ",[14,15,17],"a",{"href":16},"\u002Fposts\u002Fhibernate-logger-concurrent-exception\u002F","how to adjust the Hibernate log level with Log4j",".",[10,20,21,22,26,27,30],{},"This helped us avoid a concurrent modification exception due to logging certain database entities with the ",[23,24,25],"code",{},"DEBUG"," logger, but it also sets us up for further interaction with log4j configuration. This week we're going a step farther to take all log4j messages emitted by the HIbernate logger and redirect them to the console. This console is what is shown when you run ",[23,28,29],{},"box server log --follow"," in CommandBox.",[32,33,34],"blockquote",{},[10,35,36],{},[37,38,39,40,46],"em",{},"Not sure what Log4j is? ",[14,41,45],{"href":42,"rel":43},"https:\u002F\u002Ftwitter.com\u002Fmichaelborn_me",[44],"nofollow","Tweet at me"," and I'll happily cover basic Log4j usage in a blog post.",[10,48,49],{},"To begin, we need a Log4j \"Logger\" object which we can use to grab the Hibernate logger.",[51,52,57],"pre",{"className":53,"code":54,"language":55,"meta":56,"style":56},"language-js shiki shiki-themes github-light github-dark","var Logger = createObject( \"java\", \"org.apache.log4j.Logger\" );\nvar hibernateLog = Logger.getLogger( \"org.hibernate\" );\n","js","",[23,58,59,95],{"__ignoreMap":56},[60,61,64,68,72,75,79,82,86,89,92],"span",{"class":62,"line":63},"line",1,[60,65,67],{"class":66},"szBVR","var",[60,69,71],{"class":70},"sVt8B"," Logger ",[60,73,74],{"class":66},"=",[60,76,78],{"class":77},"sScJk"," createObject",[60,80,81],{"class":70},"( ",[60,83,85],{"class":84},"sZZnC","\"java\"",[60,87,88],{"class":70},", ",[60,90,91],{"class":84},"\"org.apache.log4j.Logger\"",[60,93,94],{"class":70}," );\n",[60,96,98,100,103,105,108,111,113,116],{"class":62,"line":97},2,[60,99,67],{"class":66},[60,101,102],{"class":70}," hibernateLog ",[60,104,74],{"class":66},[60,106,107],{"class":70}," Logger.",[60,109,110],{"class":77},"getLogger",[60,112,81],{"class":70},[60,114,115],{"class":84},"\"org.hibernate\"",[60,117,94],{"class":70},[10,119,120,121,124],{},"Our ",[23,122,123],{},"log"," variable now contains a reference to the root hibernate logger. All log messages emitted from any class in Hibernate will pass through this logger.",[10,126,127,128,131,132,134],{},"We can set the logging level - for development, we may want ",[23,129,130],{},"WARN"," or ",[23,133,25],{},":",[51,136,138],{"className":53,"code":137,"language":55,"meta":56,"style":56},"var level = createObject( \"java\", \"org.apache.log4j.Level\" );\nhibernateLog.setLevel( level.DEBUG );\n",[23,139,140,162],{"__ignoreMap":56},[60,141,142,144,147,149,151,153,155,157,160],{"class":62,"line":63},[60,143,67],{"class":66},[60,145,146],{"class":70}," level ",[60,148,74],{"class":66},[60,150,78],{"class":77},[60,152,81],{"class":70},[60,154,85],{"class":84},[60,156,88],{"class":70},[60,158,159],{"class":84},"\"org.apache.log4j.Level\"",[60,161,94],{"class":70},[60,163,164,167,170,173,176],{"class":62,"line":97},[60,165,166],{"class":70},"hibernateLog.",[60,168,169],{"class":77},"setLevel",[60,171,172],{"class":70},"( level.",[60,174,25],{"class":175},"sj4cs",[60,177,94],{"class":70},[10,179,180],{},[37,181,182,186,187,189,190,18],{},[183,184,185],"strong",{},"Note:"," Be aware that the ",[23,188,25],{}," log level may cause issues on entity save - see ",[14,191,194],{"href":192,"rel":193},"https:\u002F\u002Fmichaelborn.me\u002Fentry\u002Fresolving-concurrent-exceptions-in-hibernate-logger",[44],"Resolving Concurrent Exceptions in Hibernate Logger",[10,196,197,198,201,202,18],{},"Now that we have the logger we can reuse one of Lucee's existing log4j appenders to configure log output. This is basically piggybacking on Lucee to pass all ",[23,199,200],{},"org.hibernate"," logs through the \"console\" appender to ",[23,203,204],{},"System.Out",[51,206,208],{"className":53,"code":207,"language":55,"meta":56,"style":56},"var printWriter = getPageContext().getConfig().getOutWriter();\nvar layout = createObject( \"java\", \"lucee.commons.io.log.log4j.layout.ClassicLayout\");\nvar consoleAppender = createObject( \"java\", \"lucee.commons.io.log.log4j.appender.ConsoleAppender\" ).init( printWriter, layout );\n",[23,209,210,236,259],{"__ignoreMap":56},[60,211,212,214,217,219,222,225,228,230,233],{"class":62,"line":63},[60,213,67],{"class":66},[60,215,216],{"class":70}," printWriter ",[60,218,74],{"class":66},[60,220,221],{"class":77}," getPageContext",[60,223,224],{"class":70},"().",[60,226,227],{"class":77},"getConfig",[60,229,224],{"class":70},[60,231,232],{"class":77},"getOutWriter",[60,234,235],{"class":70},"();\n",[60,237,238,240,243,245,247,249,251,253,256],{"class":62,"line":97},[60,239,67],{"class":66},[60,241,242],{"class":70}," layout ",[60,244,74],{"class":66},[60,246,78],{"class":77},[60,248,81],{"class":70},[60,250,85],{"class":84},[60,252,88],{"class":70},[60,254,255],{"class":84},"\"lucee.commons.io.log.log4j.layout.ClassicLayout\"",[60,257,258],{"class":70},");\n",[60,260,262,264,267,269,271,273,275,277,280,283,286],{"class":62,"line":261},3,[60,263,67],{"class":66},[60,265,266],{"class":70}," consoleAppender ",[60,268,74],{"class":66},[60,270,78],{"class":77},[60,272,81],{"class":70},[60,274,85],{"class":84},[60,276,88],{"class":70},[60,278,279],{"class":84},"\"lucee.commons.io.log.log4j.appender.ConsoleAppender\"",[60,281,282],{"class":70}," ).",[60,284,285],{"class":77},"init",[60,287,288],{"class":70},"( printWriter, layout );\n",[10,290,291],{},"Then finally, we can tell log4j to use Lucee's console appender for all Hibernate logs:",[51,293,295],{"className":53,"code":294,"language":55,"meta":56,"style":56},"hibernateLog.addAppender( consoleAppender );\n",[23,296,297],{"__ignoreMap":56},[60,298,299,301,304],{"class":62,"line":63},[60,300,166],{"class":70},[60,302,303],{"class":77},"addAppender",[60,305,306],{"class":70},"( consoleAppender );\n",[10,308,309],{},"Put it all together, and here's what you get:",[51,311,313],{"className":53,"code":312,"language":55,"meta":56,"style":56},"public function setHibernateLogging(){\n  \u002F**\n   * Resolves Hibernate ConcurrentModificationException when flushing an entity save with one-to-many relationships.\n   * \n   * @see https:\u002F\u002Faccess.redhat.com\u002Fsolutions\u002F29774\n   * @see https:\u002F\u002Fmichaelborn.me\u002Fentry\u002Fresolving-concurrent-exceptions-in-hibernate-logger\n   *\u002F\n  var Logger = createObject( \"java\", \"org.apache.log4j.Logger\" );\n  var level = createObject( \"java\", \"org.apache.log4j.Level\" );\n  var hibernateLog = Logger.getLogger( \"org.hibernate\" );\n  hibernateLog.setLevel( level.WARN );\n\n  \u002F**\n   * Redirect all Hibernate logs to system.out\n   *\u002F\n  if ( listFindNoCase( \"Lucee\", server.coldfusion.productname ) ) {\n    var printWriter = getPageContext().getConfig().getOutWriter();\n    var layout = createObject( \"java\", \"lucee.commons.io.log.log4j.layout.ClassicLayout\");\n    var consoleAppender = createObject( \"java\", \"lucee.commons.io.log.log4j.appender.ConsoleAppender\" ).init( printWriter, layout );\n    hibernateLog.addAppender( consoleAppender );\n  }\n}\n",[23,314,315,329,335,340,346,358,368,374,396,417,436,450,457,462,468,473,493,515,536,561,571,577],{"__ignoreMap":56},[60,316,317,320,323,326],{"class":62,"line":63},[60,318,319],{"class":70},"public ",[60,321,322],{"class":66},"function",[60,324,325],{"class":77}," setHibernateLogging",[60,327,328],{"class":70},"(){\n",[60,330,331],{"class":62,"line":97},[60,332,334],{"class":333},"sJ8bj","  \u002F**\n",[60,336,337],{"class":62,"line":261},[60,338,339],{"class":333},"   * Resolves Hibernate ConcurrentModificationException when flushing an entity save with one-to-many relationships.\n",[60,341,343],{"class":62,"line":342},4,[60,344,345],{"class":333},"   * \n",[60,347,349,352,355],{"class":62,"line":348},5,[60,350,351],{"class":333},"   * ",[60,353,354],{"class":66},"@see",[60,356,357],{"class":70}," https:\u002F\u002Faccess.redhat.com\u002Fsolutions\u002F29774\n",[60,359,361,363,365],{"class":62,"line":360},6,[60,362,351],{"class":333},[60,364,354],{"class":66},[60,366,367],{"class":70}," https:\u002F\u002Fmichaelborn.me\u002Fentry\u002Fresolving-concurrent-exceptions-in-hibernate-logger\n",[60,369,371],{"class":62,"line":370},7,[60,372,373],{"class":333},"   *\u002F\n",[60,375,377,380,382,384,386,388,390,392,394],{"class":62,"line":376},8,[60,378,379],{"class":66},"  var",[60,381,71],{"class":70},[60,383,74],{"class":66},[60,385,78],{"class":77},[60,387,81],{"class":70},[60,389,85],{"class":84},[60,391,88],{"class":70},[60,393,91],{"class":84},[60,395,94],{"class":70},[60,397,399,401,403,405,407,409,411,413,415],{"class":62,"line":398},9,[60,400,379],{"class":66},[60,402,146],{"class":70},[60,404,74],{"class":66},[60,406,78],{"class":77},[60,408,81],{"class":70},[60,410,85],{"class":84},[60,412,88],{"class":70},[60,414,159],{"class":84},[60,416,94],{"class":70},[60,418,420,422,424,426,428,430,432,434],{"class":62,"line":419},10,[60,421,379],{"class":66},[60,423,102],{"class":70},[60,425,74],{"class":66},[60,427,107],{"class":70},[60,429,110],{"class":77},[60,431,81],{"class":70},[60,433,115],{"class":84},[60,435,94],{"class":70},[60,437,439,442,444,446,448],{"class":62,"line":438},11,[60,440,441],{"class":70},"  hibernateLog.",[60,443,169],{"class":77},[60,445,172],{"class":70},[60,447,130],{"class":175},[60,449,94],{"class":70},[60,451,453],{"class":62,"line":452},12,[60,454,456],{"emptyLinePlaceholder":455},true,"\n",[60,458,460],{"class":62,"line":459},13,[60,461,334],{"class":333},[60,463,465],{"class":62,"line":464},14,[60,466,467],{"class":333},"   * Redirect all Hibernate logs to system.out\n",[60,469,471],{"class":62,"line":470},15,[60,472,373],{"class":333},[60,474,476,479,482,485,487,490],{"class":62,"line":475},16,[60,477,478],{"class":66},"  if",[60,480,481],{"class":70}," ( ",[60,483,484],{"class":77},"listFindNoCase",[60,486,81],{"class":70},[60,488,489],{"class":84},"\"Lucee\"",[60,491,492],{"class":70},", server.coldfusion.productname ) ) {\n",[60,494,496,499,501,503,505,507,509,511,513],{"class":62,"line":495},17,[60,497,498],{"class":66},"    var",[60,500,216],{"class":70},[60,502,74],{"class":66},[60,504,221],{"class":77},[60,506,224],{"class":70},[60,508,227],{"class":77},[60,510,224],{"class":70},[60,512,232],{"class":77},[60,514,235],{"class":70},[60,516,518,520,522,524,526,528,530,532,534],{"class":62,"line":517},18,[60,519,498],{"class":66},[60,521,242],{"class":70},[60,523,74],{"class":66},[60,525,78],{"class":77},[60,527,81],{"class":70},[60,529,85],{"class":84},[60,531,88],{"class":70},[60,533,255],{"class":84},[60,535,258],{"class":70},[60,537,539,541,543,545,547,549,551,553,555,557,559],{"class":62,"line":538},19,[60,540,498],{"class":66},[60,542,266],{"class":70},[60,544,74],{"class":66},[60,546,78],{"class":77},[60,548,81],{"class":70},[60,550,85],{"class":84},[60,552,88],{"class":70},[60,554,279],{"class":84},[60,556,282],{"class":70},[60,558,285],{"class":77},[60,560,288],{"class":70},[60,562,564,567,569],{"class":62,"line":563},20,[60,565,566],{"class":70},"    hibernateLog.",[60,568,303],{"class":77},[60,570,306],{"class":70},[60,572,574],{"class":62,"line":573},21,[60,575,576],{"class":70},"  }\n",[60,578,580],{"class":62,"line":579},22,[60,581,582],{"class":70},"}\n",[10,584,585,586,589,590,593],{},"This method should be placed in ",[23,587,588],{},"Application.cfc"," early in the application lifecycle. If this method is run during the page request or in ",[23,591,592],{},"onRequestStart()",", then Hibernate has already initialized and you have lost a lot of valuable output.",[10,595,596],{},"Once this method is in place, we can take advantage of it from CommandBox:",[51,598,600],{"className":53,"code":599,"language":55,"meta":56,"style":56},"box server log --follow\n",[23,601,602],{"__ignoreMap":56},[60,603,604,607,610],{"class":62,"line":63},[60,605,606],{"class":70},"box server log ",[60,608,609],{"class":66},"--",[60,611,612],{"class":70},"follow\n",[10,614,615],{},"This is fantastically great for picking up better log details on, say, an invalid ORM entity.",[617,618,619],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":56,"searchDepth":97,"depth":97,"links":621},[],"2021-08-30T16:13:57-04:00","In my last blog post, I covered how to adjust the Hibernate log level with Log4j.",false,"md",{},"\u002Fposts\u002Fredirecting-hibernate-logs",{"title":5,"description":623},"posts\u002Fredirecting-hibernate-logs",[631,632,633,634],"cfml","coldfusion","hibernate","log4j","VJforFOzg3gQGZhJThX1_uXCmoYZso72Zyl5O_z6X0U",1790471527454]