AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

コレクションを表すエンティティの作成

このガイドでは、MongoDBコレクションを表すHibernate ORM エンティティを作成する方法を学びます。Entity は、データの構造を定義するJavaクラスです。Hibernate ORM 拡張機能を使用する場合、各エンティティをMongoDBコレクションにマッピングし、これらのエンティティを使用してコレクションのドキュメントと交流できます。

Tip

Entity チュートリアル

エンティティと Hibernetes ORM 拡張機能を使用して 1 対多の**関係**をモデル化する方法を示すチュートリアルについては、Hibernetes ORM と**MongoDB** FooJay **ブログ記事**を参照してください。

MongoDB、 BSONと呼ばれるバイナリ形式でドキュメントを整理して保存し、柔軟なデータ処理を可能にしています。このセクションでは、エンティティに含めることができるBSONフィールドに対するHibernate ORM拡張機能のサポートについて説明します。

Tip

MongoDB がBSONデータを保存する方法の詳細については、 MongoDB Serverマニュアルの「 BSON types 」を参照してください。

次の表では、サポートされているBSONフィールド型と、非表示の ORM エンティティで使用できる非表示の ORM 拡張機能について説明しています。

BSONフィールド型
拡張フィールドタイプ
BSON の説明

null

null

ヌル値またはデータの不存を表します。

Binary

byte[]

サブタイプ 0 のバイナリ データを保存します。

String

char、java.lang.Character、java.lang.String、char[]、java.time.ZoneId、java.time.ZoneOffset、または java.util.TimeZone

UTF-8 でエンコードされた文字列値を保存します。 ZoneId と TimeZone のタイプにはIDが保存されます(Europe/Paris など)。 ZoneOffset 型には、+02:00 などのオフセットIDが保存されます。

Int32

int、java.lang.Integer、または java.time.Year

32 ビットの符号付き整数を保存します。

Int64

long or java.lang.Long

64 ビットの符号付き整数を保存します。

Double

double or java.lang.Double

浮動小数点値を保存します。

Boolean

boolean or java.lang.Boolean

true または false 値を保存します。

Decimal128

java.math.BigDecimal or java.time.Duration

28 ビットの 10 進数値を保存します。 java.time.Duration の値では期間がナノ秒単位で保存されます。

ObjectId

org.bson.types.ObjectId

MongoDB がプライマリキーとして使用する一意の 12 バイト識別子を保存します。

Date

java.time.Instant

UNIXエポック からの日付と時刻をミリ秒として保存します。

Object

@org.hibernate.annotations.Struct 集計埋め込み可能

それぞれのタイプに従ってマップされたフィールド値を持つ埋め込みドキュメントを保存します。 @Struct 集計埋め込み可能には、配列または Collection 属性も含まれる場合があります。

Array

Array、サポートされているタイプの java.util.Collection(またはサブタイプ)

それぞれの型に従ってマップされた要素を持つ配列値を保存します。文字配列には、 hibernate.type.wrapper_array_handling 構成プロパティを設定する必要があります。

注意

@JdBCTypeCode 注釈はサポートされていません

Hibernetes ORM 拡張機能は @org.hibernate.annotations.JdbcTypeCode アノテーションをサポートしておらず、この注釈を使用してフィールドのタイプマッピングを上書きする場合、例外をスローします。

非表示 ORM は、そのタイプの他のマッピングがない場合、java.io.Serializable を実装するJava型をバイナリ データに直列化します。データが この形式で保存されないようにするには、 Hibernetes ORM 拡張機能 が次のタイプを拒否し、アプリケーションの起動時に例外をスローします。このチェックは、プライマリキー、通常のフィールド、埋め込み可能な属性、コレクション要素に適用されます。

次の表では、サポートされていないフィールド型とサポートされている代替手段について説明します。

カテゴリ
サポートされていないタイプ
サポートされている代替手段

日時

java.util.Calendar, java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp, java.time.LocalTime, java.time.LocalDateTime, java.time.ZonedDateTime, java.time.OffsetTime, java.time.OffsetDateTime

java.time.Instant を使用します。

BSON Values

org.bson.types.BSONTimestamp, org.bson.types.Binary, org.bson.types.Code, org.bson.types.CodeWithScope, org.bson.types.CodeWScope, org.bson.types.MinKey, org.bson.types.MaxKey, org.bson.types.Symbol, org.bson.types.Decimal128

バイナリ データには byte[] を使用し、10 進値には java.math.BigDecimal を使用します。他のタイプには同等のものはありません。

BSON ドキュメント

org.bson.Document, org.bson.BsonDocument, org.bson.RawBsonDocument, org.bson.BsonDocumentWrapper

@org.hibernate.annotations.Struct 集計埋め込み可能を使用します。

MongoDBコレクション を表すエンティティを作成するには、プロジェクトの 基本パッケージディレクトリに新しいJavaファイルを作成し、新しいファイルにエンティティクラスを追加します。エンティティクラスで、保存するフィールドとコレクション名を指定します。

name@jakarta.persistence.Tableアノテーションの 要素はMongoDBコレクション名を表します。このガイドの「schema スキーマ修飾子 」セクションで説明されているように、コレクション名の前に任意の 要素を設定することもできます。エンティティを定義するには、次の構文を使用します。

@Entity
@Table(name = "<collection name>")
public class <EntityName> {
@Id
// Specify your primary key field here
private <field type> <field name>;
// Include additional fields here
private <field type> <field name>;
// Parameterized constructor
public <EntityName>(<parameters>) {
// Initialize fields here
}
// Default constructor
public <EntityName>() {
}
// Getter and setter methods
public <field type> get<FieldName>() {
return <field name>;
}
public void set<FieldName>(<field type> <field name>) {
this.<field name> = <field name>;
}
}

エンティティを使用するには、アプリケーションファイルでクエリを実行します。Hibernate ORM 拡張機能でのCRUD操作の詳細については、「CRUD 操作の実行」ガイドを参照してください。

重要

プライマリキー フィールド名は _id である必要があります

MongoDB、_idフィールドにマッピングするためにプライマリキーフィールドが必要です。 @Column アノテーションまたは orm.xml オーバーライドを使用して、@Id フィールドの列名を明示的に設定できます。この名前を _id 以外に設定すると、 Hibernetes ORM 拡張機能はブートストラップ時に FeatureNotSupportedException をスローします。このエラーを解決するには、@Column アノテーションを削除するか、その名前を _id に設定します。

この検証は、レガシーマッピング(HBI) XML マッピングには適用されません。 HVM XML を使用してエンティティをマッピングすると、 Hibernetes ORM 拡張機能は例外をスローする代わりに、識別子列の名前を _id に変更します。

@Table アノテーションでは、コレクション名の前に任意の schema 要素を受け入れます。両方の要素を設定すると、 Hibernetes ORM 拡張機能はエンティティを <schema name>.<collection name> という名前のコレクションにマッピングします。

スキーマ修飾子は、コレクションの名前のみを変更します。スキーマは別のMongoDBデータベース ではありません。すべてのスキーマ修飾コレクションは、SessionFactoryインスタンスが接続するデータベースに存在します。これらのコレクションは 1 つのデータベースを共有する ため、トランザクションは複数のスキーマにまたがることができます。

スキーマ修飾子を適用するには、次の構文を使用します。

@Entity
@Table(schema = "<schema name>", name = "<collection name>")
public class <EntityName> {
// Define your fields, constructors, and methods here
}

注意

スキーマ修飾子の制限

Hibernetes ORM 拡張機能は、ブートストラップ時に @Table アノテーションの catalog 要素と hibernate.default_catalog 構成プロパティを拒否します。アプリケーションが複数のMongoDBデータベースにアクセスする必要がある場合は、データベースごとに個別の SessionFactoryインスタンスを作成します。

Hibernetes ORM 拡張機能は、ブートストラップ時にテーブル名またはスキーマ名内のドット(.) を拒否します。この制限は、プライマリ、セカンダリ、結合、コレクションのテーブル名と、schema 属性または hibernate.default_schema 構成プロパティのいずれかによって設定されたスキーマ名に適用されます。

このサンプルMovie.java エンティティクラスは、次の情報を含む Movie エンティティを定義します。

  • @Entity クラスをHibernetes ORM エンティティとしてマークする注釈

  • @Table Atlasサンプルデータセットからエンティティを moviesコレクションにマッピングする注釈

  • @Id と idフィールドをプライマリキーとして指定し、ObjectId の自動生成を構成する @ObjectIdGenerator 注釈

    Tip

    プライマリキー値

    この例では、ObjectId フィールドをエンティティのプライマリキーとして指定していますが、String int@Idアノテーションを使用して、 フィールドまたは フィールドをプライマリキーとして設定することもできます。詳細については、「 サポートされていないフィールド タイプ 」を参照してください。

  • 映画データを表すプライベート フィールド

  • エンティティインスタンス化のためのデフォルトおよびパラメータ付きコンストラクタ

  • エンティティのフィールドへのアクセスを提供する getter メソッドと setter メソッド

package org.example;
import com.mongodb.hibernate.annotations.ObjectIdGenerator;
import org.bson.types.ObjectId;
import java.util.List;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name = "movies")
public class Movie {
@Id
@ObjectIdGenerator
private ObjectId id;
private String title;
private String plot;
private int year;
private List<String> cast;
private List<String> directors;
public Movie(String title, String plot, int year, List<String> cast, List<String> directors) {
this.title = title;
this.plot = plot;
this.year = year;
this.cast = cast;
this.directors = directors;
}
public Movie() {
}
public ObjectId getId() {
return id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPlot() {
return plot;
}
public void setPlot(String plot) {
this.plot = plot;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public List<String> getCast() {
return cast;
}
public void setCast(List<String> cast) {
this.cast = cast;
}
public List<String> getDirectors() {
return directors;
}
public void setDirectors(List<String> directors) {
this.directors = directors;
}
}

Tip

エンティティクラス定義で使用されるフィールドの詳細については、このガイドのMongoDB BSONフィールドセクションを参照してください。

複数のフィールドでエンティティをキー化するには、 複合プライマリキーを定義します。キー コンポーネントを保持するプレーンな @Embeddableクラスまたはレコードを作成します。次に、エンティティの識別子フィールドに @jakarta.persistence.EmbeddedId 注釈を付けます。

次の BookId 埋め込みは、publisherId コンポーネントと bookNo コンポーネントで構成されるキーを定義します。

@Embeddable
public record BookId(long publisherId, long bookNo) {}

次の Book エンティティは、BookId をプライマリキーとして使用します。

@Entity(name = "Book")
@Table(name = "books")
public class Book {
@EmbeddedId
private BookId id;
private String title;
public Book() {
}
public Book(BookId id, String title) {
this.id = id;
this.title = title;
}
// Getter and setter methods
}

エンティティを永続化する前に、アプリケーション内で複合キー値を割り当てる必要があります。 Hibernetes ORM 拡張機能は複合キー値を生成しません。

Hibernetes ORM 拡張機能は複合キーを _id サブドキュメントとして保存します。上記の Book エンティティでは、次の形式のドキュメントが生成されます。

{
"_id": { "bookNo": 2, "publisherId": 10 },
"title": "My Book"
}

Hibernetes ORM 拡張機能では、_id サブドキュメントのコンポーネントは、宣言した順序ではなく、コンポーネント名のアルファベット順に並べられます。この順序は、埋め込み可能をクラスとして宣言する場合でも、レコードとして宣言する場合でも同じです。

重要

コンポーネントの順序はドキュメント一致に影響する

MongoDB はフィールド順序でサブドキュメントを比較するため、異なる順序で同じコンポーネントを含む 2 つの _id 値は一致しません。 Hibernetes ORM 拡張機能は常に同じ順序でコンポーネントを書込むため、この動作はMongoDB Javaドライバーなど、 Hibernetes ORM 拡張機能の外部でもこれらのドキュメントを読み取りまたは書込む場合にのみ影響します。

次のいずれかの方法で複合キーを宣言すると、アプリケーションの起動時に Hibernetes ORM 拡張機能は FeatureNotSupportedException をスローします。

  • @jakarta.persistence.IdClass アノテーションまたは複数の @Id 属性で宣言される非集計識別子。代わりに @EmbeddedId を使用してキーを宣言します。

  • 識別子として埋め込み可能な @Struct 集計。代わりに、プレーンの @Embeddable を使用してください。

  • 基本値ではないコンポーネント(ネストされた @Embeddable やコレクションなど)。複合キーのすべてのコンポーネントは基本値である必要があります。

  • @jakarta.persistence.MapsId アノテーションを使用する派生 ID を含む、識別子内の関連付け。

また、> や < などの順序付け演算子を使用して、複合識別子全体を比較することはできません。代わりに個々のコンポーネントを比較してください。

Hibernetes ORM 拡張機能は、 Hibernetes ORM @Embeddable 注釈による埋め込みドキュメントをサポートします。埋め込みドキュメントを使用すると、MongoDBドキュメント内に1対多、多対1、1対1の関係を作成できます。この形式は、頻繁にアクセスされるデータを表現するのに最適です。

埋め込みドキュメントを表すには、クラスで @Struct と @Embeddable アノテーションを使用して @Struct 集計埋め込み可能を作成します。次に、親エンティティに埋め込み可能な型をフィールドとして含めます。Hibernetes ORM 拡張機能は、埋め込み可能な単一オブジェクト、配列、およびコレクションの埋め込みをサポートしています。

Tip

@Struct 集計埋め込み可能ファイルの詳細については、Hibernate ORM ドキュメントの @Struct 集計埋め込み可能マッピング を参照してください。

1 対 1 の関係とは、1 つのデータベースのレコードが別のデータベースの 1 つのレコードのみに関連付けられている場合を指します。MongoDBでは、埋め込みドキュメントフィールドを持つコレクションを作成して、1 対 1 の関係をモデル化できます。Hibernetes ORM 拡張機能では、@Struct 集計埋め込み可能ファイルを使用して埋め込みドキュメントフィールドを作成できます。

この例では、このガイドの エンティティの定義 の例と同様に、エンティティ内に@Struct 集計埋め込み可能型を持つフィールドを定義します。サンプルMovie.java エンティティクラスには、次の情報が含まれています。

  • @Entity エンティティを定義し、それを moviesコレクションにマッピングする @Table アノテーション

  • @Id idフィールドをプライマリキーとして指定する @ObjectIdGenerator 注釈

  • 映画のタイトルを表す Stringフィールド

  • @Struct 映画情報とチームの情報を表す集計埋め込みフィールド

次の例は1 対 1 の関係を表します。各 Movie エンティティは 1 つの Awards 埋め込み可能と 1 つの Studio 埋め込み可能に関連付けられているためです。

@Entity
@Table(name = "movies")
public class Movie {
@Id
@ObjectIdGenerator
private ObjectId id;
private String title;
private Awards awards;
private Studio studio;
public Movie(String title, Awards awards, Studio studio) {
this.title = title;
this.awards = awards;
this.studio = studio;
}
public Movie() {
}
// Getter and setter methods
}

次のサンプルコードでは、Awards @Struct 集計埋め込み可能を作成します。

@Embeddable
@Struct(name = "Awards")
public class Awards {
private int wins;
private int nominations;
private String text;
public Awards(int wins, int nominations, String text) {
this.wins = wins;
this.nominations = nominations;
this.text = text;
}
public Awards() {
}
// Getter and setter methods
}

次のサンプルコードでは、Studio @Struct 集計埋め込み可能を作成します。

@Embeddable
@Struct(name = "Studio")
public class Studio {
private String name;
private String location;
private int foundedYear;
public Studio(String name, String location, int foundedYear) {
this.name = name;
this.location = location;
this.foundedYear = foundedYear;
}
public Studio() {
}
// Getter and setter methods
}

1 対多の関係とは、1 つのデータベースのレコードが別のデータベースの多くのレコードに関連付けられている場合を指します。MongoDBでは、埋め込みドキュメントのリストを保存するコレクションフィールドを定義して、1 対多の関係をモデル化できます。Hibernetes ORM 拡張機能を使用すると、@Struct 集計埋め込み可能ファイルのリストを使用して埋め込みドキュメントフィールドを作成できます。

この例では、このガイドの エンティティの定義例 と同様に、エンティティに@Struct 集計埋め込み可能ファイルのリストを保存するフィールドを定義します。サンプルMovie.java エンティティクラスには、次の情報が含まれています。

  • @Entity エンティティを定義し、それを moviesコレクションにマッピングする @Table アノテーション

  • @Id idフィールドをプライマリキーとして指定する @ObjectIdGenerator 注釈

  • 映画のタイトルを表す Stringフィールド

  • 複数の Writer @Struct 集計埋め込み可能性を保存するリストフィールド。これは書込み情報を表す

次の例は1 対多の関係を表しています。各 Movie エンティティは複数の Writer 埋め込み可能に関連付けられているためです。

@Entity
@Table(name = "movies")
public class Movie {
@Id
@ObjectIdGenerator
@Column(name = "_id")
private ObjectId id;
private String title;
private List<Writer> writers;
public Movie(String title, List<Writer> writers) {
this.title = title;
this.writers = writers;
}
public Movie() {
}
// Getter and setter methods
}

次のサンプルコードでは、Writer @Struct 集計埋め込み可能を作成します。

@Embeddable
@Struct(name = "Writer")
public class Writer {
private String name;
public Writer() {
}
public Writer(String name) {
this.name = name;
}
// Getter and setter methods
}

@Struct集計埋め込み可能内にフラット化された埋め込み可能をネストできます。フラット化された埋め込み可能とは、@Embeddable アノテーションを含むが@Struct アノテーションは含まないクラスです。 Hibernetes ORM 拡張機能は、フラット化された埋め込み可能のフィールドを別のネストされたドキュメントとしてではなく、親埋め込みドキュメントのフィールドとして保存します。

次のサンプルコードでは、フィールドとしてフラット化された埋め込み可能性を含むStudio@Struct Address集計埋め込み可能ファイルを作成します。

@Embeddable
@Struct(name = "Studio")
public class Studio {
private String name;
private Address address;
public Studio() {
}
public Studio(String name, Address address) {
this.name = name;
this.address = address;
}
// Getter and setter methods
}

次のサンプルコードでは、Address のフラット化された埋め込み可能値を作成します。クラスは@Struct 注釈を省略します。

@Embeddable
public class Address {
private String city;
private String country;
public Address() {
}
public Address(String city, String country) {
this.city = city;
this.country = country;
}
// Getter and setter methods
}

Studioフィールド を含むエンティティを永続化すると、Address フィールドは Studio フィールドの埋め込みドキュメントのフィールドになります。次の例ドキュメントには、Address フラット化された埋め込み可能のフィールドを保存する studio という名前の Studioフィールドがあります。

{
"_id": { "$oid": "..." },
"title": "Breathless",
"studio": {
"name": "Les Films Impéria",
"city": "Paris",
"country": "France"
}
}

クラス階層をMongoDBコレクションにマッピングする方法については、「 エンティティ継承階層のマッピング 」ガイドを参照してください。

エンティティを使用してデータベース操作を実行する方法を学ぶには、「交流するデータ」セクションにある次のガイドを参照してください。

Hibernetes ORM フィールドの詳細については、 Hibernetes ORM ドキュメントの「 マッピング型 」セクションを参照してください。

Hibernetes ORM エンティティの詳細については、 Hibernetes ORM ドキュメントの POJO モデル を参照してください。