Add jMolecules example for Spring Data MongoDB.

This commit is contained in:
Oliver Drotbohm
2021-03-16 17:15:24 +01:00
committed by Oliver Drotbohm
parent 9c3db43d02
commit 8406f3f980
12 changed files with 408 additions and 1 deletions

View File

@@ -59,6 +59,7 @@ We have separate folders for the samples of individual modules:
* `geo-json` - Example project showing usage of [GeoJSON](http://geojson.org) with MongoDB.
* `gridfs` - Example project showing usage of gridFS with MongoDB.
* `java8` - Example of how to use Spring Data MongoDB with Java 8 date time types as well as the usage of `Optional` as return type for repository methods. Note, this project requires to be build with JDK 8.
* `jmolecules` - Example of Spring Data MongoDB working with a jMolecules based domain model.
* `kotlin` - Example for using [Kotlin](https://kotlinlang.org/) with MongoDB.
* `query-by-example` - Example project showing usage of Query by Example with MongoDB.
* `querydsl` - Example project showing imperative and reactive [Querydsl](https://github.com/querydsl/querydsl) support for MongoDB.
@@ -113,5 +114,5 @@ We have separate folders for the samples of individual modules:
## Note
* The example projects make use of the [Lombok](https://projectlombok.org/) plugin. To get proper code navigation in your IDE, you must install it separately.
* The example projects make use of the [Lombok](https://projectlombok.org/) plugin. To get proper code navigation in your IDE, you must install it separately.
Lombok is available in the IntelliJ plugins repository and as a [download](https://projectlombok.org/download) for Eclipse-based IDEs.

View File

@@ -0,0 +1,63 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.data.examples</groupId>
<artifactId>spring-data-mongodb-examples</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</parent>
<name>Spring Data MongoDB - jMolecules Example</name>
<artifactId>spring-data-mongodb-jmolecules</artifactId>
<properties>
<spring-data-bom.version>2021.0.0-SNAPSHOT</spring-data-bom.version>
<jmolecules.version>1.2.0</jmolecules.version>
<jmolecules-integration.version>0.2.0</jmolecules-integration.version>
</properties>
<dependencies>
<!-- jMolecules -->
<dependency>
<groupId>org.jmolecules.integrations</groupId>
<artifactId>jmolecules-spring</artifactId>
<version>${jmolecules-integration.version}</version>
</dependency>
<dependency>
<groupId>org.jmolecules</groupId>
<artifactId>jmolecules-events</artifactId>
<version>${jmolecules.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy-maven-plugin</artifactId>
<version>${byte-buddy.version}</version>
<executions>
<execution>
<goals>
<goal>transform</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.jmolecules.integrations</groupId>
<artifactId>jmolecules-bytebuddy</artifactId>
<version>${jmolecules-integration.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Oliver Drotbohm
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.customer;
import lombok.Value;
import org.jmolecules.ddd.annotation.ValueObject;
@Value
@ValueObject
public class Address {
private final String street, city, zipCode;
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.customer;
import example.springdata.mongodb.customer.Customer.CustomerId;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
import lombok.Value;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.jmolecules.ddd.types.AggregateRoot;
import org.jmolecules.ddd.types.Identifier;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.util.Assert;
/**
* @author Oliver Drotbohm
*/
@Getter
@ToString
@AllArgsConstructor(access = AccessLevel.PRIVATE, onConstructor = @__(@PersistenceConstructor))
public class Customer implements AggregateRoot<Customer, CustomerId> {
private final CustomerId id;
private String firstname, lastname;
private List<Address> addresses;
public Customer(String firstname, String lastname, Address address) {
Assert.notNull(address, "Address must not be null!");
this.id = CustomerId.of(UUID.randomUUID());
this.firstname = firstname;
this.lastname = lastname;
this.addresses = new ArrayList<>();
this.addresses.add(address);
}
@Value(staticConstructor = "of")
public static class CustomerId implements Identifier {
private final UUID id;
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.customer;
import example.springdata.mongodb.customer.Customer.CustomerId;
import org.jmolecules.ddd.types.Repository;
import org.jmolecules.spring.AssociationResolver;
/**
* @author Oliver Drotbohm
*/
public interface Customers extends Repository<Customer, CustomerId>, AssociationResolver<Customer, CustomerId> {
Customer save(Customer customer);
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.order;
import lombok.Value;
import org.jmolecules.ddd.annotation.ValueObject;
@Value
@ValueObject
public class LineItem {
String description;
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.order;
import example.springdata.mongodb.customer.Customer;
import example.springdata.mongodb.customer.Customer.CustomerId;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import lombok.Value;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.jmolecules.ddd.types.AggregateRoot;
import org.jmolecules.ddd.types.Association;
import org.jmolecules.ddd.types.Identifier;
/**
* @author Oliver Drotbohm
*/
@Getter
@ToString
@RequiredArgsConstructor
public class Order implements AggregateRoot<Order, Order.OrderId> {
private final OrderId id;
private List<LineItem> lineItems;
private Association<Customer, CustomerId> customer;
public Order(Customer customer) {
this.id = OrderId.of(UUID.randomUUID());
this.customer = Association.forAggregate(customer);
this.lineItems = new ArrayList<>();
}
public Order addLineItem(String description) {
LineItem item = new LineItem(description);
this.lineItems.add(item);
return this;
}
@Value(staticConstructor = "of")
public static class OrderId implements Identifier {
private final UUID orderId;
public static OrderId create() {
return OrderId.of(UUID.randomUUID());
}
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright 2020-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.order;
import example.springdata.mongodb.order.Order.OrderId;
import org.jmolecules.ddd.types.Repository;
import org.jmolecules.spring.AssociationResolver;
/**
* @author Oliver Drotbohm
*/
public interface Orders extends Repository<Order, OrderId>, AssociationResolver<Order, OrderId> {
Order save(Order order);
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2020-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb;
import static org.assertj.core.api.Assertions.*;
import example.springdata.mongodb.customer.Address;
import example.springdata.mongodb.customer.Customer;
import example.springdata.mongodb.customer.Customers;
import example.springdata.mongodb.order.Order;
import example.springdata.mongodb.order.Orders;
import lombok.RequiredArgsConstructor;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
/**
* @author Oliver Drotbohm
*/
@SpringBootTest
@RequiredArgsConstructor
class ApplicationIntegrationTests {
private final ConfigurableApplicationContext context;
@Test
void exposesAssociationInMetamodel() {
MongoMappingContext mapping = context.getBean(MongoMappingContext.class);
MongoPersistentEntity<?> entity = mapping.getRequiredPersistentEntity(Order.class);
MongoPersistentProperty customer = entity.getRequiredPersistentProperty("customer");
assertThat(customer.isAssociation()).isTrue();
}
@Test
void persistsDomainModel() {
Address address = new Address("41 Greystreet", "Dreaming Tree", "2731");
Customers customers = context.getBean(Customers.class);
Customer customer = customers.save(new Customer("Dave", "Matthews", address));
Orders orders = context.getBean(Orders.class);
Order order = new Order(customer)
.addLineItem("Foo")
.addLineItem("Bar");
Order result = orders.save(order);
assertThat(customers.resolveRequired(result.getCustomer()));
}
}

View File

@@ -24,6 +24,7 @@
<module>geo-json</module>
<module>gridfs</module>
<module>java8</module>
<module>jmolecules</module>
<module>kotlin</module>
<module>query-by-example</module>
<module>reactive</module>