1616
1717package com .mongodb .hibernate ;
1818
19+ import static com .mongodb .client .model .Aggregates .project ;
20+ import static com .mongodb .client .model .Projections .include ;
21+ import static com .mongodb .hibernate .BasicCrudIntegrationTests .Item .CONSTRUCTOR_MAPPING_FOR_ITEM ;
22+ import static com .mongodb .hibernate .BasicCrudIntegrationTests .Item .MAPPING_FOR_ITEM ;
1923import static com .mongodb .hibernate .MongoTestAssertions .assertEq ;
24+ import static com .mongodb .hibernate .internal .MongoConstants .ID_FIELD_NAME ;
2025import static org .assertj .core .api .Assertions .assertThat ;
2126
2227import com .mongodb .client .MongoCollection ;
28+ import com .mongodb .hibernate .embeddable .EmbeddableIntegrationTests ;
29+ import com .mongodb .hibernate .embeddable .StructAggregateEmbeddableIntegrationTests ;
2330import com .mongodb .hibernate .junit .InjectMongoCollection ;
2431import com .mongodb .hibernate .junit .MongoExtension ;
32+ import jakarta .persistence .ColumnResult ;
33+ import jakarta .persistence .ConstructorResult ;
2534import jakarta .persistence .Entity ;
2635import jakarta .persistence .Id ;
36+ import jakarta .persistence .SqlResultSetMapping ;
2737import jakarta .persistence .Table ;
2838import java .math .BigDecimal ;
39+ import java .time .Instant ;
2940import org .bson .BsonDocument ;
41+ import org .bson .conversions .Bson ;
3042import org .bson .types .ObjectId ;
3143import org .hibernate .testing .orm .junit .DomainModel ;
3244import org .hibernate .testing .orm .junit .SessionFactory ;
4355 BasicCrudIntegrationTests .ItemDynamicallyUpdated .class ,
4456 })
4557@ ExtendWith (MongoExtension .class )
46- class BasicCrudIntegrationTests implements SessionFactoryScopeAware {
47- private static final String COLLECTION_NAME = "items" ;
58+ public class BasicCrudIntegrationTests implements SessionFactoryScopeAware {
4859
49- @ InjectMongoCollection (COLLECTION_NAME )
60+ @ InjectMongoCollection (Item . COLLECTION_NAME )
5061 private static MongoCollection <BsonDocument > mongoCollection ;
5162
5263 private SessionFactoryScope sessionFactoryScope ;
@@ -74,7 +85,8 @@ void testSimpleEntityInsertion() {
7485 true ,
7586 "str" ,
7687 BigDecimal .valueOf (10.1 ),
77- new ObjectId ("000000000000000000000001" ))));
88+ new ObjectId ("000000000000000000000001" ),
89+ Instant .parse ("2024-01-01T10:00:00Z" ))));
7890 assertCollectionContainsExactly (
7991 """
8092 {
@@ -91,7 +103,8 @@ void testSimpleEntityInsertion() {
91103 boxedBoolean: true,
92104 string: "str",
93105 bigDecimal: {$numberDecimal: "10.1"},
94- objectId: {$oid: "000000000000000000000001"}
106+ objectId: {$oid: "000000000000000000000001"},
107+ instant: {$date: "2024-01-01T10:00:00Z"}
95108 }
96109 """ );
97110 }
@@ -112,6 +125,7 @@ void testEntityWithNullFieldValuesInsertion() {
112125 null ,
113126 null ,
114127 null ,
128+ null ,
115129 null )));
116130 assertCollectionContainsExactly (
117131 """
@@ -129,7 +143,8 @@ void testEntityWithNullFieldValuesInsertion() {
129143 boxedBoolean: null,
130144 string: null,
131145 bigDecimal: null,
132- objectId: null
146+ objectId: null,
147+ instant: null
133148 }
134149 """ );
135150 }
@@ -156,7 +171,8 @@ void testSimpleDeletion() {
156171 true ,
157172 "str" ,
158173 BigDecimal .valueOf (10.1 ),
159- new ObjectId ("000000000000000000000001" ))));
174+ new ObjectId ("000000000000000000000001" ),
175+ Instant .parse ("2024-01-01T10:00:00Z" ))));
160176 assertThat (mongoCollection .find ()).hasSize (1 );
161177
162178 sessionFactoryScope .inTransaction (session -> {
@@ -188,7 +204,8 @@ void testSimpleUpdate() {
188204 true ,
189205 "str" ,
190206 BigDecimal .valueOf (10.1 ),
191- new ObjectId ("000000000000000000000001" ));
207+ new ObjectId ("000000000000000000000001" ),
208+ Instant .parse ("2024-01-01T10:00:00Z" ));
192209 session .persist (item );
193210 session .flush ();
194211 item .primitiveBoolean = false ;
@@ -211,7 +228,8 @@ void testSimpleUpdate() {
211228 boxedBoolean: false,
212229 string: "str",
213230 bigDecimal: {$numberDecimal: "10.1"},
214- objectId: {$oid: "000000000000000000000001"}
231+ objectId: {$oid: "000000000000000000000001"},
232+ instant: {$date: "2024-01-01T10:00:00Z"}
215233 }
216234 """ );
217235 }
@@ -233,7 +251,8 @@ void testSimpleUpdateWithNullFieldValues() {
233251 true ,
234252 "str" ,
235253 BigDecimal .valueOf (10.1 ),
236- new ObjectId ("000000000000000000000001" ));
254+ new ObjectId ("000000000000000000000001" ),
255+ Instant .parse ("2024-01-01T10:00:00Z" ));
237256 session .persist (item );
238257 session .flush ();
239258 item .boxedChar = null ;
@@ -244,6 +263,7 @@ void testSimpleUpdateWithNullFieldValues() {
244263 item .string = null ;
245264 item .bigDecimal = null ;
246265 item .objectId = null ;
266+ item .instant = null ;
247267 });
248268
249269 assertCollectionContainsExactly (
@@ -262,7 +282,8 @@ void testSimpleUpdateWithNullFieldValues() {
262282 boxedBoolean: null,
263283 string: null,
264284 bigDecimal: null,
265- objectId: null
285+ objectId: null,
286+ instant: null
266287 }
267288 """ );
268289 }
@@ -326,7 +347,8 @@ void testFindByPrimaryKey() {
326347 true ,
327348 "str" ,
328349 BigDecimal .valueOf (10.1 ),
329- new ObjectId ("000000000000000000000001" ));
350+ new ObjectId ("000000000000000000000001" ),
351+ Instant .parse ("2024-01-01T10:00:00Z" ));
330352 sessionFactoryScope .inTransaction (session -> session .persist (item ));
331353
332354 var loadedItem = sessionFactoryScope .fromTransaction (session -> session .find (Item .class , item .id ));
@@ -336,7 +358,21 @@ void testFindByPrimaryKey() {
336358 @ Test
337359 void testFindByPrimaryKeyWithNullFieldValues () {
338360 var item = new Item (
339- 1 , 'c' , 1 , Long .MAX_VALUE , Double .MAX_VALUE , true , null , null , null , null , null , null , null , null );
361+ 1 ,
362+ 'c' ,
363+ 1 ,
364+ Long .MAX_VALUE ,
365+ Double .MAX_VALUE ,
366+ true ,
367+ null ,
368+ null ,
369+ null ,
370+ null ,
371+ null ,
372+ null ,
373+ null ,
374+ null ,
375+ null );
340376 sessionFactoryScope .inTransaction (session -> session .persist (item ));
341377
342378 var loadedItem = sessionFactoryScope .fromTransaction (session -> session .find (Item .class , item .id ));
@@ -348,29 +384,83 @@ private static void assertCollectionContainsExactly(String documentAsJsonObject)
348384 assertThat (mongoCollection .find ()).containsExactly (BsonDocument .parse (documentAsJsonObject ));
349385 }
350386
387+ /**
388+ * This class should have persistent attributes of all the <a
389+ * href="https://docs.jboss.org/hibernate/orm/6.6/userguide/html_single/Hibernate_User_Guide.html#basic">basic
390+ * types</a> we support. When adding more persistent attributes to this class, we should do similar changes to
391+ * {@link EmbeddableIntegrationTests.Plural}/{@link StructAggregateEmbeddableIntegrationTests.Plural},
392+ * {@link EmbeddableIntegrationTests.ArraysAndCollections}/{@link StructAggregateEmbeddableIntegrationTests.ArraysAndCollections},
393+ * {@link ArrayAndCollectionIntegrationTests.ItemWithArrayAndCollectionValues}.
394+ */
351395 @ Entity
352- @ Table (name = COLLECTION_NAME )
353- static class Item {
354- @ Id
355- int id ;
396+ @ Table (name = Item .COLLECTION_NAME )
397+ @ SqlResultSetMapping (
398+ name = CONSTRUCTOR_MAPPING_FOR_ITEM ,
399+ classes =
400+ @ ConstructorResult (
401+ targetClass = Item .class ,
402+ columns = {
403+ @ ColumnResult (name = ID_FIELD_NAME , type = int .class ),
404+ @ ColumnResult (name = "primitiveChar" , type = char .class ),
405+ @ ColumnResult (name = "primitiveInt" , type = int .class ),
406+ @ ColumnResult (name = "primitiveLong" , type = long .class ),
407+ @ ColumnResult (name = "primitiveDouble" , type = double .class ),
408+ @ ColumnResult (name = "primitiveBoolean" , type = boolean .class ),
409+ @ ColumnResult (name = "boxedChar" , type = Character .class ),
410+ @ ColumnResult (name = "boxedInt" , type = Integer .class ),
411+ @ ColumnResult (name = "boxedLong" , type = Long .class ),
412+ @ ColumnResult (name = "boxedDouble" , type = Double .class ),
413+ @ ColumnResult (name = "boxedBoolean" , type = Boolean .class ),
414+ @ ColumnResult (name = "string" , type = String .class ),
415+ @ ColumnResult (name = "bigDecimal" , type = BigDecimal .class ),
416+ @ ColumnResult (name = "objectId" , type = ObjectId .class ),
417+ @ ColumnResult (name = "instant" , type = Instant .class ),
418+ }))
419+ @ SqlResultSetMapping (
420+ name = MAPPING_FOR_ITEM ,
421+ columns = {
422+ @ ColumnResult (name = ID_FIELD_NAME ),
423+ @ ColumnResult (name = "primitiveChar" , type = char .class ),
424+ @ ColumnResult (name = "primitiveInt" ),
425+ @ ColumnResult (name = "primitiveLong" ),
426+ @ ColumnResult (name = "primitiveDouble" ),
427+ @ ColumnResult (name = "primitiveBoolean" ),
428+ @ ColumnResult (name = "boxedChar" , type = Character .class ),
429+ @ ColumnResult (name = "boxedInt" ),
430+ @ ColumnResult (name = "boxedLong" ),
431+ @ ColumnResult (name = "boxedDouble" ),
432+ @ ColumnResult (name = "boxedBoolean" ),
433+ @ ColumnResult (name = "string" ),
434+ @ ColumnResult (name = "bigDecimal" ),
435+ @ ColumnResult (name = "objectId" ),
436+ @ ColumnResult (name = "instant" )
437+ })
438+ public static class Item {
439+ public static final String COLLECTION_NAME = "items" ;
440+ public static final String CONSTRUCTOR_MAPPING_FOR_ITEM = "ConstructorItem" ;
441+ public static final String MAPPING_FOR_ITEM = "Item" ;
356442
357- char primitiveChar ;
358- int primitiveInt ;
359- long primitiveLong ;
360- double primitiveDouble ;
361- boolean primitiveBoolean ;
362- Character boxedChar ;
363- Integer boxedInt ;
364- Long boxedLong ;
365- Double boxedDouble ;
366- Boolean boxedBoolean ;
367- String string ;
368- BigDecimal bigDecimal ;
369- ObjectId objectId ;
443+ @ Id
444+ public int id ;
445+
446+ public char primitiveChar ;
447+ public int primitiveInt ;
448+ public long primitiveLong ;
449+ public double primitiveDouble ;
450+ public boolean primitiveBoolean ;
451+ public Character boxedChar ;
452+ public Integer boxedInt ;
453+ public Long boxedLong ;
454+ public Double boxedDouble ;
455+ public Boolean boxedBoolean ;
456+ public String string ;
457+ public BigDecimal bigDecimal ;
458+ public ObjectId objectId ;
459+ public Instant instant ;
370460
371461 Item () {}
372462
373- Item (
463+ public Item (
374464 int id ,
375465 char primitiveChar ,
376466 int primitiveInt ,
@@ -384,7 +474,8 @@ static class Item {
384474 Boolean boxedBoolean ,
385475 String string ,
386476 BigDecimal bigDecimal ,
387- ObjectId objectId ) {
477+ ObjectId objectId ,
478+ Instant instant ) {
388479 this .id = id ;
389480 this .primitiveChar = primitiveChar ;
390481 this .primitiveInt = primitiveInt ;
@@ -399,11 +490,31 @@ static class Item {
399490 this .string = string ;
400491 this .bigDecimal = bigDecimal ;
401492 this .objectId = objectId ;
493+ this .instant = instant ;
494+ }
495+
496+ public static Bson projectAll () {
497+ return project (include (
498+ ID_FIELD_NAME ,
499+ "primitiveChar" ,
500+ "primitiveInt" ,
501+ "primitiveLong" ,
502+ "primitiveDouble" ,
503+ "primitiveBoolean" ,
504+ "boxedChar" ,
505+ "boxedInt" ,
506+ "boxedLong" ,
507+ "boxedDouble" ,
508+ "boxedBoolean" ,
509+ "string" ,
510+ "bigDecimal" ,
511+ "objectId" ,
512+ "instant" ));
402513 }
403514 }
404515
405516 @ Entity
406- @ Table (name = COLLECTION_NAME )
517+ @ Table (name = Item . COLLECTION_NAME )
407518 static class ItemDynamicallyUpdated {
408519 @ Id
409520 int id ;
0 commit comments