Para agentes de IA: um índice de documentação está disponível em https://www.mongodb.com/pt-br/docs/llms.txt — as versões de markdown de todas as páginas estão disponíveis anexando .md a qualquer caminho de URL.

Mapear uma hierarquia de herança de entidade

Neste guia, você pode aprender como mapear uma hierarquia de classe Java para uma coleção do MongoDB usando a extensão Hibernate ORM. Quando uma subclasse Java estende uma classe pai e herda seus campos, as classes formam uma hierarquia. O Hibernate ORM fornece estratégias de herança que determinam como a extensão armazena cada classe em uma hierarquia. A estratégia que você escolhe determina quais coleções mantêm seus dados e a forma dos documentos resultantes.

A extensão Hibernate ORM suporta as seguintes estratégias de herança:

  • Herança de tabela única: A extensão Hibernate ORM armazena uma hierarquia de classe inteira em uma coleção.

  • Superclasses mapeadas: Uma superclasse que não é uma entidade contribui com seus campos para cada subclasse sem uma coleção própria.

A extensão não oferece suporte às estratégias de herança JOINED e TABLE_PER_CLASS. Para aprender mais, consulte a seção Estratégias não suportadas deste guia.

Na estratégia de herança de tabela única, o framework armazena cada classe em uma hierarquia dentro da mesma coleção do MongoDB. Para usar esta 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 que mapeiam para várias classes, a extensão deve registro a classe para a qual cada documento é mapeado. A extensão armazena essas informações em um campo discriminador quando você salva um objeto. Ao fazer uma query na coleção, a extensão lê o valor do discriminador para determinar qual classe instanciar.

Para especificar o campo discriminador, aplicar a anotação @DiscriminatorColumn na entidade raiz. Para definir o valor do discriminador de uma classe, aplique a anotação @DiscriminatorValue à classe.

O exemplo a seguir mapeia uma hierarquia Movie para a coleção 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.

@Entity@Table(name = "movies")@Inheritance(strategy = InheritanceType.SINGLE_TABLE)@DiscriminatorColumn(name = "role")public abstract class Movie { @Id @ObjectIdGenerator private ObjectId id; private String name; // Getter and setter methods } @Entity@DiscriminatorValue("actor")public class Actor extends Movie { private List<String> awards; // Getter and setter methods } @Entity@DiscriminatorValue("director")public class Director extends Movie { private String studio; // Getter and setter methods }

Ao chamar 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 do 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 esse 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

Discriminadores de caractere e inteiro exigem um valor explícito

O Hibernate não define o valor do discriminador de uma classe como o nome da classe por padrão para discriminadores de caractere ou inteiro. Se você definir discriminatorType como DiscriminatorType.CHAR ou DiscriminatorType.INTEGER, você deve adicionar uma anotação @DiscriminatorValue à entidade raiz e a cada subclasse, mesmo que nunca instancie diretamente a entidade raiz.

A coleção movies contém documentos para cada classe na hierarquia Movie. Ao fazer uma query em uma dessas classes, a extensão Hibernate ORM filtra o campo discriminador para que a query retorne documentos apenas para essa classe. Este filtro depende de qual classe você faz a query:

  • Se você fizer uma query em uma subclasse, a extensão corresponderá aos documento cujo discriminador seja igual ao valor do discriminador dessa subclasse. A query de Actor no exemplo anterior corresponde apenas aos documento em que role é "actor".

  • Se você fizer uma query na classe raiz, a extensão não adicionará um filtro. A query lê cada documento na coleção e usa o valor do discriminador de cada documento para retornar um objeto da classe correta. Fazer uma query de Movie no exemplo anterior retorna os documentos Actor e Director. Se a coleção contiver um documento cujo valor de discriminador não mapeie para uma classe na hierarquia, a query lançará um HibernateException.

Para aprender mais sobre como query entidades, consulte o guia Especifique uma query.

Uma mapped superclass compartilha mapeamentos de campo com suas subclasses sem se tornar uma entidade em si. Para criar uma mapped superclass, aplique a anotação @MappedSuperclass à superclasse. Como uma mapped superclass não é uma entidade, a extensão Hibernate ORM não cria uma coleção para ela, e você não pode fazer uma query diretamente nela.

Cada subclasse que estende uma superclasse mapeada é mapeada para sua própria coleção. 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:

@MappedSuperclasspublic abstract class MovieDetails { @Id @ObjectIdGenerator private ObjectId id; private String name; // Getter and setter methods } @Entity@Table(name = "genres")public class Genre extends MovieDetails { private String description; // Getter and setter methods } @Entity@Table(name = "languages")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 mapeiam cada subclasse para sua própria coleção.

Como resultado, a extensão não cria uma coleção para MovieDetails. Em vez disso, a extensão armazena Genre documento na coleção genres e Language documento na coleção languages. Cada documento contém os campo _id e name que MovieDetails mapeia, além dos campo que sua classe correspondente define:

{ "_id": ObjectId("..."), "description": "Serious, narrative-driven stories.", "name": "Drama" }{ "_id": ObjectId("..."), "code": "en", "name": "English" }

A extensão Hibernate ORM não oferece suporte às seguintes estratégias de herança do Hibernate ORM, que armazenam uma única hierarquia de classe em várias tabelas:

  • InheritanceType.JOINED: Armazenar cada classe em sua própria tabela e unir as tabelas para reconstruir uma instância

  • InheritanceType.TABLE_PER_CLASS: Armazena cada classe concreta em sua própria tabela e combina as tabelas para query a hierarquia

Se você mapear suas classe com qualquer uma das estratégias anteriores, a extensão lançará uma FeatureNotSupportedException.

Importante

Erros ocorrem na inicialização

A extensão Hibernate ORM valida a estratégia de herança quando cria a instância SessionFactory. Um aplicativo que usa uma estratégia não suportada não pode ser iniciado.

Para aprender mais sobre como criar entidades e mapear dados incorporados, consulte o guia Criar entidades para representar coleções.

Para aprender como usar suas entidades para executar operações de banco de dados, consulte os guias Executar operações CRUD e Especificar uma query.

Para ver uma lista dos recursos que a extensão Hibernate ORM suporta, consulte a página Compatibilidade de recursos.

Para aprender mais sobre as estratégias de herança do Hibernate ORM, consulte Herança na documentação do Hibernate ORM.