Skip to content

Commit d903b50

Browse files
nakamura-toclaude
andcommitted
docs: Update embeddable documentation for nested and optional embeddables
- Add documentation for nested embeddable classes with examples - Update field type lists to include embeddable classes in Optional types - Update Japanese translations for new embeddable features - Improve clarity of optional embeddable behavior documentation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent c826182 commit d903b50

File tree

4 files changed

+149
-47
lines changed

4 files changed

+149
-47
lines changed

docs/embeddable.md

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ The field type must be one of the following:
8181

8282
- [Basic classes](basic.md)
8383
- [Domain classes](domain.md)
84-
- java.util.Optional, whose element is either [Basic classes](basic.md) or [Domain classes](domain.md)
84+
- [Embeddable classes](embeddable.md) (nested embeddables)
85+
- java.util.Optional, whose element is either [Basic classes](basic.md), [Domain classes](domain.md), or [Embeddable classes](embeddable.md)
8586
- java.util.OptionalInt
8687
- java.util.OptionalLong
8788
- java.util.OptionalDouble
@@ -105,7 +106,56 @@ final String zip;
105106

106107
### Transient
107108

108-
If an embeddable has fields that you don’t want to persist, you can annotate them using `@Transient`:
109+
If an embeddable has fields that you don't want to persist, you can annotate them using `@Transient`:
110+
111+
### Nested embeddable classes
112+
113+
Embeddable classes can contain other embeddable classes as fields, allowing for nested composition:
114+
115+
```java
116+
@Embeddable
117+
public class Address {
118+
String street;
119+
String city;
120+
String zipCode;
121+
}
122+
123+
@Embeddable
124+
public class ContactInfo {
125+
String email;
126+
String phone;
127+
Address address; // Nested embeddable
128+
}
129+
130+
@Entity
131+
public class Customer {
132+
@Id
133+
Integer id;
134+
String name;
135+
ContactInfo contactInfo; // Contains nested Address
136+
}
137+
```
138+
139+
This creates a hierarchical structure where the `Customer` entity contains `ContactInfo`, which in turn contains `Address`.
140+
All fields from nested embeddables are flattened into the entity's table structure.
141+
142+
### Optional embeddable classes
143+
144+
Embeddable classes can be wrapped in `java.util.Optional` to indicate that the entire embeddable group may be null:
145+
146+
```java
147+
@Entity
148+
public class Employee {
149+
@Id
150+
Integer id;
151+
String name;
152+
Optional<Address> homeAddress; // Optional embeddable
153+
Optional<ContactInfo> emergencyContact; // Optional nested embeddable
154+
}
155+
```
156+
157+
When an Optional embeddable is null, all corresponding database columns will be null.
158+
Conversely, when all columns corresponding to an Optional embeddable are null in the database, the Optional field will be empty (Optional.empty()).
109159

110160
## Method definition
111161

docs/entity.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ The field type must be one of the following:
141141
- [Basic classes](basic.md)
142142
- [Domain classes](domain.md)
143143
- [Embeddable classes](embeddable.md)
144-
- java.util.Optional, whose element is either [Basic classes](basic.md) or [Domain classes](domain.md)
144+
- java.util.Optional, whose element is either [Basic classes](basic.md), [Domain classes](domain.md), or [Embeddable classes](embeddable.md)
145145
- java.util.OptionalInt
146146
- java.util.OptionalLong
147147
- java.util.OptionalDouble

docs/locale/ja/LC_MESSAGES/embeddable.po

Lines changed: 92 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ msgid ""
33
msgstr ""
44
"Project-Id-Version: doma-docs\n"
55
"Report-Msgid-Bugs-To: \n"
6-
"POT-Creation-Date: 2025-07-12 16:05+0900\n"
6+
"POT-Creation-Date: 2025-07-26 00:57+0900\n"
77
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
88
"Last-Translator: \n"
99
"Language: ja_JP\n"
@@ -77,56 +77,102 @@ msgid "[Domain classes](domain.md)"
7777
msgstr "[ドメインクラス](domain.md)"
7878

7979
#: ../../embeddable.md:84
80-
msgid ""
81-
"java.util.Optional, whose element is either [Basic classes](basic.md) or "
82-
"[Domain classes](domain.md)"
83-
msgstr "要素を [基本クラス](basic.md) または [ドメインクラス](domain.md) のいずれかとする java.util.Optional"
80+
msgid "[Embeddable classes](embeddable.md) (nested embeddables)"
81+
msgstr "[埋め込み可能クラス](embeddable.md) (ネストした埋め込み可能クラス)"
8482

8583
#: ../../embeddable.md:85
86-
msgid "java.util.OptionalInt"
84+
msgid ""
85+
"java.util.Optional, whose element is either [Basic classes](basic.md), "
86+
"[Domain classes](domain.md), or [Embeddable classes](embeddable.md)"
8787
msgstr ""
88+
"要素を [基本クラス](basic.md)、[ドメインクラス](domain.md)、または [埋め込み可能クラス](embeddable.md)"
89+
" のいずれかとする java.util.Optional"
8890

8991
#: ../../embeddable.md:86
90-
msgid "java.util.OptionalLong"
91-
msgstr ""
92+
msgid "java.util.OptionalInt"
93+
msgstr "java.util.OptionalInt"
9294

9395
#: ../../embeddable.md:87
96+
msgid "java.util.OptionalLong"
97+
msgstr "java.util.OptionalLong"
98+
99+
#: ../../embeddable.md:88
94100
msgid "java.util.OptionalDouble"
95-
msgstr ""
101+
msgstr "java.util.OptionalDouble"
96102

97-
#: ../../embeddable.md:97
103+
#: ../../embeddable.md:98
98104
msgid "Column"
99105
msgstr "カラム"
100106

101-
#: ../../embeddable.md:99
107+
#: ../../embeddable.md:100
102108
msgid ""
103109
"You can specify the corresponding column name with the `@Column` "
104110
"annotation:"
105111
msgstr "カラム名を `@Column` アノテーションで指定できます。"
106112

107-
#: ../../embeddable.md:106
113+
#: ../../embeddable.md:107
108114
msgid "Transient"
109115
msgstr "Transient"
110116

111-
#: ../../embeddable.md:108
117+
#: ../../embeddable.md:109
112118
msgid ""
113-
"If an embeddable has fields that you dont want to persist, you can "
119+
"If an embeddable has fields that you don't want to persist, you can "
114120
"annotate them using `@Transient`:"
115-
msgstr "埋め込み可能オブジェクトに永続化したくないフィールドがある場合は、 `@Transient` アノテーションを指定できます。"
121+
msgstr "埋め込み可能クラスに永続化したくないフィールドがある場合は、`@Transient` アノテーションを指定できます:"
122+
123+
#: ../../embeddable.md:111
124+
msgid "Nested embeddable classes"
125+
msgstr "ネストした埋め込み可能クラス"
126+
127+
#: ../../embeddable.md:113
128+
msgid ""
129+
"Embeddable classes can contain other embeddable classes as fields, "
130+
"allowing for nested composition:"
131+
msgstr "埋め込み可能クラスは他の埋め込み可能クラスをフィールドとして含むことができ、ネストした構成が可能です:"
132+
133+
#: ../../embeddable.md:139
134+
msgid ""
135+
"This creates a hierarchical structure where the `Customer` entity "
136+
"contains `ContactInfo`, which in turn contains `Address`. All fields "
137+
"from nested embeddables are flattened into the entity's table structure."
138+
msgstr ""
139+
"これにより、`Customer` エンティティが `ContactInfo` を含み、さらに `ContactInfo` が `Address` "
140+
"を含む階層構造が作成されます。ネストした埋め込み可能クラスのすべてのフィールドは、エンティティのテーブル構造にフラット化されます。"
141+
142+
#: ../../embeddable.md:142
143+
msgid "Optional embeddable classes"
144+
msgstr "Optionalな埋め込み可能クラス"
116145

117-
#: ../../embeddable.md:110
146+
#: ../../embeddable.md:144
147+
msgid ""
148+
"Embeddable classes can be wrapped in `java.util.Optional` to indicate "
149+
"that the entire embeddable group may be null:"
150+
msgstr ""
151+
"埋め込み可能クラスを `java.util.Optional` でラップして、埋め込み可能グループ全体が null "
152+
"になる可能性があることを示すことができます:"
153+
154+
#: ../../embeddable.md:157
155+
msgid ""
156+
"When an Optional embeddable is null, all corresponding database columns "
157+
"will be null. Conversely, when all columns corresponding to an Optional "
158+
"embeddable are null in the database, the Optional field will be empty "
159+
"(Optional.empty())."
160+
msgstr ""
161+
"Optionalな埋め込み可能クラスがnullの場合、対応するすべてのデータベースカラムがnullになります。逆に、Optionalな埋め込み可能クラスに対応するすべてのカラムがデータベースでnullの場合、Optionalフィールドは空(Optional.empty())になります。"
162+
163+
#: ../../embeddable.md:160
118164
msgid "Method definition"
119165
msgstr "メソッドの定義"
120166

121-
#: ../../embeddable.md:112
167+
#: ../../embeddable.md:162
122168
msgid "There are no limitations in the use of methods."
123169
msgstr "メソッドの使用に制限はありません。"
124170

125-
#: ../../embeddable.md:114
171+
#: ../../embeddable.md:164
126172
msgid "Using @Embedded annotation"
127173
msgstr "@Embeddedアノテーションの使用"
128174

129-
#: ../../embeddable.md:116
175+
#: ../../embeddable.md:166
130176
msgid ""
131177
"You can use the `@Embedded` annotation to embed the same embeddable type "
132178
"multiple times within a single entity with different column name "
@@ -135,99 +181,99 @@ msgstr ""
135181
"`@Embedded` "
136182
"アノテーションを使用すると、同じ埋め込み可能型を異なるカラム名プレフィックスで単一のエンティティ内に複数回埋め込むことができます。"
137183

138-
#: ../../embeddable.md:118
184+
#: ../../embeddable.md:168
139185
msgid "Basic usage"
140186
msgstr "基本的な使用方法"
141187

142-
#: ../../embeddable.md:137
188+
#: ../../embeddable.md:187
143189
msgid "This will generate the following columns in the SQL statements:"
144190
msgstr "これにより、SQL文で以下のカラムが生成されます:"
145191

146-
#: ../../embeddable.md:139
192+
#: ../../embeddable.md:189
147193
msgid "`billing_street`"
148194
msgstr "`billing_street`"
149195

150-
#: ../../embeddable.md:140
196+
#: ../../embeddable.md:190
151197
msgid "`billing_city`"
152198
msgstr "`billing_city`"
153199

154-
#: ../../embeddable.md:141
200+
#: ../../embeddable.md:191
155201
msgid "`billing_zip_code`"
156202
msgstr "`billing_zip_code`"
157203

158-
#: ../../embeddable.md:142
204+
#: ../../embeddable.md:192
159205
msgid "`shipping_street`"
160206
msgstr "`shipping_street`"
161207

162-
#: ../../embeddable.md:143
208+
#: ../../embeddable.md:193
163209
msgid "`shipping_city`"
164210
msgstr "`shipping_city`"
165211

166-
#: ../../embeddable.md:144
212+
#: ../../embeddable.md:194
167213
msgid "`shipping_zip_code`"
168214
msgstr "`shipping_zip_code`"
169215

170-
#: ../../embeddable.md:146
216+
#: ../../embeddable.md:196
171217
msgid "Prefix behavior"
172218
msgstr "プレフィックスの動作"
173219

174-
#: ../../embeddable.md:148
220+
#: ../../embeddable.md:198
175221
msgid "The `prefix` attribute controls how column names are generated:"
176222
msgstr "`prefix` 属性はカラム名の生成方法を制御します:"
177223

178-
#: ../../embeddable.md:150
224+
#: ../../embeddable.md:200
179225
msgid ""
180226
"Column names are generated by combining the prefix with the embeddable "
181227
"field column name"
182228
msgstr "カラム名は、プレフィックスと埋め込み可能フィールドのカラム名を組み合わせて生成されます"
183229

184-
#: ../../embeddable.md:151
230+
#: ../../embeddable.md:201
185231
msgid "The prefix is added as-is to the field column name"
186232
msgstr "プレフィックスはフィールドのカラム名にそのまま追加されます"
187233

188-
#: ../../embeddable.md:152
234+
#: ../../embeddable.md:202
189235
msgid ""
190236
"If no prefix is specified, the behavior remains the same as using the "
191237
"embeddable field column name directly"
192238
msgstr "プレフィックスが指定されていない場合、動作は埋め込み可能フィールドのカラム名を直接使用する場合と同じままです"
193239

194-
#: ../../embeddable.md:169
240+
#: ../../embeddable.md:219
195241
msgid "Column overrides"
196242
msgstr "カラムのオーバーライド"
197243

198-
#: ../../embeddable.md:171
244+
#: ../../embeddable.md:221
199245
msgid ""
200246
"You can use the `columnOverrides` attribute along with `@ColumnOverride` "
201247
"annotations to have fine-grained control over individual column mappings:"
202248
msgstr ""
203249
"`columnOverrides` 属性を `@ColumnOverride` "
204250
"アノテーションと共に使用することで、個々のカラムマッピングをきめ細かく制御できます:"
205251

206-
#: ../../embeddable.md:193
252+
#: ../../embeddable.md:243
207253
msgid "The `@ColumnOverride` annotation allows you to:"
208254
msgstr "`@ColumnOverride` アノテーションを使用すると、以下のことができます:"
209255

210-
#: ../../embeddable.md:195
256+
#: ../../embeddable.md:245
211257
msgid "Specify a custom column name for a specific embeddable field"
212258
msgstr "特定の埋め込み可能フィールドにカスタムカラム名を指定する"
213259

214-
#: ../../embeddable.md:196
260+
#: ../../embeddable.md:246
215261
msgid "Override column attributes such as `insertable`, `updatable`, and `quote`"
216262
msgstr "`insertable`、`updatable`、`quote` などのカラム属性をオーバーライドする"
217263

218-
#: ../../embeddable.md:197
264+
#: ../../embeddable.md:247
219265
msgid "Take precedence over any `prefix` attribute when both are specified"
220266
msgstr "両方が指定されている場合、`prefix` 属性よりも優先される"
221267

222-
#: ../../embeddable.md:200
268+
#: ../../embeddable.md:250
223269
msgid ""
224270
"When both `prefix` and `columnOverrides` are used, the `@ColumnOverride` "
225271
"settings take precedence for the specified fields."
226272
msgstr ""
227273
"`prefix` と `columnOverrides` の両方が使用されている場合、指定されたフィールドに対しては "
228274
"`@ColumnOverride` の設定が優先されます。"
229275

230-
#: ../../embeddable.md:203
276+
#: ../../embeddable.md:253
231277
msgid "Example"
232278
msgstr "例"
233279

@@ -243,3 +289,9 @@ msgstr "例"
243289
#~ msgid "{doc}`domain`"
244290
#~ msgstr ""
245291

292+
#~ msgid ""
293+
#~ "When an Optional embeddable is null, "
294+
#~ "all corresponding database columns will "
295+
#~ "be null."
296+
#~ msgstr "Optional な埋め込み可能クラスが null の場合、対応するすべてのデータベースカラムが null になります。"
297+

docs/locale/ja/LC_MESSAGES/entity.po

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ msgid ""
33
msgstr ""
44
"Project-Id-Version: doma-docs\n"
55
"Report-Msgid-Bugs-To: \n"
6-
"POT-Creation-Date: 2025-07-12 16:05+0900\n"
6+
"POT-Creation-Date: 2025-07-25 22:20+0900\n"
77
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
88
"Last-Translator: \n"
99
"Language: ja_JP\n"
@@ -181,9 +181,9 @@ msgstr "[埋め込み可能クラス](embeddable.md)"
181181

182182
#: ../../entity.md:144
183183
msgid ""
184-
"java.util.Optional, whose element is either [Basic classes](basic.md) or "
185-
"[Domain classes](domain.md)"
186-
msgstr "[基本クラス](basic.md)または [ドメインクラス](domain.md) のいずれかを要素とする java.util.Optional"
184+
"java.util.Optional, whose element is either [Basic classes](basic.md), "
185+
"[Domain classes](domain.md), or [Embeddable classes](embeddable.md)"
186+
msgstr "要素を [基本クラス](basic.md)[ドメインクラス](domain.md)、または [埋め込み可能クラス](embeddable.md) のいずれかとする java.util.Optional"
187187

188188
#: ../../entity.md:145
189189
msgid "java.util.OptionalInt"

0 commit comments

Comments
 (0)