Problema com Hibernate 5.2.6 Final e Wildfly 10

Boa tarde!
Estou tendo um problema com o Hibernate. Pelo que entendi, o Wildfly 10 tem um Hibernate embarcado que eu não quero usar para não “amarrar” a aplicação. Estou usando o “Hibernate 5.2.6 Final” e aparentemente ele está conflitando com o Wildfly.
Quando tento iniciar a aplicação aparece a mensagem:

19:28:40,148 INFO  [org.hibernate.dialect.Dialect] (ServerService Thread Pool -- 58) HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
19:28:40,208 INFO  [org.hibernate.envers.boot.internal.EnversServiceImpl] (ServerService Thread Pool -- 58) Envers integration enabled? : true
19:28:40,453 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 58) MSC000001: Failed to start service jboss.persistenceunit."bookstore.war#bookstore": org.jboss.msc.service.StartException in service jboss.persistenceunit."bookstore.war#bookstore": java.lang.ClassCastException: org.dom4j.DocumentFactory cannot be cast to org.dom4j.DocumentFactory
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:172)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:117)
at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:667)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:182)
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)
at org.jboss.threads.JBossThread.run(JBossThread.java:320)
Caused by: java.lang.ClassCastException: org.dom4j.DocumentFactory cannot be cast to org.dom4j.DocumentFactory
at org.dom4j.DocumentFactory.getInstance(DocumentFactory.java:97)
at org.hibernate.internal.util.xml.XMLHelper$1.doWork(XMLHelper.java:33)
at org.hibernate.internal.util.xml.XMLHelper$1.doWork(XMLHelper.java:27)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.workWithClassLoader(ClassLoaderServiceImpl.java:342)
at org.hibernate.internal.util.xml.XMLHelper.<init>(XMLHelper.java:26)
at org.hibernate.envers.boot.internal.EnversServiceImpl.initialize(EnversServiceImpl.java:115)
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.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:847)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:874)
at org.jboss.as.jpa.hibernate5.TwoPhaseBootstrapImpl.build(TwoPhaseBootstrapImpl.java:44)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:154)
... 7 more

Depois de uma pesquisa, me falaram para colocar o “Scope” do “hibernate” no “pom.xml” como “provided”, quando faço isso ele passa a considerar o hibernante do wildfly. O que eu qeuro na verdade é fazer justamente o contrario.
Como posso resolver isso?

está tendo conflito com isso : dom4j

dentro do zip do hibernate tem um jar com esse nome, se colocou ele junto da pasta lib com outros jar, retira o mesmo e tenta rodar o projeto novamente.

caso esteja utilizando o maven, tem um jeito que não baixar esse jar :

    <dependency>
            <groupId>org.hibernate</groupId>
       <artifactId>hibernate-core</artifactId>
       <version>5.2.6.Final</version>
            <exclusions> 
                <exclusion>
                    <groupId>dom4j</groupId>
                    <artifactId>dom4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

{ },S.

1 curtida

Cara, eu tive exatamente a mesma dúvida que você há algum tempo e vou compartilhar contigo as conclusões que eu obtive depois de pesquisar bastante e conversar com alguns amigos que atuam na área.

É legal escrever o código independente do provider, para poder trocar entre eles livremente. Mas, pensando num cenário real, quando é que você vai mudar o provider? Principalmente se tratando de Hibernate, que é a implementação referência para o mercado e não vai deixar de ser utilizada tão cedo. Muito pelo contrário, você pode até utilizar recursos específicos do Hibernate para otimizar seu sistema.

Quando chegar a hora de trocar de provider, você altera os pontos de incompatibilidade. Para isso servem testes de integração sólidos, com os quais você deve poder contar para detectar se alguma parte do sistema quebrou na hora que trocou o provider.

Outra coisa, você não precisa necessariamente disponibilizar o teu provider dentro do teu .war. Você pode instalar o provider dentro do Application Container (no caso o Wildfly) e utilizá-lo normalmente. Tem como ter várias versões de um mesmo provider e escolher a versão específica dentro do teu persistence.xml, assim: <property name="jboss.as.jpa.providerModule" value="org.hibernate:5.2"/>, para utilizar o Hibernate 5.2.QualquerCoisa, por exemplo (dá para ser mais específico e colocar algo como 5.2.6.Final).

Algo que me ajudou bastante com essas questões foi ler os guias na documentação do Wildfly. Vale a pena gastar uma tarde lá e aprender algumas coisas mais internas do container! Por exemplo, sabia que tem como você dar deploy em um datasource temporário, que vive enquanto o teu .war estiver lá? Isso é extremamente útil para fazer testes.

Isso que você falou faz todo sentido. Temos que ser mais práticos.

Como sempre uma excelente resposta, obrigado meu camarada!!

1 curtida