Closed pgutierrezn2 closed 1 year ago
I tried to run it, but it fails with:
>grailsw
Error opening zip file or JAR manifest missing : wrapper/springloaded-1.2.7.RELEASE.jar
Error occurred during initialization of VM
agent library failed to init: instrument
I created this GitHub repository for Grails and Hibernate 4.
@pgutierrezn2 So, this repository shows how Hypersistence Optimizer works on this Grails app with Hibernate 4.3.
If you run the application, it will generate the following events:
ERROR Hypersistence Optimizer - CRITICAL - IdentityGeneratorEvent - The [id] identifier attribute in the [org.grails.samples.Visit] entity uses the [IdentityGenerator] strategy, which prevents Hibernate from enabling JDBC batch inserts. Consider using the SEQUENCE identifier strategy instead. For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#IdentityGeneratorEvent
ERROR Hypersistence Optimizer - CRITICAL - IdentityGeneratorEvent - The [id] identifier attribute in the [org.grails.samples.Pet] entity uses the [IdentityGenerator] strategy, which prevents Hibernate from enabling JDBC batch inserts. Consider using the SEQUENCE identifier strategy instead. For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#IdentityGeneratorEvent
ERROR Hypersistence Optimizer - CRITICAL - BidirectionalSynchronizationEvent - The [visits] bidirectional association in the [org.grails.samples.Pet] entity requires both ends to be synchronized. Consider adding the [addVisit(org.grails.samples.Visit visit)] and [removeVisit(org.grails.samples.Visit visit)] synchronization methods. For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#BidirectionalSynchronizationEvent
ERROR Hypersistence Optimizer - CRITICAL - IdentityGeneratorEvent - The [id] identifier attribute in the [org.grails.samples.Owner] entity uses the [IdentityGenerator] strategy, which prevents Hibernate from enabling JDBC batch inserts. Consider using the SEQUENCE identifier strategy instead. For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#IdentityGeneratorEvent
ERROR Hypersistence Optimizer - CRITICAL - BidirectionalSynchronizationEvent - The [pets] bidirectional association in the [org.grails.samples.Owner] entity requires both ends to be synchronized. Consider adding the [addPet(org.grails.samples.Pet pet)] and [removePet(org.grails.samples.Pet pet)] synchronization methods. For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#BidirectionalSynchronizationEvent
ERROR Hypersistence Optimizer - CRITICAL - IdentityGeneratorEvent - The [id] identifier attribute in the [org.grails.samples.Person] entity uses the [IdentityGenerator] strategy, which prevents Hibernate from enabling JDBC batch inserts. Consider using the SEQUENCE identifier strategy instead. For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#IdentityGeneratorEvent
ERROR Hypersistence Optimizer - CRITICAL - IdentityGeneratorEvent - The [id] identifier attribute in the [org.grails.samples.Vet] entity uses the [IdentityGenerator] strategy, which prevents Hibernate from enabling JDBC batch inserts. Consider using the SEQUENCE identifier strategy instead. For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#IdentityGeneratorEvent
ERROR Hypersistence Optimizer - CRITICAL - IdentityGeneratorEvent - The [id] identifier attribute in the [org.grails.samples.PetType] entity uses the [IdentityGenerator] strategy, which prevents Hibernate from enabling JDBC batch inserts. Consider using the SEQUENCE identifier strategy instead. For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#IdentityGeneratorEvent
ERROR Hypersistence Optimizer - CRITICAL - IdentityGeneratorEvent - The [id] identifier attribute in the [org.grails.samples.Speciality] entity uses the [IdentityGenerator] strategy, which prevents Hibernate from enabling JDBC batch inserts. Consider using the SEQUENCE identifier strategy instead. For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#IdentityGeneratorEvent
ERROR Hypersistence Optimizer - CRITICAL - JdbcBatchSizeEvent - If you set the [hibernate.jdbc.batch_size] configuration property to a value greater than 1 (usually between 5 and 30), Hibernate can then execute SQL statements in batches, therefore reducing the number of database network roundtrips. For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#JdbcBatchSizeEvent
ERROR Hypersistence Optimizer - CRITICAL - JdbcFetchSizeEvent - If you set the [hibernate.jdbc.fetch_size] configuration property to a value greater than the current value of [100], then Hibernate will use fewer database network roundtrips to fetch a JDBC ResultSet and transform it to a List of entities, DTOs or scalar types. For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#JdbcFetchSizeEvent
ERROR Hypersistence Optimizer - BLOCKER - SchemaGenerationEvent - You should not set the [hibernate.hbm2ddl.auto] configuration property to the value of [create-drop], as Hibernate will then manage the database schema for you. Instead, you should use an incremental schema migration tool (e.g., Flyway, Liquibase), which allows you to use any database-specific DDL construct. By storing the migration scripts in the Version Control System along with the application source code, you will always remember why a certain schema change was done. For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#SchemaGenerationEvent
ERROR Hypersistence Optimizer - BLOCKER - PooledSequenceOptimizerEvent - You should set the [hibernate.id.new_generator_mappings] configuration property to the value of [true], as Hibernate can then use the pooled or pooled-lo identifier optimizers for sequence-based entity identifiers. Note that the pooled and pooled-lo optimizers are not backward compatible with the legacy hilo optimizer that you might have used with Hibernate ORM 3 or 4. So, if you were using the hilo optimizer, then you would need to increase the current sequence number so that is greater than any previously allocated entity identifiers. For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#PooledSequenceOptimizerEvent
ERROR Hypersistence Optimizer - CRITICAL - DefaultQueryPlanCacheMaxSizeEvent - You should set the [hibernate.query.plan_cache_max_size] configuration property to a value that allows you to hold all JPQL, Criteria API, or SQL queries executed with Hibernate. The default query plan cache size is [2048] and might not be enough for a non-trivial application. For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#DefaultQueryPlanCacheMaxSizeEvent
Please, correct me if I'm wrong, but isn't the RuntimeScanner disabled in this example?
The Runtime scanner is enabled by default, so unless explicitly disabled, it should be active when you bootstrap the application.
Ok, it is enabled by default, but then, none of the Runtime events has been identified as critical/blocker in this example, right?
However, with the current configuration (I understand the sessionFactory provided by Grails is not being decorated), it is still able to generate Runtime events?
@pgutierrezn2 I tried to decorate the SessionFactory
:
sessionFactory(HypersistenceConfigurableLocalSessionFactoryBean) {
dataSource = ref('dataSource')
hibernateProperties = ref('hibernateProperties')
grailsApplication = ref('grailsApplication')
}
But it looks like Grails uses some hard-coded SessionFactoryImpl
castings:
ConnectionProvider connectionProvider = ((SessionFactoryImpl) sessionFactory).getServiceRegistry().getService(ConnectionProvider.class);
So, only the Configuration and Mapping scanners will work.
Now I understand. Thanks for your effort It's been a pleasure
You're welcome. The good news is that you can still detect a lot of issues with mapping and configs even on older Grails apps.
Sure, we'll buy one to test it further. Thanks
Enjoy using it. Hopefully, newer Grails versions use the Hibernate interfsces, like SessionFactory
, instead of casting to implementation classes that are now in the internal packages.
Thanks, I'll review it when I have some time.