Cloud with rain
.:G
G:.
0 and 1 serie, black on white
pulled card
myjsp.feelinglinux.com
ver. 1.1.9-4
Hallo, welcome to my world.
Here you can find some stuff about computer science.
<<< Enjoy your visit! >>>
0 and 1 serie, white on black

Grails 3.2.6, db-reverse-engineer 4.0.0: reverse engineering di database Postgresql

        Scritto: Giansante Gabriele, 18/03/2017     

* Jdk 1.8.0_102
* Netbeans 8.2
* Grails 3.2.6
* Groovy 2.4.8
* Plugin grails "db-reverse-engineer" ver. 4.0.0
Inizialmente si vedra' una possibile configurazione del plugin "db-reverse-engineer" (4.0.0) su Grails 3.2.6 in modo da farlo funzionare per la generazione delle classi di dominio a partire da un database Postgresql esistente.
Successivamente, dal momento che la semplice inclusione del plugin sembra non funzionare, ripercorrero' i passi che mi hanno portato ad una soluzione accettabile per i miei scopi, segnalando i vari problemi riscontrati (valido al 01/03/2017, se non escono aggiornamenti vari).

Configurazione e generazione delle classi

Mi sono trovato nella situazione di realizzare un'applicazione con Grails 3.2.6 e accesso ad una base di dati Postgresql gia' esistente. Dovendomi appoggiare ad una base di dati gia' esistente e di dimensioni medio-grandi, ho pensato di uare il plugin "db-reverse-engineer" per mapparla automaticamente con classi di dominio.
Ecco come ho configurato l'applicazione appena creata in modo da effettuare il reverse-engineering della base di dati.
  1. Aggiungere il plugin "db-reverse-engineer" nel file "build.gradle" presente nella root directory del progetto:
    build.gradle
                
        buildscript {
            dependencies {
                [...]
    
                //Va messo sia qui che in dependencies, altrimenti
                //non viene compilato il task dbReverseEngineer
                classpath "org.grails.plugins:db-reverse-engineer:4.0.0"
            }
        }
    
        dependencies {
            [...]
    
            compile "postgresql:postgresql:9.1-901.jdbc4"
            //Plugin per il reverse engineer del DB
            compile 'org.grails.plugins:db-reverse-engineer:4.0.0'
        }
                
            


  2. Aggiungere/modificare le dipendenze relative ad "Hibernate". L'applicazione Grails appena creata contiene dipendenze da Hibernate 5. Purtroppo il plugin non funziona con Hibernate 5 e anzi, non viene proprio compilato con solo le dipendenze di deault. Viene aggiunta la dipendenza da "hibernate-entitymanager" (non presente alla creazione dell'applicazione) e viene modificata "temporaneamente" la versione di Hibernate da 5 a 4.
    build.gradle
    
        dependencies {
            [...]
    
            //compile "org.grails.plugins:hibernate5"
            compile "org.grails.plugins:hibernate4"
    
            /*compile "org.hibernate:hibernate-core:5.1.2.Final"
            compile "org.hibernate:hibernate-ehcache:5.1.2.Final"
            compile "org.hibernate:hibernate-core:4.3.10.Final"
            compile "org.hibernate:hibernate-ehcache:4.3.10.Final"
            compile "org.hibernate:hibernate-entitymanager:4.3.10.Final"
    
            [...]
        }
            
    Al termine dell'esecuzione del task di reverse-engineering, ripristinare Hibernate 5.

  3. Eventualmente, configurare i parametri del plugin. A tale scopo, vedere "DB Reverse Engineering Plugin - Reference Documentation

  4. Da linea di comando, posizionarsi nella root directory del progetto (es. per il porgetto "MyProjects" creato con NetBeans, "C:\Users\Pippo\Documents\NetBeansProjects\MyProject"). Per compilare ed avviare il task "dbReverseEngineer" eseguire il seguente comando (development environment):
    
        gradlew dbReverseEngineer
            
    Il nome del task lo si trova lanciando "gradlew tasks", che elenca tutti i task disponibili). Al termine dell'esecuzione, se tutto e' andato bene, dovremmo trovare le classi generate (da modificare leggermente in caso di possibili errori di compilazione dovuti ad una errata generazione o problemi legati all'implementazione della base di dati).

  5. Ripristinare "Hibernate 5", lanciare "gradlew clean", correggere eventuali errori nelle classi generate
Pubblicita'


Problemi riscontrati prima di arrivare ad una configurazione accettabile

Il plugin "db-reverse-engineer" purtroppo sembra avere qualche problema a funzionare correttamente con Grails 3.2.6. Inserendolo nelle dipendenze di un nuovo progetto (punto 1 del paragrafo precedente) ed eseguendo il task da linea di comando, ho ottenuto quanto segue:
C:\Users\Pippo\Documents\NetBeansProjects\MyProject>gradlew dbReverseEngineer
:compileJava UP-TO-DATE
:compileGroovy
:buildProperties UP-TO-DATE
:processResources UP-TO-DATE
:classes
:findMainClass
:dbReverseEngineer
2017-03-01 11:39:04.176 ERROR --- [           main] o.s.boot.SpringApplication               : Application startup failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tomcatEmbeddedServletContainerFactory' defined in class path resource [org/springframework/boot/autoconfigure/web/EmbeddedServletContainerAutoConfiguration$EmbeddedTomcat.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serverProperties' defined in class path resource [org/springframework/boot/autoconfigure/web/ServerPropertiesAutoConfiguration.class]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/hibernate/bytecode/instrumentation/internal/FieldInterceptionHelper
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:372)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:83)
        at grails.ui.command.GrailsApplicationContextCommandRunner.run(GrailsApplicationContextCommandRunner.groovy:55)
        at grails.ui.command.GrailsApplicationContextCommandRunner.main(GrailsApplicationContextCommandRunner.groovy:102)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serverProperties' defined in class path resource [org/springframework/boot/autoconfigure/web/ServerPropertiesAutoConfiguration.class]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/hibernate/bytecode/instrumentation/internal/FieldInterceptionHelper
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:519)
        at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1197)
        at org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor.getCustomizers(EmbeddedServletContainerCustomizerBeanPostProcessor.java:77)
        at org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor.postProcessBeforeInitialization(EmbeddedServletContainerCustomizerBeanPostProcessor.java:67)
        at org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor.postProcessBeforeInitialization(EmbeddedServletContainerCustomizerBeanPostProcessor.java:54)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
        ... 14 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/hibernate/bytecode/instrumentation/internal/FieldInterceptionHelper
        at org.hibernate.jpa.internal.util.PersistenceUtilHelper.isLoadedWithoutReference(PersistenceUtilHelper.java:121)
        at org.hibernate.jpa.HibernatePersistenceProvider$1.isLoadedWithoutReference(HibernatePersistenceProvider.java:171)
        at javax.persistence.Persistence$1.isLoaded(Persistence.java:111)
        at org.hibernate.validator.internal.engine.resolver.JPATraversableResolver.isReachable(JPATraversableResolver.java:46)
        at org.hibernate.validator.internal.engine.resolver.DefaultTraversableResolver.isReachable(DefaultTraversableResolver.java:128)
        at org.hibernate.validator.internal.engine.resolver.CachingTraversableResolverForSingleValidation.isReachable(CachingTraversableResolverForSingleValidation.java:36)
        at org.hibernate.validator.internal.engine.ValidatorImpl.isReachable(ValidatorImpl.java:1612)
        at org.hibernate.validator.internal.engine.ValidatorImpl.isValidationRequired(ValidatorImpl.java:1597)
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:609)
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:580)
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForSingleDefaultGroupElement(ValidatorImpl.java:524)
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:492)
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:457)
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:407)
        at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:205)
        at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:94)
        at org.springframework.validation.DataBinder.validate(DataBinder.java:877)
        at org.springframework.boot.bind.PropertiesConfigurationFactory.validate(PropertiesConfigurationFactory.java:367)
        at org.springframework.boot.bind.PropertiesConfigurationFactory.doBindPropertiesToTarget(PropertiesConfigurationFactory.java:287)
        at org.springframework.boot.bind.PropertiesConfigurationFactory.bindPropertiesToTarget(PropertiesConfigurationFactory.java:256)
        at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:347)
        at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:303)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
        ... 27 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.hibernate.bytecode.instrumentation.internal.FieldInterceptionHelper
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 52 common frames omitted

Context failed to load: Error creating bean with name 'tomcatEmbeddedServletContainerFactory' defined in class path resource [org/springframework/boot/autoconfigure/web/EmbeddedServletContainerAutoConfiguration$EmbeddedTomcat.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serverProperties' defined in class path resource [org/springframework/boot/autoconfigure/web/ServerPropertiesAutoConfiguration.class]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/hibernate/bytecode/instrumentation/internal/FieldInterceptionHelper
:dbReverseEngineer FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':dbReverseEngineer'.
> Process 'command 'C:\Program Files\Java\jdk1.8.0_112\bin\java.exe'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 1 mins 15.591 secs
    

Manca nelle dipendenze "hibernate-entitymanager" che non viene inserito alla creazione del progetto.
Ho aggiunto quindi tale dipendenza, risolvendo l'eccezione "ClassNotFoundException". Ora il task riesce ad essere avviato. I problemi non sono finiti, pero': il task si blocca con il seguente errore:
C:\Users\Pippo\Documents\NetBeansProjects\MyProject>gradlew dbReverseEngineer
Starting a Gradle Daemon, 22 busy and 2 stopped Daemons could not be reused, use --status for details
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:buildProperties
:processResources UP-TO-DATE
:classes UP-TO-DATE
:findMainClass
:dbReverseEngineer
Starting database reverse engineering, connecting to 'jdbc:postgresql://10.60.[...]:5432/myDb?autoreconnect=true' as 'dbUser' ...
Command execution error: org.hibernate.cfg.Configuration.buildSettings(Lorg/hibernate/service/ServiceRegistry;)Lorg/hibernate/cfg/Settings;
:dbReverseEngineer FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':dbReverseEngineer'.
> Process 'command 'C:\Program Files\Java\jdk1.8.0_112\bin\java.exe'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 1 mins 57.592 secs
    

Effettuando un downgrade di Hibernate ad una versione 4 spariscono tutti gli errori, il task parte regolarmente e le classi di dominio vengono create nell'apposito package nella cartella "domains". Ovviamente potrebbero esserci errori nelle classi generate, dovuti a vari fattori come una errata configurazione del plugin. L'importante e' che le classi siano state generate, sollevandoci dalla fatica di crearle a mano una per una.


Hai trovato utile questo articolo?
Aiutami a condividerlo o metti un "mi piace".
Grazie mille!


Gli strumenti di condivisione (Google+, Facebook) sono visibili in alto a destra solo dopo aver accettato la policy di utilizzo dei cookie per questo sito.
FAQ - Come faccio a cambiare la mia scelta?

 

Strumenti (myjsp.feelinglinux.com)
Gioco: allenamento con la tastiera Strumenti di codifica/decodifica URI (%-encoding) e Base64 Strumenti di calcolo online per IP e Reti
QUIZ GAME
Quiz game

Cerca @myjsp.feelinglinux.com

Pubblicita'