Visão geral
Neste guia, você pode aprender como mapear uma hierarquia de classe Java para uma coleção MongoDB usando a extensão ORM do Hibername. Quando uma subclasse Java estende uma classe pai e herda seus campos, as classes formam uma hierarquia. O Hibername ORM fornece estratégias de herança que determinam como a extensão armazena cada classe em uma hierarquia. A estratégia escolhida determina quais collections contêm seus dados e o formato dos documentos resultantes.
A extensão Hibername ORM suporta as seguintes estratégias de herança:
Herança detabela única: A extensão Hibername ORM armazena uma hierarquia de classe inteira em uma coleção.
Superclasses mapeadas: uma superclasse sem entidade contribui com seus campos para cada subclasse sem uma coleção própria.
A extensão não suporta as estratégias de herança JOINED e TABLE_PER_CLASS. Para saber mais, consulte a seção Estratégias não suportadas deste guia.
Herança de Tabela Única
Na estratégia de herança de tabela única, a estrutura armazena todas as classe em uma hierarquia dentro da mesma coleção MongoDB . Para usar essa estratégia, aplique a anotação @Inheritance(strategy = InheritanceType.SINGLE_TABLE) à entidade raiz, a classe pai de nível mais alto na hierarquia.
Como a coleção contém documentos mapeados para várias classes, a extensão deve registrar a classe para a qual cada documento é mapeado. A extensão armazena essas informações em um campo discriminador quando você salva um objeto. Quando você consulta a coleção, a extensão lê o valor do discriminador para determinar qual classe instanciar.
Para especificar o campo discriminador, aplique a anotação @DiscriminatorColumn à entidade raiz. Para definir o valor discriminador de uma classe, aplique a anotação @DiscriminatorValue à classe.
O exemplo a seguir mapeia uma hierarquia Movie para a collection movies. As subclasses Actor e Director herdam o campo name de Movie, mas cada subclasse também adiciona seu próprio campo. Cada documento armazena "actor" ou "director" no campo discriminador role.
public abstract class Movie { private ObjectId id; private String name; // Getter and setter methods } public class Actor extends Movie { private List<String> awards; // Getter and setter methods } public class Director extends Movie { private String studio; // Getter and setter methods }
Quando você chama o método persist() em uma instância Actor ou uma instância Director, a extensão insere o documento correspondente na coleção movies. Cada documento contém os campos que sua própria classe define e o valor discriminador para essa classe:
{ "_id": ObjectId("..."), "role": "actor", "name": "Andrew Garfield", "awards": ["Golden Globe Award"] } { "_id": ObjectId("..."), "role": "director", "name": "Greta Gerwig", "studio": "Warner Bros." }
O exemplo anterior usa um discriminador de string, o tipo de discriminador padrão. Para alterar este tipo, defina o elemento discriminatorType da anotação @DiscriminatorColumn. Defina este elemento como DiscriminatorType.CHAR para armazenar o discriminador como um caractere ou como DiscriminatorType.INTEGER para armazenar o discriminador como um número inteiro.
Importante
Os discriminadores de caracteres e números inteiros exigem um valor explícito
O Hibername não padroniza o valor discriminador de uma classe para o nome da classe para discriminadores de caracteres ou inteiros. Se você definir discriminatorType como DiscriminatorType.CHAR ou DiscriminatorType.INTEGER, deverá adicionar uma anotação @DiscriminatorValue à entidade raiz e a cada subclasse, mesmo que nunca instancie diretamente a entidade raiz.
Fazer query em uma hierarquia de tabela única
A coleção movies contém documentos para cada classe na hierarquia do Movie. Quando você faz query de uma dessas classes, a extensão Hibername ORM filtra o campo discriminador para que a query retorne documentos somente para essa classe . Este filtro depende de qual classe você consulta:
Se você consultar uma subclasse, a extensão corresponderá aos documentos cujo discriminador seja igual ao valor de discriminador dessa subclasse. A query de
Actorno exemplo anterior corresponde apenas a documentos em queroleestá"actor".Se você fizer query da classe raiz , a extensão não adicionará um filtro. A query lê todos os documento na coleção e usa o valor discriminador de cada documento para retornar um objeto da classe correta. A query de
Movieno exemplo anterior retorna os documentosActoreDirector. Se a collection contiver um documento cujo valor discriminador não mapeie para uma classe na hierarquia, a query lançará umHibernateException.
Para saber mais sobre como consultar entidades, consulte o guia Especificar uma query.
Superclasses mapeadas
Uma superclasse mapeada compartilha mapeamentos de campo com suas subclasses sem se tornar uma entidade. Para criar uma superclasse mapeada, aplique a anotação @MappedSuperclass à superclasse. Como uma superclasse mapeada não é uma entidade, a extensão ORM do Hibernar não cria uma coleção para ela, e você não pode consultá-la diretamente.
Cada subclasse que estende uma superclasse mapeada mapeia para sua própria collection. Em cada documento, a extensão armazena os campos herdados e os campos da própria subclasse como campos de nível superior. A extensão não aninha os campos herdados nem os armazena separadamente.
O exemplo a seguir define uma superclasse mapeada MovieDetails que fornece os mapeamentos de identificador e nome para uma entidade Genre e uma entidade Language:
public abstract class MovieDetails { private ObjectId id; private String name; // Getter and setter methods } public class Genre extends MovieDetails { private String description; // Getter and setter methods } public class Language extends MovieDetails { private String code; // Getter and setter methods }
No exemplo anterior, a anotação @MappedSuperclass permite que MovieDetails defina os mapeamentos id e name sem se tornar uma entidade. As anotações @Entity e @Table em Genre e Language então mapeiam cada subclasse para sua própria collection.
Como resultado, a extensão não cria uma coleção para MovieDetails. Em vez disso, a extensão armazena documentos Genre na coleção genres e documentos Language na coleção languages. Cada documento contém os campos _id e name que MovieDetails mapeia, além dos campos que sua classe correspondente define:
{ "_id": ObjectId("..."), "description": "Serious, narrative-driven stories.", "name": "Drama" } { "_id": ObjectId("..."), "code": "en", "name": "English" }
Estratégias não suportadas
A extensão ORM do Hibernado não suporta as seguintes estratégias de herança do ORM do Hibernado, que armazenam uma única hierarquia de classe em várias tabelas:
InheritanceType.JOINED: Armazena cada classe em sua própria tabela e une as tabelas para reconstruir uma instânciaInheritanceType.TABLE_PER_CLASS: Armazena cada classe concreta em sua própria tabela e combina as tabelas para consultar a hierarquia
Se você mapear suas classes com qualquer uma das estratégias anteriores, a extensão lançará um FeatureNotSupportedException.
Importante
Os erros ocorrem na inicialização
A extensão ORM do Hibername valida a estratégia de herança quando cria a instância SessionFactory. Um aplicação que usa uma estratégia sem suporte não pode ser iniciado.
Informações adicionais
Para saber mais sobre como criar entidades e mapear dados incorporados, consulte o guia Criar entidades para representar coleções.
Para saber como usar suas entidades para executar operações de banco de dados , consulte os guias Executar operações CRUD e Especificar uma query.
Para visualizar uma lista dos recursos compatíveis com a extensão Hibername ORM, consulte a página Compatibilidade de recursos.
Para saber mais sobre estratégias de herança do Hibernar ORM, consulte Herança na documentação do Hibernar ORM.