Custom Scalar Valued function in Hibernate 5.x - java

I have a custom Scalar Valued function in SQL with the below details:
Name : fn_WorkDays
Returns : Int
Parameters : 1. StartDate (type - datetime) 2. EndDate (type - datetime)
I'm using Hibernate 5.4.6 to fetch some records from the database. I want to use the above function in the HQL (in the Where Clause), however currently facing issues.
Query<Device> query = session.createQuery("Select ud from Device ud where fn_WorkDays(ua.created, current_date())>2", Device.class);
After going through some posts, I understand that the custom function needs to be registered before using it, hence have created the below class:
public class MySQLServerDialect extends SQLServerDialect {
public MySQLServerDialect() {
super();
registerFunction("fn_WorkDays", new VarArgsSQLFunction(StandardBasicTypes.INTEGER, "fn_WorkDays(", ",", ")"));
}
}
Have updated the hibernate.cfg.xml with :
<property name="dialect">com.test.service.utils.MySQLServerDialect</property>
I dont seem to understand how the registerFunction should be done as im getting the below error:
ERROR SqlExceptionHelper:142 - 'fn_WorkDays' is not a recognized function name.
Log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<!-- Console Appender -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout
pattern="%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36}:%L - %msg%n" />
</Console>
</Appenders>
<Loggers>
<!-- Log everything in hibernate -->
<Logger name="org.hibernate" level="debug" additivity="false">
<AppenderRef ref="Console" />
</Logger>
<!-- Log SQL statements -->
<Logger name="org.hibernate.SQL" level="debug" additivity="false">
<AppenderRef ref="Console" />
</Logger>
<!-- Log JDBC bind parameters -->
<Logger name="org.hibernate.type.descriptor.sql" level="trace" additivity="false">
<AppenderRef ref="Console" />
</Logger>
<!-- Log custom packages -->
<Logger name="com.test.service" level="debug" additivity="false">
<AppenderRef ref="Console" />
</Logger>
<Root level="error">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
Any help to resolve the above will be greatly appreciated.

ERROR SqlExceptionHelper:142 - 'fn_WorkDays' is not a recognized function name.
The error already says what is wrong, the function does not exist in the database.
Try this:
registerFunction("fn_WorkDays", new VarArgsSQLFunction(StandardBasicTypes.INTEGER, "dbo.fn_WorkDays(", ",", ")"));

Functions that are not pre-defined in the JPQL/HQL are invoked like this:
`function('fn_WorkDays' , ua.created, current_date())`
This is later translated to fn_WorkDays(ua.created, current_date()) in the native query. You still need to have it registered by the dialect as you have.

Related

What does ${sys:logger.out.type} mean in Log4j2?

I am currently working on tidying up the logs for an internal tool we have. I came across the use of ${sys:logger.out.type} inside the Loggers in log4j2.xml.
Here's a copy of our log4j2.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="OFF">
<Appenders>
<Console name="stdout" target="SYSTEM_OUT">..
<PatternLayout pattern="..."/>
</Console>
<RollingFile name="FILE" fileName="${sys:microservice.log}" filePattern="${sys:microservice.log}.%i">
<PatternLayout>
<Pattern>...</Pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="300 MB" />
</Policies>
<DefaultRolloverStrategy max="5" />
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.springframework" level="warn" additivity="false">
<appender-ref ref="${sys:logger.out.type}"/>
</Logger>
<Logger name="org.springframework.jdbc.core" level="off" additivity="false">
<appender-ref ref="${sys:logger.out.type}"/>
</Logger>
<Logger name="org.springframework.jdbc.core.StatementCreatorUtils" level="off" additivity="false">
<appender-ref ref="${sys:logger.out.type}"/>
</Logger>
<Logger name="com.myOrgName" level="trace" additivity="false">
<appender-ref ref="${sys:logger.out.type}"/>
</Logger>
<Root level="info" additivity="false">
<appender-ref ref="${sys:logger.out.type}"/>
</Root>
</Loggers>
</configuration>
In my previous StackOverflow question, a very kind user redirected me to the Log4j Property Substitution page to better understand the semantics of ${sys:logger.out.type}.
After reading through the documentation, I understand the sys Prefix is referring to a system property but don't quite understand what logger.out.type means?
Taking a stab here, is it referring to the output type of a Logger? Which could mean it's referring to the Console element named stdout?
Appreciate any insights & feedback from the community. Should any of my understanding be mistaken, please correct me, I am also learning :) Thank you!
A property like ${sys:logger.out.type} in a log4j 2.x configuration file resolves to the value of the Java system property named logger.out.type.
You set system properties by passing the command line argument -Dlogger.out.type=stdout (or more generally -D<property name>=<value>) to the JVM when you invoke the java command.
You can also provide defaults, so ${sys:logger.out.type:-FILE} would choose your FILE appender if no value was set for that system property.

log4j2: Is there any way to display sql values in log4j2?

Right now my info logs only show sql queries with ? for values. Can you suggest me changes to log4j2.xml file to display values?
log4j2.xml:
<RollingRandomAccessFile name="SQLLOGFILE">
<PatternLayout>
<Pattern>%-5p:%d{dd-MMM-yyyy HH:mm:ss,SSS}: %-25t %c : %m%n</Pattern>
</PatternLayout>
</RollingRandomAccessFile>
<AsyncLogger name="jdbc.sqlonly" level="INFO">
<AppenderRef ref="LOGFILE" level="INFO"/>
</AsyncLogger>
<AsyncLogger name="jdbc.audit" level="off"></AsyncLogger>
<AsyncLogger name="jdbc.resultset" level="off"></AsyncLogger>
<AsyncLogger name="jdbc.connection" level="DEBUG">
<AppenderRef ref="CONNECTION"/>
</AsyncLogger>
If your ORM vendor is Hiberante, which is by default in Spring framework you can use the following properties inside log4j2.xml
<AsyncLogger name="org.hibernate.SQL" level="DEBUG">
<AppenderRef ref="LOGFILE"/>
</AsyncLogger>
<AsyncLogger name="org.hibernate.type" level="TRACE">
<AppenderRef ref="LOGFILE"/>
</AsyncLogger>
Those 2 above properties include all necessary classes for the SQLs to appear correctly in your logs, including the binded values inside ? placeholders.
More specifically in hibernate the responsible class for placing values inside ? is the org.hibernate.type.descriptor.sql.BasicBinder. Those 2 above properties include this class as well to the Trace level, so the binded values for ? are correctly appended.
Consider using the datasource proxy TTDDYY that logs the quires already at more convenient way

Turning off Log4j2 by setting Root level to "off" doesnt work

I have a problem with logging within Junit tests.
In log4j2.xml, I have changed <Root level="info"> to <Root level="off">:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d [%t] %-5p %c{1.} - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="off">
<AppenderRef ref="STDOUT"/>
</Root>
<!-- hibernate debugging -->
<Logger name="org.hibernate.SQL" level="DEBUG">
<AppenderRef ref="STDOUT" />
</Logger>
<Logger name="org.hibernate.type" level="TRACE">
<AppenderRef ref="STDOUT" />
</Logger>
</Loggers>
</Configuration>
But it doesn't help, I still get the same amount of logs. I need to make the logs dissapear to make progress in an test performance investigation, to be able to run my own allways despised System.out.println() in some of the tests. How can I achive that?

Change Quartz appender in log4j2

I'm trying to redirect all Quartz logging to a separate file, but it still keeps logging into the console. What am I doing wrong in the configuration file?
Here's a simplified version of my log4j2.xml
<Configuration>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<!--stuff-->
</Console>
<RollingFile name="Quartz">
<!--stuff-->
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.quartz" level="ALL">
<AppenderRef ref="Quartz"/>
</Logger>
<Logger name="com.rotoplastyc" level="ALL">
<AppenderRef ref="Console" />
</Logger>
<Root level="OFF">
</Root>
</Loggers>
</Configuration>
Found out that, as #teppic suggested in the comments, I needed the log4j-slf4j-impl lib in order for it to work properly, I was currently using the slf4j-simple lib which only logs into the console.

How to setup log4j2 asyncQueueFullPolicy

I am using log4j-core-2.5 for my logging and I would like to Discard items when the logging queue is full. I have determined that this could be applied by using the log4j2.asyncQueueFullPolicy configuration property in log4j.
Could somone please help me with how to apply this configuration in my application.
I am using a file configuration like so...
Configurator.initialize("", "log4j-node.xml");
My config file looks somthing like this
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{dd-MMM HH:mm:ss.SSS} %logger{1}.%t %-5level] %msg%n"/>
</Console>
<RollingFile name="DefaultFile" fileName="../logs/app.log"
filePattern="../logs/app-%d{MM-dd-yyyy}-%i.log" bufferedIO="true" bufferedSize="32000" immediateFlush="false">
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
...
</RollingFile>
<Async name="AsyncFile">
<AppenderRef ref="DefaultFile"/>
<LinkedTransferQueue/>
</Async>
<Async name="AsyncConsole">
<AppenderRef ref="Console"/>
<LinkedTransferQueue/>
</Async>
</Appenders>
<logger name="org.hibernate">
<level value="debug" />
</logger>
<Loggers>
<Root level="TRACE">
<AppenderRef ref="AsyncConsole"/>
<AppenderRef ref="AsyncFile"/>
</Root>
<Logger name="org.hibernate.SQL" level="error" />
<!-- Log all JDBC parameters -->
<Logger name="org.hibernate.type" level="error" />
<!-- Log all SQL DDL statements as they are executed -->
<Logger name="org.hibernate.tool.hbm2ddl" level="error" />
<!-- Log the state of all entities (max 20 entities) associated with the session at flush time -->
<Logger name="org.hibernate.pretty" level="error" />
<!-- Log all second-level cache activity -->
<Logger name="org.hibernate.cache" level="error" />
<!-- Log transaction related activity -->
<Logger name="org.hibernate.transaction" level="error" />
<!-- Log all JDBC resource acquisition -->
<Logger name="org.hibernate.jdbc" level="error" />
<!-- Log HQL and SQL ASTs during query parsing -->
<Logger name="org.hibernate.hql.ast.AST" level="error" />
<!-- Log all JAAS authorization requests -->
<Logger name="org.hibernate.secure" level="error" />
<!-- Log everything (a lot of information, but very useful for troubleshooting) -->
<Logger name="org.hibernate" level="error" />
</Loggers>
</Configuration>
Cheers
First, please upgrade to Log4j 2.10, which fixed an important issue in this area where log events no longer appear out of order in the log file when the queue is full.
You can configure Log4j2's behaviour via system property log4j2.AsyncQueueFullPolicy. See AsyncQueueFullPolicy and AsyncQueueFullPolicyFactory. The "Discard" policy with some log level may be of interest.
Property log4j2.AsyncQueueFullPolicy controls the routing
behaviour. If this property is not specified or has value "Default",
this factory creates DefaultAsyncQueueFullPolicy objects.
If this property has value "Discard", this factory creates
DiscardingAsyncQueueFullPolicy objects. By default, this router
discards events of level INFO, DEBUG and TRACE if the queue is full.
This can be adjusted with property log4j2.DiscardThreshold (name of
the level at which to start discarding).

Categories

Resources