EnkiHibernateMultipleMetamodels
From LucidDB Wiki
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:
- 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.
- 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.
- 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
- 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()
- org.eigenbase.enki.hibernate.jmi.HibernateRefAssociation
- 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
- During code generation, use Ant-style property references instead of table prefixes when generating:
- mapping.xml
- indexMapping.xml
- For example,
table="`${tprefix}Sample_Vehicle`"orcreate index `${tprefix}AssocOneToManyChildren`... - It may be necessary to introduce an OutputStream or Writer that automatically converts
PREFIX_Footo${tprefix}Foofor index generation
- 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)
- During HibernateMDRepository initialization, use a custom InputStream or Reader to convert the table prefix references to the current repository's table prefix
- Make table prefix a storage property and load it when HibernateMDRepository is instantiated.
Make ENKI_TYPE_LOOKUP Repository-specific
- Add table prefix column to ENKI_TYPE_LOOKUP
- 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.
- Introduce a new configurator.properties field that stores a plugin identifier.
- Provide a HibernateGenerator option to set the plugin identifier. If unset, choose one. Store the identifier in configurator.properties
- Introduce collection property for ENKI_EXTENT that stores plugin identifiers in a new table ENKI_EXTENT_PLUGINS.
- When a new extent is instantiated, note the identifiers of present in the new collection property
- 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).