Skip to content

Commit 82615f5

Browse files
authored
Merge pull request #45 from zspitzer/LDEV-6159-redux
LDEV-6159 this.logs support, lifecycle logging, test coverage
2 parents a172edd + b2dca7b commit 82615f5

33 files changed

Lines changed: 774 additions & 7 deletions

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## 5.6.15.13
4+
5+
### Improvements
6+
7+
- ORM logging now respects application-level `this.logs` overrides (Lucee 7.0+). Each application can independently control the orm log level without affecting other apps on the server
8+
- Added lifecycle logging at DEBUG level: "ORM initializing", "ORM initialized" (with entity count and settings), and "ormReload()" messages
9+
310
## 5.6.15.12
411

512
### Performance

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>org.lucee</groupId>
66
<artifactId>hibernate-extension</artifactId>
7-
<version>5.6.15.12-SNAPSHOT</version>
7+
<version>5.6.15.13-SNAPSHOT</version>
88
<packaging>jar</packaging>
99
<name>Hibernate Extension</name>
1010

source/java/src/org/lucee/extension/orm/hibernate/HibernateORMEngine.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ public ORMSession createSession(PageContext pc) throws PageException {
9595
public boolean reload(PageContext pc, boolean force) throws PageException {
9696
String appName = pc.getApplicationContext().getName();
9797
if (force || !isInitializedForApplication(appName)) {
98+
if ( force ) {
99+
Log log = CommonUtil.getORMLog( pc );
100+
if ( log != null ) log.log( Log.LEVEL_DEBUG, "hibernate", "ormReload() for application [" + appName + "]" );
101+
}
98102
synchronized (INIT_LOCK) {
99103
if (force || !isInitializedForApplication(appName)) {
100104
buildSessionFactoryData(pc);
@@ -186,11 +190,18 @@ private SessionFactoryData buildSessionFactoryData(PageContext pc) throws PageEx
186190

187191
// Configure ORM logging BEFORE Hibernate classes load, so level filtering is active
188192
// from the start.
189-
Log log = pc.getConfig().getLog( "orm" );
193+
Log log = CommonUtil.getORMLog( pc );
190194
OrmLoggingSettings logSettings = OrmLoggingSettings.load( pc, ormConf );
191195
LoggerLevelManager.configure( log, logSettings.logSQL, logSettings.logParams,
192196
logSettings.logCache, logSettings.logVerbose );
193197

198+
if ( log != null ) {
199+
log.log( Log.LEVEL_DEBUG, "hibernate",
200+
"ORM initializing for application [" + applicationName + "], dbcreate [" + dbCreateLabel( ormConf.getDbCreate() ) + "]" );
201+
String dbCreateWarning = OrmLoggingSettings.checkDbCreate( pc, ormConf.getDbCreate() );
202+
if ( dbCreateWarning != null ) log.log( Log.LEVEL_WARN, "hibernate", dbCreateWarning );
203+
}
204+
194205
SessionFactoryData data = new SessionFactoryData(this, ormConf);
195206
setSessionFactory(applicationName, data);
196207

@@ -267,6 +278,9 @@ private SessionFactoryData buildSessionFactoryData(PageContext pc) throws PageEx
267278
data.buildSessionFactory(e.getKey());
268279
}
269280

281+
if ( log != null ) log.log( Log.LEVEL_DEBUG, "hibernate",
282+
"ORM initialized [" + data.sizeCFCs() + "] entities for application [" + applicationName + "], " + logSettings );
283+
270284
return data;
271285
}
272286

@@ -403,6 +417,18 @@ private static Component _create(PageContext pc, String entityName, boolean uniq
403417
}
404418
return null;
405419
}
420+
421+
private static String dbCreateLabel( int dbCreate ) {
422+
switch ( dbCreate ) {
423+
case ORMConfiguration.DBCREATE_NONE: return "none";
424+
case ORMConfiguration.DBCREATE_DROP_CREATE: return "dropcreate";
425+
case ORMConfiguration.DBCREATE_UPDATE: return "update";
426+
case 3: return "create";
427+
case 4: return "create-drop";
428+
case 5: return "validate";
429+
default: return "unknown(" + dbCreate + ")";
430+
}
431+
}
406432
}
407433

408434
class CFCInfo {

source/java/src/org/lucee/extension/orm/hibernate/logging/OrmLoggingSettings.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,33 @@ private static Struct getOrmSettingsStruct( PageContext pc ) {
9191
return null;
9292
}
9393

94+
/**
95+
* Check if the raw dbcreate string from this.ormSettings was silently defaulted to "none"
96+
* by the Lucee loader (6.2 doesn't support create/create-drop/validate).
97+
*
98+
* @return a warning message if there's a mismatch, or null if everything is fine.
99+
*/
100+
public static String checkDbCreate( PageContext pc, int resolvedDbCreate ) {
101+
Struct ormSettings = getOrmSettingsStruct( pc );
102+
if ( ormSettings == null ) return null;
103+
104+
Key KEY_DB_CREATE = CommonUtil.createKey( "dbcreate" );
105+
String raw = CommonUtil.toString( ormSettings.get( KEY_DB_CREATE, null ), null );
106+
if ( raw == null || raw.trim().isEmpty() ) return null;
107+
108+
raw = raw.trim().toLowerCase();
109+
// These are the values that all Lucee versions understand
110+
if ( "none".equals( raw ) || "update".equals( raw ) || "dropcreate".equals( raw ) || "drop-create".equals( raw ) )
111+
return null;
112+
113+
// If the resolved value is NONE but the raw value isn't one of the known strings,
114+
// the loader silently defaulted it
115+
if ( resolvedDbCreate == 0 )
116+
return "Unsupported dbcreate value [" + raw + "] for this Lucee version, defaulting to [none]";
117+
118+
return null;
119+
}
120+
94121
@Override
95122
public String toString() {
96123
return String.format( "OrmLoggingSettings[logSQL=%s, logParams=%s, logCache=%s, formatSQL=%s, logVerbose=%s]",

source/java/src/org/lucee/extension/orm/hibernate/util/CommonUtil.java

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -888,13 +888,46 @@ public static Config config() {
888888
return pc().getConfig();
889889
}
890890

891+
// Cached reflection lookup for ApplicationContext.getLog(String) (Lucee 7.0+).
892+
private static volatile Method appContextGetLog;
893+
private static volatile boolean appContextGetLogResolved = false;
894+
895+
/**
896+
* Get the ORM log from the given PageContext, respecting application-level
897+
* this.logs overrides before falling back to server config.
898+
*/
899+
public static Log getORMLog( PageContext pc ) {
900+
if ( pc != null ) {
901+
// Try application-level this.logs first (Lucee 7.0+ only)
902+
if ( !appContextGetLogResolved ) {
903+
try {
904+
appContextGetLog = pc.getApplicationContext().getClass().getMethod( "getLog", String.class );
905+
}
906+
catch ( Exception e ) {
907+
// Lucee 6.2 — method doesn't exist
908+
}
909+
appContextGetLogResolved = true;
910+
}
911+
if ( appContextGetLog != null ) {
912+
try {
913+
Log log = ( Log ) appContextGetLog.invoke( pc.getApplicationContext(), "orm" );
914+
if ( log != null ) return log;
915+
}
916+
catch ( Exception e ) {
917+
// fall through to server config
918+
}
919+
}
920+
return pc.getConfig().getLog( "orm" );
921+
}
922+
return null;
923+
}
924+
891925
/**
892926
* Get the ORM log from the current thread's PageContext, or null if unavailable.
893927
*/
894928
public static Log getORMLog() {
895929
try {
896-
PageContext pc = CFMLEngineFactory.getInstance().getThreadPageContext();
897-
if ( pc != null ) return pc.getConfig().getLog( "orm" );
930+
return getORMLog( CFMLEngineFactory.getInstance().getThreadPageContext() );
898931
}
899932
catch ( Exception e ) {
900933
// no log available
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
component {
2+
3+
this.name = "orm-applog-error-#hash( getCurrentTemplatePath() )#";
4+
this.datasource = server.getDatasource( "h2", server._getTempDir( "orm-applog-error" ) );
5+
this.ormEnabled = true;
6+
this.ormSettings = {
7+
dbcreate: "dropcreate",
8+
cfclocation: [ getDirectoryFromPath( getCurrentTemplatePath() ) ],
9+
logSQL: true,
10+
logParams: true
11+
};
12+
13+
// Application-level log override — set orm log to ERROR
14+
this.logs = {
15+
"orm": {
16+
"appender": "resource",
17+
"appenderArguments": {
18+
"path": "{lucee-config}/logs/orm.log"
19+
},
20+
"level": "error",
21+
"layout": "classic"
22+
}
23+
};
24+
25+
function onRequestStart() {
26+
ormReload();
27+
}
28+
29+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
component persistent="true" table="LogEntity" accessors="true" {
2+
3+
property name="id" type="string" fieldtype="id" ormtype="string";
4+
property name="name" type="string";
5+
6+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<cfscript>
2+
cflog( text: url.marker, log: "orm" );
3+
4+
item = entityNew( "LogEntity" );
5+
item.setId( createUUID() );
6+
item.setName( "ErrorTest" );
7+
entitySave( item );
8+
ormFlush();
9+
10+
echo( "ok" );
11+
</cfscript>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
component {
2+
3+
this.name = "orm-applog-trace-#hash( getCurrentTemplatePath() )#";
4+
this.datasource = server.getDatasource( "h2", server._getTempDir( "orm-applog-trace" ) );
5+
this.ormEnabled = true;
6+
this.ormSettings = {
7+
dbcreate: "dropcreate",
8+
cfclocation: [ getDirectoryFromPath( getCurrentTemplatePath() ) ],
9+
logSQL: true,
10+
logParams: true
11+
};
12+
13+
// Application-level log override — set orm log to TRACE
14+
this.logs = {
15+
"orm": {
16+
"appender": "resource",
17+
"appenderArguments": {
18+
"path": "{lucee-config}/logs/orm.log"
19+
},
20+
"level": "trace",
21+
"layout": "classic"
22+
}
23+
};
24+
25+
function onRequestStart() {
26+
ormReload();
27+
}
28+
29+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
component persistent="true" table="LogEntity" accessors="true" {
2+
3+
property name="id" type="string" fieldtype="id" ormtype="string";
4+
property name="name" type="string";
5+
6+
}

0 commit comments

Comments
 (0)