为什么这个 Hibernate bootstrap 代码在 Envers 打开时无法启动?

Why is this Hibernate bootstrap code failing to start up, when Envers is turned on?

我正在使用 Hibernate 5.2.0

此代码有效(Envers 已关闭):

public static SessionFactory buildSessionFactory()
    {
    StandardServiceRegistryBuilder standardServiceRegistryBuilder 
        = new StandardServiceRegistryBuilder();

    standardServiceRegistryBuilder
          .applySetting("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect")
          .applySetting("hibernate.connection.driver_class", "com.mysql.jdbc.Driver")
          .applySetting("hibernate.connection.url", "jdbc:mysql://localhost:3415/test")
          .applySetting("hibernate.connection.username", "myusername")
          .applySetting("hibernate.connection.password", "mypass123")
          .applySetting(AvailableSettings.HBM2DDL_AUTO, "create")
          .applySetting(AvailableSettings.TRANSACTION_COORDINATOR_STRATEGY, "jdbc")
          .applySetting(AvailableSettings.ISOLATION, String.valueOf(Connection.TRANSACTION_READ_COMMITTED))

          // TURN OFF ENVERS:
          .applySetting(EnversService.INTEGRATION_ENABLED, false)
          .applySetting(EnversIntegrator.AUTO_REGISTER, false);

    standardRegistry = standardServiceRegistryBuilder.build();
    MetadataSources metadataSources = new MetadataSources(standardRegistry);

    Set<Class> classes = getAllPersistableClasses();
    classes.forEach(metadataSources::addAnnotatedClass);

    MetadataBuilder metadataBuilder = metadataSources.getMetadataBuilder();
    metadataBuilder.applyImplicitNamingStrategy(new MyNamingStrategy());

    // It FAILS HERE WHEN ENVERS IS TURNED ON:
    Metadata metadata = metadataBuilder.build(); 

    SessionFactoryBuilder sessionFactoryBuilder = metadata.getSessionFactoryBuilder();
    sessionFactoryBuilder.applyInterceptor(new MyInterceptor());

    return sessionFactoryBuilder.build();
    }

但是,当我打开 Envers 时:

.applySetting(EnversService.INTEGRATION_ENABLED, true)
.applySetting(EnversIntegrator.AUTO_REGISTER, true)

当以下行构建元数据时失败:

Metadata metadata = metadataBuilder.build();

它失败了:

org.hibernate.boot.MappingException: Unable to perform unmarshalling at line number 0 and column 0. Message: null : origin(envers)

这是完整的 stacktrace:

org.hibernate.boot.MappingException: Unable to perform unmarshalling at line number 0 and column 0. Message: null : origin(envers)
    at org.hibernate.boot.jaxb.internal.AbstractBinder.jaxb(AbstractBinder.java:177)
    at org.hibernate.boot.jaxb.internal.MappingBinder.doBind(MappingBinder.java:61)
    at org.hibernate.boot.jaxb.internal.AbstractBinder.doBind(AbstractBinder.java:102)
    at org.hibernate.boot.jaxb.internal.AbstractBinder.bind(AbstractBinder.java:57)
    at org.hibernate.envers.boot.internal.AdditionalJaxbMappingProducerImpl.addDocument(AdditionalJaxbMappingProducerImpl.java:92)
    at org.hibernate.envers.configuration.internal.EntitiesConfigurator.configure(EntitiesConfigurator.java:111)
    at org.hibernate.envers.boot.internal.EnversServiceImpl.doInitialize(EnversServiceImpl.java:152)
    at org.hibernate.envers.boot.internal.EnversServiceImpl.initialize(EnversServiceImpl.java:117)
    at org.hibernate.envers.boot.internal.AdditionalJaxbMappingProducerImpl.produceAdditionalMappings(AdditionalJaxbMappingProducerImpl.java:99)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:288)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
    at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:418)
    at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:87)
    at Bd.RelacionadosAoHibernate.UtilHibernate.createSessionFactory(UtilHibernate.java:470)
    at Bd.RelacionadosAoHibernate.UtilHibernate.<clinit>(UtilHibernate.java:79)
    at Aplicativo.InitAplicativoBdHttp.executaInicializacao_Hibernate(InitAplicativoBdHttp.java:108)
    at Aplicativo.InitAplicativoBdHttp.inicializaBancoDeDados(InitAplicativoBdHttp.java:29)
    at Aplicativo.InitAplicativo.inicializa(InitAplicativo.java:16)
    at Http.Sessao.ListenerDeAplicacao.<clinit>(ListenerDeAplicacao.java:24)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at java.lang.Class.newInstance(Class.java:433)
    at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:121)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4651)    
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5167)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
    at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1648)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:463)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:413)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1466)
    at javax.management.remote.rmi.RMIConnectionImpl.access0(RMIConnectionImpl.java:76)
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1307)
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1399)
    at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:828)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
    at sun.rmi.transport.Transport.run(Transport.java:178)
    at sun.rmi.transport.Transport.run(Transport.java:175)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:174)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:557)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:812)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:671)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Caused by: javax.xml.bind.UnmarshalException
 - with linked exception:
[javax.xml.stream.XMLStreamException: ParseError at [row,col]:[67,50]
Message: Invalid byte 2 of 2-byte UTF-8 sequence.]
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:470)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:448)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:420)
    at org.hibernate.boot.jaxb.internal.AbstractBinder.jaxb(AbstractBinder.java:171)
    ... 67 more

Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[67,50]
Message: Invalid byte 2 of 2-byte UTF-8 sequence.
    at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:596)
    at com.sun.xml.internal.stream.XMLEventReaderImpl.peek(XMLEventReaderImpl.java:276)
    at javax.xml.stream.util.EventReaderDelegate.peek(EventReaderDelegate.java:104)
    at org.hibernate.boot.jaxb.internal.stax.BufferedXMLEventReader.peek(BufferedXMLEventReader.java:96)
    at javax.xml.stream.util.EventReaderDelegate.peek(EventReaderDelegate.java:104)
    at org.hibernate.boot.jaxb.internal.stax.HbmEventReader.peek(HbmEventReader.java:47)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXEventConnector.handleCharacters(StAXEventConnector.java:164)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXEventConnector.bridge(StAXEventConnector.java:126)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:445)
    ... 69 more

05-Jun-2016 23:49:27.093 SEVERE [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full details will be found in the appropriate container log file

有什么想法吗?谢谢。

我发现了问题,并打开了这个错误问题:

https://hibernate.atlassian.net/browse/HHH-10811

这个错误阻止了一些有效的 Java 标识符被用作持久化的字段名称,并且只有在使用 Envers 时。

一个示例问题是经过审核的 class(UTF-8 源代码)包含一个名为 "seÉfinal" 的布尔字段,因为字符“É”是字符 [=24 的重音版本=],导致解析错误:"Invalid byte 2 of 2-byte UTF-8 sequence"。 许多字符会失败,例如:áéíóúãõñàèçÁÉÇ等

最常见的原因是输入了 ISO-8859-x(如 Latin-1),但 XML 解析器认为它正在获取 UTF-8(反之亦然)。例如,某些 Latin-1 字符序列(两个带有重音符号或元音变音的连续字符)形成一些作为 UTF-8 无效的东西,特别是基于第一个字节,第二个字节具有意外的高位。

解决方法是重命名所有字段,使它们不包含非英文字母。