EnkiHibernateMultipleMetamodels

From LucidDB Wiki
Jump to: navigation, search

Presently this page just a set of notes about the changes necessary to support multiple instances of the same metamodel in a single database schema.

Contents

Assumptions

This document makes the following assumptions:

  1. The metamodel instances have distinct extent names. Farrago, for example, always uses "FarragoMetamodel" and "FarragoCatalog". Farrago extensions (e.g., SQLStream or LucidEra ALS) do the same. Multiple Farrago/extension instances, therefore, cannot share a database unless the extent names are made distinct.
  2. The metamodel instances are configured with different table prefixes. This requires making the table name prefix a storage property rather than something that is burned into the metamodel.
  3. Multiple instances of the same metamodel are loaded in separate HibernateMDRepository instances. That is, Enki/Hibernate supports multiple extents via a single repository object, but they must be based on different metamodels.

Multiple Metamodel Instances Design

Make Table Prefix a Storage Property

  1. During code generation, strip the table prefix from the following methods (listed by abstract method implemented by code gen):
    • org.eigenbase.enki.hibernate.jmi.HibernateRefAssociation
      • getTable()
      • getCollectionTable()
    • org.eigenbase.enki.hibernate.storage.HibernateAssociation
      • getTable()
      • getCollectionTable()
    • HibernateRefClass
      • getQueryCacheRegion()
      • getTable()
  2. Modify code that invokes these methods to obtain the table prefix from the HibernateMDRepository and re-apply it
    • As a stepping stone to the final implementation, the HibernateMDRepository can be modified to return the table prefix value from configurator.properties
  3. During code generation, use Ant-style property references instead of table prefixes when generating:
    • mapping.xml
    • indexMapping.xml
    • For example, table="`${tprefix}Sample_Vehicle`" or create index `${tprefix}AssocOneToManyChildren`...
    • It may be necessary to introduce an OutputStream or Writer that automatically converts PREFIX_Foo to ${tprefix}Foo for index generation
  4. Similarly, generate create.sql and drop.sql (see org.eigenbase.enki.hibernate.ant.ExportSchemaSubTask) using prefix references.
    • Introduce a new Hibernate-specific Ant sub task that loads create.sql or drop.sql and resolves the table prefix references to a new file (see InputStream/Reader mentioned below)
  5. During HibernateMDRepository initialization, use a custom InputStream or Reader to convert the table prefix references to the current repository's table prefix
  6. Make table prefix a storage property and load it when HibernateMDRepository is instantiated.

Make ENKI_TYPE_LOOKUP Repository-specific

  1. Add table prefix column to ENKI_TYPE_LOOKUP
  2. Filter queries by table prefix.

Track Plugins

Difference instances of a metamodel may have different plugins when they are instantiated. Therefore the plugins present at the time the extent is created should be recorded.

  1. Introduce a new configurator.properties field that stores a plugin identifier.
  2. Provide a HibernateGenerator option to set the plugin identifier. If unset, choose one. Store the identifier in configurator.properties
  3. Introduce collection property for ENKI_EXTENT that stores plugin identifiers in a new table ENKI_EXTENT_PLUGINS.
  4. When a new extent is instantiated, note the identifiers of present in the new collection property
  5. When loading an extent only use the plugins stored in ENKI_EXTENT/ENKI_EXTENT_PLUGINS, ignoring others.

Multiple Extents Using the Same Metamodel Design

It should be possible to allow multiple extents of the same metamodel to exist in a single set of tables. It requires modifying adding the extentId to all metamodel tables, populating that value as objects are created, and using the extentId as a filter on queries (e.g., refAllOfType/Class, refAllLinks, etc).

Product Documentation