Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@

package com.mongodb.hibernate;

import static com.mongodb.client.model.Aggregates.project;
import static com.mongodb.client.model.Projections.include;
import static com.mongodb.hibernate.BasicCrudIntegrationTests.Item.COLLECTION_NAME;
import static com.mongodb.hibernate.MongoTestAssertions.assertEq;
import static com.mongodb.hibernate.internal.MongoConstants.ID_FIELD_NAME;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
Expand All @@ -29,16 +33,19 @@
import com.mongodb.hibernate.internal.FeatureNotSupportedException;
import com.mongodb.hibernate.junit.InjectMongoCollection;
import com.mongodb.hibernate.junit.MongoExtension;
import jakarta.persistence.ColumnResult;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.SqlResultSetMapping;
import jakarta.persistence.Table;
import java.math.BigDecimal;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.HashSet;
import java.util.List;
import org.bson.BsonDocument;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import org.hibernate.MappingException;
import org.hibernate.boot.MetadataSources;
Expand All @@ -64,8 +71,6 @@
@ServiceRegistry(settings = {@Setting(name = WRAPPER_ARRAY_HANDLING, value = "allow")})
@ExtendWith(MongoExtension.class)
public class ArrayAndCollectionIntegrationTests implements SessionFactoryScopeAware {
private static final String COLLECTION_NAME = "items";

@InjectMongoCollection(COLLECTION_NAME)
private static MongoCollection<BsonDocument> mongoCollection;

Expand Down Expand Up @@ -98,7 +103,7 @@ void testArrayAndCollectionValues() {
new StructAggregateEmbeddableIntegrationTests.Single(1), null
},
asList('s', 't', null, 'r'),
asList(null, 5),
new HashSet<>(asList(null, 5)),
asList(Long.MAX_VALUE, null, 6L),
asList(null, Double.MAX_VALUE),
asList(null, true),
Expand Down Expand Up @@ -310,8 +315,7 @@ void testArrayAndCollectionValuesOfStructAggregateEmbeddablesHavingArraysAndColl
new StructAggregateEmbeddableIntegrationTests.Single(1)
},
List.of('s', 't', 'r'),
// Hibernate ORM uses `LinkedHashSet`, forcing us to also use it, but messing up the order anyway
new LinkedHashSet<>(List.of(5)),
new HashSet<>(List.of(5)),
List.of(Long.MAX_VALUE, 6L),
List.of(Double.MAX_VALUE),
List.of(true),
Expand Down Expand Up @@ -486,11 +490,47 @@ private static void assertCollectionContainsExactly(String documentAsJsonObject)
assertThat(mongoCollection.find()).containsExactly(BsonDocument.parse(documentAsJsonObject));
}

/** @see BasicCrudIntegrationTests.Item */
@Entity
@Table(name = COLLECTION_NAME)
static class ItemWithArrayAndCollectionValues {
@SqlResultSetMapping(
name = ItemWithArrayAndCollectionValues.MAPPING_FOR_ITEM,
columns = {
@ColumnResult(name = ID_FIELD_NAME),
@ColumnResult(name = "bytes", type = byte[].class),
@ColumnResult(name = "chars", type = char[].class),
@ColumnResult(name = "ints", type = int[].class),
@ColumnResult(name = "longs", type = long[].class),
@ColumnResult(name = "doubles", type = double[].class),
@ColumnResult(name = "booleans", type = boolean[].class),
@ColumnResult(name = "boxedChars", type = Character[].class),
@ColumnResult(name = "boxedInts", type = Integer[].class),
@ColumnResult(name = "boxedLongs", type = Long[].class),
@ColumnResult(name = "boxedDoubles", type = Double[].class),
@ColumnResult(name = "boxedBooleans", type = Boolean[].class),
@ColumnResult(name = "strings", type = String[].class),
@ColumnResult(name = "bigDecimals", type = BigDecimal[].class),
@ColumnResult(name = "objectIds", type = ObjectId[].class),
@ColumnResult(
name = "structAggregateEmbeddables",
type = StructAggregateEmbeddableIntegrationTests.Single[].class),
@ColumnResult(name = "charsCollection", type = Character[].class),
@ColumnResult(name = "intsCollection", type = Integer[].class),
@ColumnResult(name = "longsCollection", type = Long[].class),
@ColumnResult(name = "doublesCollection", type = Double[].class),
@ColumnResult(name = "booleansCollection", type = Boolean[].class),
@ColumnResult(name = "stringsCollection", type = String[].class),
@ColumnResult(name = "bigDecimalsCollection", type = BigDecimal[].class),
@ColumnResult(name = "objectIdsCollection", type = ObjectId[].class),
@ColumnResult(
name = "structAggregateEmbeddablesCollection",
type = StructAggregateEmbeddableIntegrationTests.Single[].class)
})
public static class ItemWithArrayAndCollectionValues {
public static final String MAPPING_FOR_ITEM = "ItemWithArrayAndCollectionValues";

@Id
int id;
public int id;

byte[] bytes;
char[] chars;
Expand Down Expand Up @@ -519,7 +559,7 @@ static class ItemWithArrayAndCollectionValues {

ItemWithArrayAndCollectionValues() {}

ItemWithArrayAndCollectionValues(
public ItemWithArrayAndCollectionValues(
int id,
byte[] bytes,
char[] chars,
Expand Down Expand Up @@ -571,27 +611,73 @@ static class ItemWithArrayAndCollectionValues {
this.objectIdsCollection = objectIdsCollection;
this.structAggregateEmbeddablesCollection = structAggregateEmbeddablesCollection;
}

public static Bson projectAll() {
return project(include(
ID_FIELD_NAME,
"bytes",
"chars",
"ints",
"longs",
"doubles",
"booleans",
"boxedChars",
"boxedInts",
"boxedLongs",
"boxedDoubles",
"boxedBooleans",
"strings",
"bigDecimals",
"objectIds",
"structAggregateEmbeddables",
"charsCollection",
"intsCollection",
"longsCollection",
"doublesCollection",
"booleansCollection",
"stringsCollection",
"bigDecimalsCollection",
"objectIdsCollection",
"structAggregateEmbeddablesCollection"));
}
}

@Entity
@Table(name = COLLECTION_NAME)
static class ItemWithArrayAndCollectionValuesOfStructAggregateEmbeddablesHavingArraysAndCollections {
@SqlResultSetMapping(
name =
ItemWithArrayAndCollectionValuesOfStructAggregateEmbeddablesHavingArraysAndCollections
.MAPPING_FOR_ITEM,
columns = {
@ColumnResult(name = ID_FIELD_NAME),
@ColumnResult(name = "structAggregateEmbeddables", type = ArraysAndCollections[].class),
@ColumnResult(name = "structAggregateEmbeddablesCollection", type = ArraysAndCollections[].class)
})
public static class ItemWithArrayAndCollectionValuesOfStructAggregateEmbeddablesHavingArraysAndCollections {
public static final String MAPPING_FOR_ITEM =
"ItemWithArrayAndCollectionValuesOfStructAggregateEmbeddablesHavingArraysAndCollections";

@Id
int id;
public int id;

ArraysAndCollections[] structAggregateEmbeddables;
Collection<ArraysAndCollections> structAggregateEmbeddablesCollection;

ItemWithArrayAndCollectionValuesOfStructAggregateEmbeddablesHavingArraysAndCollections() {}

ItemWithArrayAndCollectionValuesOfStructAggregateEmbeddablesHavingArraysAndCollections(
public ItemWithArrayAndCollectionValuesOfStructAggregateEmbeddablesHavingArraysAndCollections(
int id,
ArraysAndCollections[] structAggregateEmbeddables,
Collection<ArraysAndCollections> structAggregateEmbeddablesCollection) {
this.id = id;
this.structAggregateEmbeddables = structAggregateEmbeddables;
this.structAggregateEmbeddablesCollection = structAggregateEmbeddablesCollection;
}

public static Bson projectAll() {
return project(
include(ID_FIELD_NAME, "structAggregateEmbeddables", "structAggregateEmbeddablesCollection"));
}
}

@Nested
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,26 @@

package com.mongodb.hibernate;

import static com.mongodb.client.model.Aggregates.project;
import static com.mongodb.client.model.Projections.include;
import static com.mongodb.hibernate.BasicCrudIntegrationTests.Item.MAPPING_FOR_ITEM;
import static com.mongodb.hibernate.MongoTestAssertions.assertEq;
import static com.mongodb.hibernate.internal.MongoConstants.ID_FIELD_NAME;
import static org.assertj.core.api.Assertions.assertThat;

import com.mongodb.client.MongoCollection;
import com.mongodb.hibernate.embeddable.EmbeddableIntegrationTests;
import com.mongodb.hibernate.embeddable.StructAggregateEmbeddableIntegrationTests;
import com.mongodb.hibernate.junit.InjectMongoCollection;
import com.mongodb.hibernate.junit.MongoExtension;
import jakarta.persistence.ColumnResult;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.SqlResultSetMapping;
import jakarta.persistence.Table;
import java.math.BigDecimal;
import org.bson.BsonDocument;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
Expand All @@ -43,10 +52,9 @@
BasicCrudIntegrationTests.ItemDynamicallyUpdated.class,
})
@ExtendWith(MongoExtension.class)
class BasicCrudIntegrationTests implements SessionFactoryScopeAware {
private static final String COLLECTION_NAME = "items";
public class BasicCrudIntegrationTests implements SessionFactoryScopeAware {

@InjectMongoCollection(COLLECTION_NAME)
@InjectMongoCollection(Item.COLLECTION_NAME)
private static MongoCollection<BsonDocument> mongoCollection;

private SessionFactoryScope sessionFactoryScope;
Expand Down Expand Up @@ -348,29 +356,58 @@ private static void assertCollectionContainsExactly(String documentAsJsonObject)
assertThat(mongoCollection.find()).containsExactly(BsonDocument.parse(documentAsJsonObject));
}

/**
* This class should have persistent attributes of all the <a
* href="https://docs.jboss.org/hibernate/orm/6.6/userguide/html_single/Hibernate_User_Guide.html#basic">basic
* types</a> we support. When adding more persistent attributes to this class, we should do similar changes to
* {@link EmbeddableIntegrationTests.Plural}/{@link StructAggregateEmbeddableIntegrationTests.Plural},
* {@link EmbeddableIntegrationTests.ArraysAndCollections}/{@link StructAggregateEmbeddableIntegrationTests.ArraysAndCollections},
* {@link ArrayAndCollectionIntegrationTests.ItemWithArrayAndCollectionValues}.
*/
@Entity
@Table(name = COLLECTION_NAME)
static class Item {
@Id
int id;
@Table(name = Item.COLLECTION_NAME)
@SqlResultSetMapping(
name = MAPPING_FOR_ITEM,
columns = {
@ColumnResult(name = ID_FIELD_NAME),
@ColumnResult(name = "primitiveChar", type = char.class),
@ColumnResult(name = "primitiveInt"),
@ColumnResult(name = "primitiveLong"),
@ColumnResult(name = "primitiveDouble"),
@ColumnResult(name = "primitiveBoolean"),
@ColumnResult(name = "boxedChar", type = Character.class),
@ColumnResult(name = "boxedInt"),
@ColumnResult(name = "boxedLong"),
@ColumnResult(name = "boxedDouble"),
@ColumnResult(name = "boxedBoolean"),
@ColumnResult(name = "string"),
@ColumnResult(name = "bigDecimal"),
@ColumnResult(name = "objectId")
})
public static class Item {
public static final String COLLECTION_NAME = "items";
public static final String MAPPING_FOR_ITEM = "Item";

char primitiveChar;
int primitiveInt;
long primitiveLong;
double primitiveDouble;
boolean primitiveBoolean;
Character boxedChar;
Integer boxedInt;
Long boxedLong;
Double boxedDouble;
Boolean boxedBoolean;
String string;
BigDecimal bigDecimal;
ObjectId objectId;
@Id
public int id;

public char primitiveChar;
public int primitiveInt;
public long primitiveLong;
public double primitiveDouble;
public boolean primitiveBoolean;
public Character boxedChar;
public Integer boxedInt;
public Long boxedLong;
public Double boxedDouble;
public Boolean boxedBoolean;
public String string;
public BigDecimal bigDecimal;
public ObjectId objectId;

Item() {}

Item(
public Item(
int id,
char primitiveChar,
int primitiveInt,
Expand Down Expand Up @@ -400,10 +437,28 @@ static class Item {
this.bigDecimal = bigDecimal;
this.objectId = objectId;
}

public static Bson projectAll() {
return project(include(
ID_FIELD_NAME,
"primitiveChar",
"primitiveInt",
"primitiveLong",
"primitiveDouble",
"primitiveBoolean",
"boxedChar",
"boxedInt",
"boxedLong",
"boxedDouble",
"boxedBoolean",
"string",
"bigDecimal",
"objectId"));
}
}

@Entity
@Table(name = COLLECTION_NAME)
@Table(name = Item.COLLECTION_NAME)
static class ItemDynamicallyUpdated {
@Id
int id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.mongodb.hibernate.embeddable;

import static com.mongodb.hibernate.BasicCrudIntegrationTests.Item.COLLECTION_NAME;
import static com.mongodb.hibernate.MongoTestAssertions.assertEq;
import static com.mongodb.hibernate.MongoTestAssertions.assertUsingRecursiveComparison;
import static java.util.Arrays.asList;
Expand All @@ -25,6 +26,7 @@

import com.mongodb.client.MongoCollection;
import com.mongodb.hibernate.ArrayAndCollectionIntegrationTests;
import com.mongodb.hibernate.BasicCrudIntegrationTests;
import com.mongodb.hibernate.internal.FeatureNotSupportedException;
import com.mongodb.hibernate.junit.InjectMongoCollection;
import com.mongodb.hibernate.junit.MongoExtension;
Expand Down Expand Up @@ -63,8 +65,6 @@
})
@ExtendWith(MongoExtension.class)
public class EmbeddableIntegrationTests implements SessionFactoryScopeAware {
private static final String COLLECTION_NAME = "items";

@InjectMongoCollection(COLLECTION_NAME)
private static MongoCollection<BsonDocument> mongoCollection;

Expand Down Expand Up @@ -581,8 +581,9 @@ ItemWithFlattenedValues getParent() {
}
}

/** @see BasicCrudIntegrationTests.Item */
@Embeddable
record Plural(
public record Plural(
char primitiveChar,
int primitiveInt,
long primitiveLong,
Expand Down Expand Up @@ -613,8 +614,9 @@ static class ItemWithFlattenedValueHavingArraysAndCollections {
}
}

/** @see BasicCrudIntegrationTests.Item */
@Embeddable
static class ArraysAndCollections {
public static class ArraysAndCollections {
byte[] bytes;
char[] chars;
int[] ints;
Expand Down Expand Up @@ -642,7 +644,7 @@ static class ArraysAndCollections {

ArraysAndCollections() {}

ArraysAndCollections(
public ArraysAndCollections(
byte[] bytes,
char[] chars,
int[] ints,
Expand Down
Loading