SlideShare una empresa de Scribd logo
1 de 28
Descargar para leer sin conexión
GORM Optimization

Burt Beckwith
SpringSource




                                                  CONFIDENTIAL
                    © 2010 SpringSource, A division of VMware. All rights reserved
Agenda

 Mapping Database Views

 Writing a Custom Configuration Subclass for Fun and Profit

 Read-only Domain Classes

 Monitoring




                               CONFIDENTIAL                    2
Also See



 Advanced GORM - Performance, Customization and
 Monitoring

 • Spring One / class UserInfo {
                2GX 2010
                    String name
                    String orgName
 • http://www.infoq.com/presentations/GORM-Performance
                     static mapping = {
 • Primarily   focused on 'v_user_info'
                       table performance     implications around
                     }
                   }
  using Many-to-One and Many-to-Many in GORM



                              CONFIDENTIAL                         3
Mapping Database Views




         CONFIDENTIAL    4
Database View –> Entity


    class Organization {
      String name
    }


                                                class UserInfo {
                                                  String name
                                                  String orgName
                                                }
   class AuthUser {
     String name
     String password
     Organization organization
   }




                                 CONFIDENTIAL                      5
Database View –> Entity

   CREATE OR REPLACE VIEW v_user_info AS
   SELECT u.name, u.id, u.version, o.name org_name
   FROM auth_user u, organization o
   WHERE u.organization_id = o.id



                class UserInfo {
                   String name
                   String orgName

                    static mapping = {
                      table 'v_user_info'
                    }
                }




                                CONFIDENTIAL         6
Database View –> Entity


 ERROR hbm2ddl.SchemaExport  ­ 
 Unsuccessful: create table v_user_info (id 
 bigint not null auto_increment, version 
 bigint not null, name varchar(255) not 
 null, org_name varchar(255) not null, 
 primary key (id)) type=InnoDB

 ERROR hbm2ddl.SchemaExport  ­ Table 
 'v_user_info' already exists




                          CONFIDENTIAL         7
Database View –> Entity

Register a Custom Configuration in DataSource.groovy


         dataSource {
           pooled = true
           driverClassName = ...
           username = ...
           password = ...
           dialect = ...
           configClass = gr8conf.DdlFilterConfiguration
         }




                                  CONFIDENTIAL            8
Database View –> Entity

   public class DdlFilterConfiguration extends GrailsAnnotationConfiguration {

       private static final String[] IGNORED_NAMES = { "v_user_info" };
       ...
       private boolean isIgnored(String command) {
           command = command.toLowerCase();

           for (String table : IGNORED_NAMES) {
             if (command.startsWith("create table " + table + " ") ||
                 command.startsWith("alter table " + table + " ") ||
                 command.startsWith("drop table " + table) ||
                 command.startsWith("drop table if exists " + table)) {
                return true;
             }
           }

           return false;
       }
   }

                                           CONFIDENTIAL                          9
Database View –> Entity


      grails-app/conf/hibernate/hibernate.cfg.xml


    <hibernate­configuration>

       <session­factory>

          <mapping resource='misc.mysql.innodb.hbm.xml'/>

          <mapping resource='misc.h2.hbm.xml'/>

       </session­factory>

    </hibernate­configuration>




                            CONFIDENTIAL                    10
Database View –> Entity

     grails-app/conf/hibernate/misc.mysql.innodb.hbm.xml

    <hibernate­mapping>
       <database­object>

          <create>
             CREATE OR REPLACE VIEW v_user_info AS
             SELECT u.name, u.id, u.version, o.name org_name
             FROM auth_user u, organization o
             WHERE u.organization_id = o.id
          </create>

          <drop>DROP VIEW IF EXISTS v_user_info</drop>

          <dialect­scope
              name='org.hibernate.dialect.MySQLInnoDBDialect' />

       </database­object>
    </hibernate­mapping>



                              CONFIDENTIAL                         11
Subdomain Entity


      “Subdomain” with a subset of AuthUser data:


               class Person {
                 String name
                 Organization organization

                   static mapping = {
                     table 'auth_user'
                   }
               }




                                 CONFIDENTIAL       12
Subdomain Entity


      Updatable Subdomain:


               class Person {
                 String name
                 Organization organization

                   static mapping = {
                     table 'auth_user'
                     dynamicUpdate true
                   }
               }




                               CONFIDENTIAL   13
Writing a Custom Configuration Subclass for
               Fun and Profit




                   CONFIDENTIAL               14
Writing a Custom Configuration Subclass for Fun and Profit

Custom Configurations: http://burtbeckwith.com/blog/?p=465
 Examples
  • Previous SQL generation example
    • Overrides generateSchemaCreationScript(),
      generateDropSchemaScript(), and generateSchemaUpdateScript()
  • Specifying the 'connection.provider_class' property
    • Overrides buildSettings()
  • Renaming columns of a composite foreign key
    • Overrides secondPassCompile()
  • Overriding the EntityPersister class
    • Overrides secondPassCompile()
  • Using field access
    • Overrides secondPassCompile()



                                       CONFIDENTIAL                  15
Writing a Custom Configuration Subclass for Fun and Profit


 secondPassCompile()
  • Access each PersistentClass/RootClass and call any of
   • addFilter()              • setDynamicUpdate()
   • setBatchSize()           • setExplicitPolymorphism()
   • setCustomSQLDelete()     • setOptimisticLockMode()
   • setCustomSQLInsert()     • setSelectBeforeUpdate()
   • setCustomSQLUpdate()     • setWhere()
   • setDynamicInsert()




                                 CONFIDENTIAL                16
Read-only Domain Classes




          CONFIDENTIAL     17
Read-only Domain Classes

 Not 100% possible, but close enough

 Hibernate

 • Seems possible via setMutable(false) in a custom Configuration, but:


   • Won't block saves or deletes, only disables dirty-check updates

   • Does nothing with collections since they're a PersistentSet or
    PersistentList and managed separately (but you wouldn't want to map
    collections anyway, right?)

   • See http://docs.jboss.org/hibernate/core/3.5/reference/en/html/readonly.html



                                     CONFIDENTIAL                                   18
Read-only Domain Classes

 Grails

 • Only beforeUpdate supports 'vetoing' by returning false


 • A hackish solution would be to throw an exception in beforeDelete and
   beforeInsert


 • Better solution: hibernateEventListeners bean in grails­
   app/conf/spring/resources.groovy


 • Still a good idea to use a custom Configuration and call setMutable(false)
   to reduce memory usage




                                   CONFIDENTIAL                                 19
Read-only Domain Classes


      grails-app/conf/spring/resources.groovy

    import gr8conf.ReadOnlyEventListener

    import o.c.g.g.orm.hibernate.HibernateEventListeners

    beans = {

       readOnlyEventListener(ReadOnlyEventListener)

       hibernateEventListeners(HibernateEventListeners) {
          listenerMap = ['pre­delete': readOnlyEventListener,
                         'pre­insert': readOnlyEventListener,
                         'pre­update': readOnlyEventListener]
       }
    }




                               CONFIDENTIAL                     20
Read-only Domain Classes

   src/groovy/gr8conf/ReadOnlyEventListener.groovy
   class ReadOnlyEventListener implements PreDeleteEventListener,
            PreInsertEventListener, PreUpdateEventListener {

    private static final List<String> READ_ONLY = ['gr8conf.LegacyData']

    boolean onPreDelete(PreDeleteEvent event) {
       isReadOnly event.persister.entityName
    }

    boolean onPreInsert(PreInsertEvent event) {
       isReadOnly event.persister.entityName
    }

    boolean onPreUpdate(PreUpdateEvent event) {
       isReadOnly event.persister.entityName
    }

    private boolean isReadOnly(String name) { READ_ONLY.contains name }
   }



                                CONFIDENTIAL                               21
Read-only Domain Classes


   grails-app/domain/gr8conf/LegacyData.groovy


                class LegacyData {

                   String name

                   static mapping = {
                      id column: 'legacy_data_id'
                      version false
                   }
                }




                            CONFIDENTIAL            22
Read-only Domain Classes

 ReadOnlyEventListener

 • delete()
   • silently fails


 • Update with save()
   • silently fails


 • New instance save()
   • Throws exception    ?




                             CONFIDENTIAL   23
Read-only Domain Classes


   You can also map a second writable domain class
   to the same table, e.g. for admin:

   class User {                           class WritableUser {

      String username                        String username
      String password                        String password
   }
                                             static mapping = {
                                                table 'user'
                                             }
                                          }




                           CONFIDENTIAL                           24
Monitoring




   CONFIDENTIAL   25
Monitoring

 SQL logging
 • logSql=true in DataSource.groovy
 • org.hibernate.SQL → debug, org.hibernate.type → trace
     appenders {
        file name: 'sql', file: 'sql.log'
     }

     debug additivity: false, sql: 'org.hibernate.SQL'
     trace additivity: false, sql: 'org.hibernate.type'

 • P6spy plugin
   • Use SQL Profiler Swing app to view realtime logs; see Mike Hugo's blog post
    Grails, p6spy and Sql Profiler
 • Run explain (Oracle, MySQL, others) on real queries to look for missing indexes




                                         CONFIDENTIAL                                26
Monitoring


 Spring Insight lets you drill down to SQL and view timing
 • http://www.grails.org/screencast/show/13

 Profiler plugin can give you timing data
 JavaMelody Plugin
 App Info plugin




                                 CONFIDENTIAL                 27
Questions?




   CONFIDENTIAL   28

Más contenido relacionado

La actualidad más candente

Top5 scalabilityissues withappendix
Top5 scalabilityissues withappendixTop5 scalabilityissues withappendix
Top5 scalabilityissues withappendix
ColdFusionConference
 
07 association of entities
07 association of entities07 association of entities
07 association of entities
thirumuru2012
 
Spring design-juergen-qcon
Spring design-juergen-qconSpring design-juergen-qcon
Spring design-juergen-qcon
Yiwei Ma
 
database-querry-student-note
database-querry-student-notedatabase-querry-student-note
database-querry-student-note
Leerpiny Makouach
 
05 qmds2005 session07
05 qmds2005 session0705 qmds2005 session07
05 qmds2005 session07
Niit Care
 
Taking Apache Camel For a Ride
Taking Apache Camel For a RideTaking Apache Camel For a Ride
Taking Apache Camel For a Ride
Bruce Snyder
 

La actualidad más candente (20)

Top5 scalabilityissues withappendix
Top5 scalabilityissues withappendixTop5 scalabilityissues withappendix
Top5 scalabilityissues withappendix
 
My sql tutorial-oscon-2012
My sql tutorial-oscon-2012My sql tutorial-oscon-2012
My sql tutorial-oscon-2012
 
07 association of entities
07 association of entities07 association of entities
07 association of entities
 
Developing for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQLDeveloping for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQL
 
Manage users & tables in Oracle Database
Manage users & tables in Oracle DatabaseManage users & tables in Oracle Database
Manage users & tables in Oracle Database
 
Spring design-juergen-qcon
Spring design-juergen-qconSpring design-juergen-qcon
Spring design-juergen-qcon
 
database-querry-student-note
database-querry-student-notedatabase-querry-student-note
database-querry-student-note
 
Managing users & tables using Oracle Enterprise Manage
Managing users & tables using Oracle Enterprise ManageManaging users & tables using Oracle Enterprise Manage
Managing users & tables using Oracle Enterprise Manage
 
05 qmds2005 session07
05 qmds2005 session0705 qmds2005 session07
05 qmds2005 session07
 
Lecture17
Lecture17Lecture17
Lecture17
 
Cloudera Impala, updated for v1.0
Cloudera Impala, updated for v1.0Cloudera Impala, updated for v1.0
Cloudera Impala, updated for v1.0
 
Java &amp; banco de dados
Java &amp; banco de dadosJava &amp; banco de dados
Java &amp; banco de dados
 
Validating JSON -- Percona Live 2021 presentation
Validating JSON -- Percona Live 2021 presentationValidating JSON -- Percona Live 2021 presentation
Validating JSON -- Percona Live 2021 presentation
 
12c db upgrade from 11.2.0.4
12c db upgrade from 11.2.0.412c db upgrade from 11.2.0.4
12c db upgrade from 11.2.0.4
 
Database administration
Database administrationDatabase administration
Database administration
 
Taking Apache Camel For a Ride
Taking Apache Camel For a RideTaking Apache Camel For a Ride
Taking Apache Camel For a Ride
 
Android Data Persistence
Android Data PersistenceAndroid Data Persistence
Android Data Persistence
 
User, roles and privileges
User, roles and privilegesUser, roles and privileges
User, roles and privileges
 
B13 Investigating oracle by Julian Dyke
B13 Investigating oracle by Julian DykeB13 Investigating oracle by Julian Dyke
B13 Investigating oracle by Julian Dyke
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 

Similar a GR8Conf 2011: GORM Optimization

Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentation
guest11106b
 
Developing your first application using FI-WARE
Developing your first application using FI-WAREDeveloping your first application using FI-WARE
Developing your first application using FI-WARE
Fermin Galan
 
Groovygrailsnetbeans 12517452668498-phpapp03
Groovygrailsnetbeans 12517452668498-phpapp03Groovygrailsnetbeans 12517452668498-phpapp03
Groovygrailsnetbeans 12517452668498-phpapp03
Kevin Juma
 
GR8Conf 2011: Grails, how to plug in
GR8Conf 2011: Grails, how to plug inGR8Conf 2011: Grails, how to plug in
GR8Conf 2011: Grails, how to plug in
GR8Conf
 
Symfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 IntegrationSymfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 Integration
Jonathan Wage
 

Similar a GR8Conf 2011: GORM Optimization (20)

Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
Data binding в массы!
Data binding в массы!Data binding в массы!
Data binding в массы!
 
Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentation
 
Hibernate
Hibernate Hibernate
Hibernate
 
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
 
Spring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in HeavenSpring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in Heaven
 
2) security
2) security2) security
2) security
 
Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...
 
Dropwizard
DropwizardDropwizard
Dropwizard
 
Yii Introduction
Yii IntroductionYii Introduction
Yii Introduction
 
Code Igniter 2
Code Igniter 2Code Igniter 2
Code Igniter 2
 
Developing your first application using FI-WARE
Developing your first application using FI-WAREDeveloping your first application using FI-WARE
Developing your first application using FI-WARE
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven Development
 
Play 2.0
Play 2.0Play 2.0
Play 2.0
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
Groovygrailsnetbeans 12517452668498-phpapp03
Groovygrailsnetbeans 12517452668498-phpapp03Groovygrailsnetbeans 12517452668498-phpapp03
Groovygrailsnetbeans 12517452668498-phpapp03
 
GR8Conf 2011: Grails, how to plug in
GR8Conf 2011: Grails, how to plug inGR8Conf 2011: Grails, how to plug in
GR8Conf 2011: Grails, how to plug in
 
Symfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 IntegrationSymfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 Integration
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The Browser
 
Config/BuildConfig
Config/BuildConfigConfig/BuildConfig
Config/BuildConfig
 

Más de GR8Conf

Más de GR8Conf (20)

DevOps Enabling Your Team
DevOps Enabling Your TeamDevOps Enabling Your Team
DevOps Enabling Your Team
 
Creating and testing REST contracts with Accurest Gradle
Creating and testing REST contracts with Accurest Gradle Creating and testing REST contracts with Accurest Gradle
Creating and testing REST contracts with Accurest Gradle
 
Mum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developerMum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developer
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with Groovy
 
Scraping with Geb
Scraping with GebScraping with Geb
Scraping with Geb
 
How to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and AndroidHow to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and Android
 
Ratpack On the Docks
Ratpack On the DocksRatpack On the Docks
Ratpack On the Docks
 
Groovy Powered Clean Code
Groovy Powered Clean CodeGroovy Powered Clean Code
Groovy Powered Clean Code
 
Cut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature pluginsCut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature plugins
 
Performance tuning Grails applications
 Performance tuning Grails applications Performance tuning Grails applications
Performance tuning Grails applications
 
Ratpack and Grails 3
 Ratpack and Grails 3 Ratpack and Grails 3
Ratpack and Grails 3
 
Grails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloudGrails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloud
 
Functional testing your Grails app with GEB
Functional testing your Grails app with GEBFunctional testing your Grails app with GEB
Functional testing your Grails app with GEB
 
Deploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPCDeploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPC
 
The Grails introduction workshop
The Grails introduction workshopThe Grails introduction workshop
The Grails introduction workshop
 
Idiomatic spock
Idiomatic spockIdiomatic spock
Idiomatic spock
 
The Groovy Ecosystem Revisited
The Groovy Ecosystem RevisitedThe Groovy Ecosystem Revisited
The Groovy Ecosystem Revisited
 
Groovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examplesGroovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examples
 
Integration using Apache Camel and Groovy
Integration using Apache Camel and GroovyIntegration using Apache Camel and Groovy
Integration using Apache Camel and Groovy
 
CRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual MachineCRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual Machine
 

Último

Challenges and Opportunities: A Qualitative Study on Tax Compliance in Pakistan
Challenges and Opportunities: A Qualitative Study on Tax Compliance in PakistanChallenges and Opportunities: A Qualitative Study on Tax Compliance in Pakistan
Challenges and Opportunities: A Qualitative Study on Tax Compliance in Pakistan
vineshkumarsajnani12
 
Jual Obat Aborsi ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan Cytotec
Jual Obat Aborsi ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan CytotecJual Obat Aborsi ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan Cytotec
Jual Obat Aborsi ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan Cytotec
ZurliaSoop
 
Al Mizhar Dubai Escorts +971561403006 Escorts Service In Al Mizhar
Al Mizhar Dubai Escorts +971561403006 Escorts Service In Al MizharAl Mizhar Dubai Escorts +971561403006 Escorts Service In Al Mizhar
Al Mizhar Dubai Escorts +971561403006 Escorts Service In Al Mizhar
allensay1
 

Último (20)

Challenges and Opportunities: A Qualitative Study on Tax Compliance in Pakistan
Challenges and Opportunities: A Qualitative Study on Tax Compliance in PakistanChallenges and Opportunities: A Qualitative Study on Tax Compliance in Pakistan
Challenges and Opportunities: A Qualitative Study on Tax Compliance in Pakistan
 
Kalyan Call Girl 98350*37198 Call Girls in Escort service book now
Kalyan Call Girl 98350*37198 Call Girls in Escort service book nowKalyan Call Girl 98350*37198 Call Girls in Escort service book now
Kalyan Call Girl 98350*37198 Call Girls in Escort service book now
 
Berhampur Call Girl Just Call 8084732287 Top Class Call Girl Service Available
Berhampur Call Girl Just Call 8084732287 Top Class Call Girl Service AvailableBerhampur Call Girl Just Call 8084732287 Top Class Call Girl Service Available
Berhampur Call Girl Just Call 8084732287 Top Class Call Girl Service Available
 
Organizational Transformation Lead with Culture
Organizational Transformation Lead with CultureOrganizational Transformation Lead with Culture
Organizational Transformation Lead with Culture
 
Berhampur 70918*19311 CALL GIRLS IN ESCORT SERVICE WE ARE PROVIDING
Berhampur 70918*19311 CALL GIRLS IN ESCORT SERVICE WE ARE PROVIDINGBerhampur 70918*19311 CALL GIRLS IN ESCORT SERVICE WE ARE PROVIDING
Berhampur 70918*19311 CALL GIRLS IN ESCORT SERVICE WE ARE PROVIDING
 
joint cost.pptx COST ACCOUNTING Sixteenth Edition ...
joint cost.pptx  COST ACCOUNTING  Sixteenth Edition                          ...joint cost.pptx  COST ACCOUNTING  Sixteenth Edition                          ...
joint cost.pptx COST ACCOUNTING Sixteenth Edition ...
 
Falcon Invoice Discounting: Unlock Your Business Potential
Falcon Invoice Discounting: Unlock Your Business PotentialFalcon Invoice Discounting: Unlock Your Business Potential
Falcon Invoice Discounting: Unlock Your Business Potential
 
Ooty Call Gril 80022//12248 Only For Sex And High Profile Best Gril Sex Avail...
Ooty Call Gril 80022//12248 Only For Sex And High Profile Best Gril Sex Avail...Ooty Call Gril 80022//12248 Only For Sex And High Profile Best Gril Sex Avail...
Ooty Call Gril 80022//12248 Only For Sex And High Profile Best Gril Sex Avail...
 
WheelTug Short Pitch Deck 2024 | Byond Insights
WheelTug Short Pitch Deck 2024 | Byond InsightsWheelTug Short Pitch Deck 2024 | Byond Insights
WheelTug Short Pitch Deck 2024 | Byond Insights
 
Dr. Admir Softic_ presentation_Green Club_ENG.pdf
Dr. Admir Softic_ presentation_Green Club_ENG.pdfDr. Admir Softic_ presentation_Green Club_ENG.pdf
Dr. Admir Softic_ presentation_Green Club_ENG.pdf
 
Getting Real with AI - Columbus DAW - May 2024 - Nick Woo from AlignAI
Getting Real with AI - Columbus DAW - May 2024 - Nick Woo from AlignAIGetting Real with AI - Columbus DAW - May 2024 - Nick Woo from AlignAI
Getting Real with AI - Columbus DAW - May 2024 - Nick Woo from AlignAI
 
Nashik Call Girl Just Call 7091819311 Top Class Call Girl Service Available
Nashik Call Girl Just Call 7091819311 Top Class Call Girl Service AvailableNashik Call Girl Just Call 7091819311 Top Class Call Girl Service Available
Nashik Call Girl Just Call 7091819311 Top Class Call Girl Service Available
 
PARK STREET 💋 Call Girl 9827461493 Call Girls in Escort service book now
PARK STREET 💋 Call Girl 9827461493 Call Girls in  Escort service book nowPARK STREET 💋 Call Girl 9827461493 Call Girls in  Escort service book now
PARK STREET 💋 Call Girl 9827461493 Call Girls in Escort service book now
 
Cannabis Legalization World Map: 2024 Updated
Cannabis Legalization World Map: 2024 UpdatedCannabis Legalization World Map: 2024 Updated
Cannabis Legalization World Map: 2024 Updated
 
Paradip CALL GIRL❤7091819311❤CALL GIRLS IN ESCORT SERVICE WE ARE PROVIDING
Paradip CALL GIRL❤7091819311❤CALL GIRLS IN ESCORT SERVICE WE ARE PROVIDINGParadip CALL GIRL❤7091819311❤CALL GIRLS IN ESCORT SERVICE WE ARE PROVIDING
Paradip CALL GIRL❤7091819311❤CALL GIRLS IN ESCORT SERVICE WE ARE PROVIDING
 
Durg CALL GIRL ❤ 82729*64427❤ CALL GIRLS IN durg ESCORTS
Durg CALL GIRL ❤ 82729*64427❤ CALL GIRLS IN durg ESCORTSDurg CALL GIRL ❤ 82729*64427❤ CALL GIRLS IN durg ESCORTS
Durg CALL GIRL ❤ 82729*64427❤ CALL GIRLS IN durg ESCORTS
 
Jual Obat Aborsi ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan Cytotec
Jual Obat Aborsi ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan CytotecJual Obat Aborsi ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan Cytotec
Jual Obat Aborsi ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan Cytotec
 
Al Mizhar Dubai Escorts +971561403006 Escorts Service In Al Mizhar
Al Mizhar Dubai Escorts +971561403006 Escorts Service In Al MizharAl Mizhar Dubai Escorts +971561403006 Escorts Service In Al Mizhar
Al Mizhar Dubai Escorts +971561403006 Escorts Service In Al Mizhar
 
Falcon Invoice Discounting: Empowering Your Business Growth
Falcon Invoice Discounting: Empowering Your Business GrowthFalcon Invoice Discounting: Empowering Your Business Growth
Falcon Invoice Discounting: Empowering Your Business Growth
 
GUWAHATI 💋 Call Girl 9827461493 Call Girls in Escort service book now
GUWAHATI 💋 Call Girl 9827461493 Call Girls in  Escort service book nowGUWAHATI 💋 Call Girl 9827461493 Call Girls in  Escort service book now
GUWAHATI 💋 Call Girl 9827461493 Call Girls in Escort service book now
 

GR8Conf 2011: GORM Optimization

  • 1. GORM Optimization Burt Beckwith SpringSource CONFIDENTIAL © 2010 SpringSource, A division of VMware. All rights reserved
  • 2. Agenda  Mapping Database Views  Writing a Custom Configuration Subclass for Fun and Profit  Read-only Domain Classes  Monitoring CONFIDENTIAL 2
  • 3. Also See  Advanced GORM - Performance, Customization and Monitoring • Spring One / class UserInfo { 2GX 2010 String name String orgName • http://www.infoq.com/presentations/GORM-Performance static mapping = { • Primarily focused on 'v_user_info' table performance implications around } } using Many-to-One and Many-to-Many in GORM CONFIDENTIAL 3
  • 4. Mapping Database Views CONFIDENTIAL 4
  • 5. Database View –> Entity class Organization { String name } class UserInfo { String name String orgName } class AuthUser { String name String password Organization organization } CONFIDENTIAL 5
  • 6. Database View –> Entity CREATE OR REPLACE VIEW v_user_info AS SELECT u.name, u.id, u.version, o.name org_name FROM auth_user u, organization o WHERE u.organization_id = o.id class UserInfo { String name String orgName static mapping = { table 'v_user_info' } } CONFIDENTIAL 6
  • 7. Database View –> Entity ERROR hbm2ddl.SchemaExport  ­  Unsuccessful: create table v_user_info (id  bigint not null auto_increment, version  bigint not null, name varchar(255) not  null, org_name varchar(255) not null,  primary key (id)) type=InnoDB ERROR hbm2ddl.SchemaExport  ­ Table  'v_user_info' already exists CONFIDENTIAL 7
  • 8. Database View –> Entity Register a Custom Configuration in DataSource.groovy dataSource { pooled = true driverClassName = ... username = ... password = ... dialect = ... configClass = gr8conf.DdlFilterConfiguration } CONFIDENTIAL 8
  • 9. Database View –> Entity public class DdlFilterConfiguration extends GrailsAnnotationConfiguration { private static final String[] IGNORED_NAMES = { "v_user_info" }; ... private boolean isIgnored(String command) { command = command.toLowerCase(); for (String table : IGNORED_NAMES) { if (command.startsWith("create table " + table + " ") || command.startsWith("alter table " + table + " ") || command.startsWith("drop table " + table) || command.startsWith("drop table if exists " + table)) { return true; } } return false; } } CONFIDENTIAL 9
  • 10. Database View –> Entity grails-app/conf/hibernate/hibernate.cfg.xml <hibernate­configuration>    <session­factory>       <mapping resource='misc.mysql.innodb.hbm.xml'/>       <mapping resource='misc.h2.hbm.xml'/>    </session­factory> </hibernate­configuration> CONFIDENTIAL 10
  • 11. Database View –> Entity grails-app/conf/hibernate/misc.mysql.innodb.hbm.xml <hibernate­mapping>    <database­object>       <create>          CREATE OR REPLACE VIEW v_user_info AS          SELECT u.name, u.id, u.version, o.name org_name          FROM auth_user u, organization o          WHERE u.organization_id = o.id       </create>       <drop>DROP VIEW IF EXISTS v_user_info</drop>       <dialect­scope           name='org.hibernate.dialect.MySQLInnoDBDialect' />    </database­object> </hibernate­mapping> CONFIDENTIAL 11
  • 12. Subdomain Entity “Subdomain” with a subset of AuthUser data: class Person { String name Organization organization static mapping = { table 'auth_user' } } CONFIDENTIAL 12
  • 13. Subdomain Entity Updatable Subdomain: class Person { String name Organization organization static mapping = { table 'auth_user' dynamicUpdate true } } CONFIDENTIAL 13
  • 14. Writing a Custom Configuration Subclass for Fun and Profit CONFIDENTIAL 14
  • 15. Writing a Custom Configuration Subclass for Fun and Profit Custom Configurations: http://burtbeckwith.com/blog/?p=465  Examples • Previous SQL generation example • Overrides generateSchemaCreationScript(), generateDropSchemaScript(), and generateSchemaUpdateScript() • Specifying the 'connection.provider_class' property • Overrides buildSettings() • Renaming columns of a composite foreign key • Overrides secondPassCompile() • Overriding the EntityPersister class • Overrides secondPassCompile() • Using field access • Overrides secondPassCompile() CONFIDENTIAL 15
  • 16. Writing a Custom Configuration Subclass for Fun and Profit  secondPassCompile() • Access each PersistentClass/RootClass and call any of • addFilter() • setDynamicUpdate() • setBatchSize() • setExplicitPolymorphism() • setCustomSQLDelete() • setOptimisticLockMode() • setCustomSQLInsert() • setSelectBeforeUpdate() • setCustomSQLUpdate() • setWhere() • setDynamicInsert() CONFIDENTIAL 16
  • 17. Read-only Domain Classes CONFIDENTIAL 17
  • 18. Read-only Domain Classes  Not 100% possible, but close enough  Hibernate • Seems possible via setMutable(false) in a custom Configuration, but: • Won't block saves or deletes, only disables dirty-check updates • Does nothing with collections since they're a PersistentSet or PersistentList and managed separately (but you wouldn't want to map collections anyway, right?) • See http://docs.jboss.org/hibernate/core/3.5/reference/en/html/readonly.html CONFIDENTIAL 18
  • 19. Read-only Domain Classes  Grails • Only beforeUpdate supports 'vetoing' by returning false • A hackish solution would be to throw an exception in beforeDelete and beforeInsert • Better solution: hibernateEventListeners bean in grails­ app/conf/spring/resources.groovy • Still a good idea to use a custom Configuration and call setMutable(false) to reduce memory usage CONFIDENTIAL 19
  • 20. Read-only Domain Classes grails-app/conf/spring/resources.groovy import gr8conf.ReadOnlyEventListener import o.c.g.g.orm.hibernate.HibernateEventListeners beans = {    readOnlyEventListener(ReadOnlyEventListener)    hibernateEventListeners(HibernateEventListeners) {       listenerMap = ['pre­delete': readOnlyEventListener,                      'pre­insert': readOnlyEventListener,                      'pre­update': readOnlyEventListener]    } } CONFIDENTIAL 20
  • 21. Read-only Domain Classes src/groovy/gr8conf/ReadOnlyEventListener.groovy class ReadOnlyEventListener implements PreDeleteEventListener,          PreInsertEventListener, PreUpdateEventListener {  private static final List<String> READ_ONLY = ['gr8conf.LegacyData']  boolean onPreDelete(PreDeleteEvent event) {     isReadOnly event.persister.entityName  }  boolean onPreInsert(PreInsertEvent event) {     isReadOnly event.persister.entityName  }  boolean onPreUpdate(PreUpdateEvent event) {     isReadOnly event.persister.entityName  }  private boolean isReadOnly(String name) { READ_ONLY.contains name } } CONFIDENTIAL 21
  • 22. Read-only Domain Classes grails-app/domain/gr8conf/LegacyData.groovy class LegacyData {    String name    static mapping = {       id column: 'legacy_data_id'       version false    } } CONFIDENTIAL 22
  • 23. Read-only Domain Classes  ReadOnlyEventListener • delete() • silently fails • Update with save() • silently fails • New instance save() • Throws exception ? CONFIDENTIAL 23
  • 24. Read-only Domain Classes You can also map a second writable domain class to the same table, e.g. for admin: class User { class WritableUser {    String username    String username    String password    String password }    static mapping = {       table 'user'    } } CONFIDENTIAL 24
  • 25. Monitoring CONFIDENTIAL 25
  • 26. Monitoring  SQL logging • logSql=true in DataSource.groovy • org.hibernate.SQL → debug, org.hibernate.type → trace appenders {    file name: 'sql', file: 'sql.log' } debug additivity: false, sql: 'org.hibernate.SQL' trace additivity: false, sql: 'org.hibernate.type' • P6spy plugin • Use SQL Profiler Swing app to view realtime logs; see Mike Hugo's blog post Grails, p6spy and Sql Profiler • Run explain (Oracle, MySQL, others) on real queries to look for missing indexes CONFIDENTIAL 26
  • 27. Monitoring  Spring Insight lets you drill down to SQL and view timing • http://www.grails.org/screencast/show/13  Profiler plugin can give you timing data  JavaMelody Plugin  App Info plugin CONFIDENTIAL 27
  • 28. Questions? CONFIDENTIAL 28