Thanks for the excellent write-up! I'm fine with option 2. Sent from my iPad
On May 6, 2013, at 5:50 AM, Nick Williams <[email protected]> wrote: > 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
