As I wait on the beta6 release process to complete so that Ralph can commit my first pass at the JDBC, JPA, and NoSQL Appenders, I wanted to start a discussion about the JPA appender and JPA 2.1. (For reference, you can see the new feature request here [1], and there is a patch attached to that feature request containing my first pass at the Appenders.)
Currently, the patch includes a JPA appender that requires JPA 2.0. Hibernate isn't the only JPA provider out there, but since it's the most popular I'll use it as an example here. Hibernate 3.5.0 or higher is required for JPA 2.0 support. JPA 1 had a major drawback that caused it to receive a lot of criticism from the community (including me): There was no way to specify custom type converters, so if you had some kind of special type (like a StackTraceElement, or a Marker, or a Message) that you wanted to support you had to use a provider-proprietary API to do it, or convert the value manually within the getter and setter. Many (again, including me) were outraged when JPA 2.0 came out and it STILL did not have support for custom types. So, when I created the JPA appender I created an abstract class implementing LogEvent called LogEventWrapperEntity. This class provides no-op setters to complement all of the getters defined in the interface (because JPA requires setters, but we don't need them because log events will be write-only). However, the end-user MUST implement ALL of the getters specified in the LogEvent interface, because how these values are converted will depend on which provider they use. I'm not 100% happy with that, but it works. Enter JPA 2.1, whose final draft was approved two weeks ago and will be released final literally any day now, and finally there is a way to specify custom converters without depending on provider-specific APIs (@javax.persistence.Convert and javax.persistence.AttributeConverter). Using these, I could create AttributeConverters for StackTraceElement, Throwable, Message, Marker, Level, Map<String, String>, and ThreadContext.ContextStack. I could then create a more complete entity with all of the getters already defined using default column names. Then, if someone wanted to change one or more column names, they would only need to override the getters whose column names they wanted to change, and they wouldn't have to worry about type conversion. It would make using the JPA Appender MUCH easier. Since JPA 2.1 is a minor version, this shouldn't so much be a problem, except that people using Hibernate would need to upgrade to 4.3.0 or higher ... a major upgrade if they're still on 3.5-3.7, but only a minor upgrade if they're on 4.0+ already. Hibernate 4.3.0 is currently in beta but should release soon, almost assuredly before Log4j 2 does. I know in both of my $work environments we have a need for many custom converters and will be upgrading ASAP when 4.3.0 comes out. So, what do you think? Which of these options do you prefer? 1) A harder-to-use JPA Appender that is more forgiving about which JPA provider version you use, or 2) A much easier-to-use JPA Appender that requires the absolute latest JPA provider version? I lean towards 2. My thoughts are that by the time Log4j 2 becomes widely used JPA 2.1 providers will be the norm, not brand new like they are now. My bets are that the few people that will be using the JPA Appender early on are likely already early adopters who will already be on JPA 2.1 or don't mind upgrading. Nick [1] https://issues.apache.org/jira/browse/LOG4J2-229
smime.p7s
Description: S/MIME cryptographic signature
