:link-parallelArrays: https://en.wikipedia.org/wiki/Parallel_array["parallel arrays"] = Domain Model Mappings :toc2: :toclevels: 3 :sectanchors: :numbered: Describes Hibernate's handling of domain model metadata == Mapping sources Mapping sources include `hbm.xml` files, `orm.xml` files and annotated classes. There are other specialized forms of sources, but they all come back to locating annotated classes and XML mappings. The main actors in managing the sources include: `MetadataSources`:: Used to collect mapping sources to be processed together `JaxbHbmHibernateMapping`:: Main JAXB binding for a `hbm.xml` mapping document `Binding`:: Represents an XML mapping within the `MetadataSources`. Wraps either a `JaxbHbmHibernateMapping` or DOM `Document` representing a JPA `orm.xml`. `MappingBinder`:: Responsible for generating `Binding` instances. The handling for XML mappings is as follows: [plantuml,hbm,png] .hbm.xml processing ---- @startuml skinparam handwritten true Application -> MetadataSources : add(hbm.xml) MetadataSources -> MappingBinder : parse(hbm.xml) MappingBinder -> JAXB : bind(hbm.xml) MappingBinder <- JAXB : JaxbHbmHibernateMapping MetadataSources <- MappingBinder : Binding @enduml ---- [plantuml,orm,png] .orm.xml processing ---- @startuml skinparam handwritten true Application -> MetadataSources : add(orm.xml) MetadataSources -> MappingBinder : parse(orm.xml) MappingBinder -> DOM : bind(orm.xml) MappingBinder <- DOM : Document MetadataSources <- MappingBinder : Binding @enduml ---- NOTE: `MetadataSources` receives XML files without any knowledge of whether the file is a Hibernate mapping (`hbm.xml`) or a JPA mapping (`orm.xml`). `MappingBinder` makes that distinction based on doctype, schema, etc. == Boot-time metamodel The `org.hibernate.mapping` package defines most of the boot-time model. [plantuml,bootmodel,png] .Boot model actors ---- @startmindmap skinparam handwritten true + Boot model ++ PersistentClass ++ Property ++ Value ++ IdGenerator ++ TypeDef -- Table -- Selectable -- PrimaryKey -- Constraint @endmindmap ---- === PersistentClass Models an entity [plantuml,persistentclass,png] .PersistentClass hierarchy ---- @startuml interface Value class Property Property -- Value : value > class PersistentClass { entityName : String } PersistentClass *- Property : properties > class RootClass { table : Table } class JoinedSubclass { table : Table } class UnionSubclass { table : Table } PersistentClass <|-- RootClass PersistentClass <|-- Subclass Subclass <|-- JoinedSubclass Subclass <|-- SingleTableSubclass Subclass <|-- UnionSubclass @enduml ---- === Value Models a value. A value ultimately corresponds to a `org.hibernate.type.Type`. We will discuss this "simple" distinction when we talk about Types in the run-time metamodel section. [plantuml,value,png] .Value hierarchy ---- @startuml class SimpleValue note left of SimpleValue : By itself represents\na basic value class OneToMany note top of OneToMany : Used as element descriptor for\none-to-many collections Value <|-- KeyValue Value <|-- OneToMany KeyValue <|-- SimpleValue SimpleValue <|-- DependentValue SimpleValue <|-- Component SimpleValue <|-- Any SimpleValue <|-- ToOne ToOne <|-- ManyToOne ToOne <|-- OneToOne Value <|-- Collection Collection <|-- Bag Collection <|-- Set Collection <|-- IdentifierCollection IdentifierCollection <|-- IdentifierBag Collection <|-- IndexedCollection IndexedCollection <|-- List List <|-- Array IndexedCollection <|-- Map @enduml ---- === Database model [plantuml,db,png] .Database model ---- @startuml class Identifier Identifier : String text Identifier : boolean quoted Selectable <|-- Column Column : Identifider name Selectable <|-- Formula Formula : String fragment Constraint <|-- PrimaryKey Constraint <|-- UniqueKey Constraint <|-- ForeignKey class Table Table : Identifier name Table : Identifier schema Table : Identifier catalog Table : PrimaryKey : primaryKey Table : Selectable : selectables class Index class Sequence interface Exportable Exportable <|-- Table Exportable <|-- Constraint Exportable <|-- Index Exportable <|-- Sequence Exportable <|-- AuxilaryDatabaseObject interface TableOwner TableOwner : Table table TableOwner <|-- RootClass TableOwner <|-- JoinedSubclass TableOwner <|-- UnionSubclass @enduml ---- === Transition from sources to boot-time model The boot-time metamodel is built iteratively. The general paradigm in this transition is to instantiate one of these boot-time objects which are then populated in multiple later steps (via setters, additions, etc). The main actors in this process are `HbmMetadataSourceProcessorImpl` and `AnnotationMetadataSourceProcessorImpl`. [plantuml,source2boot,png] .Transition sources to boot-time model ---- @startuml skinparam handwritten true autonumber Application -> MetadataBuilder : build() MetadataBuilder -> MetadataBuildingProcess : build() MetadataBuildingProcess -> MetadataSourceProcessor MetadataSourceProcessor -> HbmMetadataSourceProcessorImpl : process hbm.xml Bindings MetadataSourceProcessor -> AnnotationMetadataSourceProcessorImpl : process annotations + orm.xml Bindings MetadataBuilder <- MetadataBuildingProcess : Metadata Application <- MetadataBuilder : Metadata @enduml ---- == Run-time metamodel [plantuml,runtimemodel,png] .Run-time model actors ---- @startmindmap skinparam handwritten true + Boot model ++ EntityPersister ++ CollectionPersister ++ Tuplizer -- Type -- IdentifierGenerator @endmindmap ---- === EntityPersister Manages persistence of an entity to/from its defined table(s). Maintains flattened state regarding various aspects of the entity's value mappings as {link-parallelArrays}. An entity's value mappings include: * identifier * attribute state * (discriminator) * (version) [plantuml,entitypersister,png] .EntityPersister hierarchy ---- @startuml skinparam handwritten true interface EntityPersister abstract class AbstractEntityPersister EntityPersister <|-- AbstractEntityPersister AbstractEntityPersister <|-- SingleTableEntityPersister AbstractEntityPersister <|-- JoinedEntityPersister AbstractEntityPersister <|-- UnionEntityPersister @enduml ---- === CollectionPersister Manages persistence of a collection to its defined table(s). Maintains flattened state as {link-parallelArrays} regarding various aspects of the value mappings making up the collection. These aspects include: * key -- the FK * element * (identifier) -- @IdBag * (list-index | map-key) [plantuml,collectionpersister,png] .CollectionPersister hierarchy ---- @startuml skinparam handwritten true interface CollectionPersister abstract class AbstractCollectionPersister CollectionPersister <|-- CollectionPersister AbstractCollectionPersister <|-- BasicCollectionPersister AbstractCollectionPersister <|-- OneToManyCollectionPersister note left of BasicCollectionPersister : collection mappings\nwith a collection table @enduml ---- === Type Describes a value mapping which is some form of non-identified state. [plantuml,type,png] .Type hierarchy ---- @startuml skinparam handwritten true interface Type interface IdentifierType Type <|-- IdentifierType interface DiscriminatorType IdentifierType <|-- DiscriminatorType interface VersionType Type <|-- VersionType interface BasicType Type <|-- BasicType interface CompositeType Type <|-- CompositeType CompositeType *- Type : subtypes interface AssociationType Type <|-- AssociationType interface AnyType { discriminatorType : DiscriminatorType identifierType : IdentifierType } AssociationType <|-- AnyType CompositeType <|-- AnyType interface UserType interface CustomType CustomType -- UserType : wrappedUserType Type <|-- CustomType @enduml ---- `IdentifierType`:: Specialized Type contract for types that can be used as an identifier `DiscriminatorType`:: Specialized Type contract for types that can be used as a discriminator `VersionType`:: Specialized Type contract for types that can be used as a version `BasicType`:: Mapping to a single column `CompositeType`:: Mapping to one or more columns `AssociationType`:: Mapping to an entity association `AnyType`:: Models a discriminated association which is similar to an association referencing a discriminated-subclass entity in that the mapping involves a discriminator. However, in an ANY mapping the discriminator is on the referring side. This will map to at least 2 columns - one for the discriminator plus one or more identifier columns. `EntityType`:: Models a foreign-key, which "from this side" is a to-one. Could map to a single column or multiple. `CollectionType`:: Models a foreign-key, which "from this side" is a to-many. Will map to at === Transition from boot-time model to run-time model This transition involves processing the boot model objects (`PersistentClass`, `Value`, etc) and building the corresponding run-time counterparts (`EntityPersister`, `Type`, etc). The main actors in this transition are the `SessionFactory` itself, `MetamodelImplementor` and `TypeConfiguration`: [plantuml,boot2run,png] .Transition boot-time model to run-time model ---- @startuml skinparam handwritten true Application -> SessionFactoryBuilder : build() SessionFactoryBuilder -> SessionFactory : new SessionFactory -> TypeConfiguration : scope ... @enduml ---- ##