Skip to content

Commit

Permalink
fix: typos and small fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
loicmathieu committed Sep 6, 2019
1 parent 4653a99 commit 5c4ff38
Show file tree
Hide file tree
Showing 13 changed files with 111 additions and 99 deletions.
5 changes: 4 additions & 1 deletion build-parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@
<microprofile-metrics-api.version>2.0.2</microprofile-metrics-api.version>
<microprofile-rest-client-api.version>1.2.1</microprofile-rest-client-api.version>
<microprofile-open-api.version>1.1.2</microprofile-open-api.version>

<!-- Antlr is used by the PanacheQL parser-->
<antlr.version>4.7.2</antlr.version>
</properties>

<dependencyManagement>
Expand Down Expand Up @@ -247,7 +250,7 @@
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.7.2</version><!-- keep it aligned with the runtime bom-->
<version>${antlr.version}</version><!-- keep it aligned with the runtime bom-->
</plugin>
</plugins>
</pluginManagement>
Expand Down
2 changes: 1 addition & 1 deletion devtools/common/src/main/filtered/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@
"artifactId": "quarkus-mongodb-client"
},
{
"name": "MongoDB Panache",
"name": "MongoDB with Panache",
"labels": [
"mongo",
"mongodb",
Expand Down
3 changes: 2 additions & 1 deletion docs/src/main/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ include::quarkus-intro.adoc[tag=intro]
* link:kogito-guide.html[Using Kogito (business automation with processes and rules)]
* link:oauth2-guide.html[Using OAuth2 RBAC]
* link:tika-guide.html[Using Apache Tika]
* link:mongodb-panache-guid.adoc[Simplified MongoDB with Panache]
* link:mongo-guide.adoc[Using MongoDB]
* link:mongodb-panache-guide.adoc[Simplified MongoDB with Panache]

* link:faq.html[FAQs]

Expand Down
3 changes: 3 additions & 0 deletions docs/src/main/asciidoc/mongo-guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,9 @@ public class CodecFruitService {
}
----

== Simplifying MongoDB with Panache

The link::mongodb-panache-guide.html[MongoDB with Panache] extension facilitate the usage of MongoDB by providing active record style entities (and repositories) like you have in link::hibernate-orm-panache-guide.html[Hibernate ORM with Panache] and focuses on making your entities trivial and fun to write in Quarkus.

== Building a native executable

Expand Down
69 changes: 35 additions & 34 deletions docs/src/main/asciidoc/mongodb-panache-guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc
include::./attributes.adoc[]
:config-file: application.properties

MongoDB is a well known NoSQL Database that is widely used, but using its raw API can be cumbersome as you need to express your entities and your queries as MongoDB Document.
MongoDB is a well known NoSQL Database that is widely used, but using its raw API can be cumbersome as you need to express your entities and your queries as a MongoDB link::https://mongodb.github.io/mongo-java-driver/3.11/bson/documents/#document[`Document`].

MongoDB with Panache provides active record style entities (and repositories) like you have in Hibernate ORM with Panache and focuses on making your entities trivial and fun to write in Quarkus.
MongoDB with Panache provides active record style entities (and repositories) like you have in link::hibernate-orm-panache-guide.html[Hibernate ORM with Panache] and focuses on making your entities trivial and fun to write in Quarkus.

It is build on top of the link::mongo-guide.html[MongoDB Client] extension.

== First: an example

Expand All @@ -31,16 +33,16 @@ public class Person extends PanacheMongoEntity {
return list("status", Status.Alive);
}

public static void deleteStefs(){
delete("name", "Stef");
public static void deleteLoics(){
delete("name", "Loïc");
}
}
--

You have noticed how much more compact and readable the code is compared to using the MongoDB API ?
Does this look interesting? Read on!

NOTE: the `list()` method might be surprising at first. It takes fragments of PanacheQL queries (subset of JPQL) and contextualize the rest.
NOTE: the `list()` method might be surprising at first. It takes fragments of PanacheQL queries (subset of JPQL) and contextualizes the rest.
That makes for very concise but yet readable code.
MongoDB native queries are also supported.

Expand Down Expand Up @@ -106,8 +108,8 @@ For advanced configuration of the MongoDB client, you can follow the link:mongo-

== Defining your entity

To define a Panache entity, simply extend `PanacheMongoEntity`, annotate it with `@MongoEntity` and add your
columns as public fields:
To define a Panache entity, simply extend `PanacheMongoEntity` and add your columns as public fields.
You can add the `@MongoEntity` annotation to your entity if need to customize the name of the collection and/or the database.

[source,java]
--
Expand All @@ -119,13 +121,13 @@ public class Person extends PanacheMongoEntity {
}
--

NOTE: annotating with `@MongoEntity` is optional, it allows to configure the name of the collection and the name of the database. Here the entity will be stored in the `ThePerson` collection instead of the default `Person` collection.
NOTE: annotating with `@MongoEntity` is optional, it allows you to configure the name of the collection and the name of the database. Here the entity will be stored in the `ThePerson` collection instead of the default `Person` collection.

MongoDB with Panache uses the link:https://mongodb.github.io/mongo-java-driver/3.10/bson/pojos/[PojoCodecProvider] to map your entities to MongoDB Document.
MongoDB with Panache uses the link:https://mongodb.github.io/mongo-java-driver/3.10/bson/pojos/[PojoCodecProvider] to map your entities to a MongoDB `Document`.

You will be allowed to use the following annotations to customize this mapping:

- `@BsonId`: customize the id field, by default it's the field named `id` and of type `ObjectId`.
- `@BsonId`: allows you to customize the ID field, see link::#custom-ids[Custom IDs].
- `@BsonProperty`: customize the serialized name of the field.
- `@BsonIgnore`: ignore a field during the serialization.

Expand Down Expand Up @@ -161,7 +163,7 @@ Once you have written your entity, here are the most common operations you will
--
// creating a person
Person person = new Person();
person.name = "Stef";
person.name = "Loïc";
person.birth = LocalDate.of(1910, Month.FEBRUARY, 1);
person.status = Status.Alive;

Expand Down Expand Up @@ -204,6 +206,7 @@ List<String> namesButEmmanuels = persons
.collect(Collectors.toList());
--

NOTE: The `persist()` method needs to be called each time you do a modification to your entity.

== Paging

Expand Down Expand Up @@ -281,20 +284,20 @@ public class Person extends PanacheMongoEntity {
return list("status", Status.Alive);
}

public static void deleteStefs(){
delete("name", "Stef");
public static void deleteLoics(){
delete("name", "Loïc");
}
}
--

== Simplified queries

Normally, MongoDB queries are of this form: `{'firstname': 'John', 'lastname':'Doe'}`, this is what we called MongoDB native queries.
Normally, MongoDB queries are of this form: `{'firstname': 'John', 'lastname':'Doe'}`, this is what we call MongoDB native queries.

You can use them if you want, but we also support what we call **PanacheQL** that can be seen as a subset of JP-QL (or HQL) and allows to easily express a query.
You can use them if you want, but we also support what we call **PanacheQL** that can be seen as a subset of link::https://docs.oracle.com/javaee/7/tutorial/persistence-querylanguage.htm#BNBTG[JPQL] (or link::https://docs.jboss.org/hibernate/core/3.3/reference/en/html/queryhql.html[HQL]) and allows you to easily express a query.
MongoDB with Panache will then map it to a MongoDB native query.

If your query does not start with `{`, we will consider it a PanacheQL query
If your query does not start with `{`, we will consider it a PanacheQL query:

- `<singleColumnName>` (and single parameter) which will expand to `{'singleColumnName': '?'}`
- `<query>` will expand to `{<query>}` where we will map the PanacheQL query to MongoDB native query form. We support the following operators that will be mapped to the corresponding MongoDB operators: 'and', 'or' ( mixing 'and' and 'or' is not currently supported), '=', '>', '>=', '<', '<=', '!=', 'is null', 'is not null', and 'like' that is mapped to the MongoDB `$regex` operator.
Expand All @@ -306,7 +309,7 @@ Here are some query examples:
- `lastname like ?1` will be mapped to `{'lastname': {'$regex': ?1}}`. Be careful that this will be link:https://docs.mongodb.com/manual/reference/operator/query/regex/#op._S_regex[MongoDB regex] support and not SQL like pattern.
- `lastname is not null` will be mapped to `{'lastname':{'$exists': true}}`

We also handle some basic Date type transformation: all fields of type `Date`, `LocalDate` or `LocalDateTime` will be mapped to the MongoDB `ISODate` type.
We also handle some basic date type transformations: all fields of type `Date`, `LocalDate` or `LocalDateTime` will be mapped to the link::https://docs.mongodb.com/manual/reference/bson-types/#document-bson-type-date[BSON Date] using the `ISODate` type (UTC datetime).

MongoDB with Panache also supports extended MongoDB queries by providing a `Document` query, this is supported by the find/list/stream/cout/delete methods.

Expand All @@ -316,16 +319,16 @@ You can pass query parameters, for both native and PanacheQL queries, by index (

[source,java]
--
Person.find("name = ?1 and status = ?2", "stef", Status.Alive);
Person.find("{'name': ?1, 'status': ?2}", "stef", Status.Alive);
Person.find("name = ?1 and status = ?2", "Loïc", Status.Alive);
Person.find("{'name': ?1, 'status': ?2}", "Loïc", Status.Alive);
--

Or by name using a `Map`:

[source,java]
--
Map<String, Object> params = new HashMap<>();
params.put("name", "stef");
params.put("name", "Loïc");
params.put("status", Status.Alive);
Person.find("name = :name and status = :status", params);
Person.find("{'name': :name, 'status', :status}", params);
Expand All @@ -337,25 +340,26 @@ Or using the convenience class `Parameters` to either build a `Map` or just used
--
// generate a Map
Person.find("name = :name and status = :status",
Parameters.with("name", "stef").and("status", Status.Alive).map());
Parameters.with("name", "Loïc").and("status", Status.Alive).map());

// use it as-is
Person.find("{'name': :name, 'status': :status}",
Parameters.with("name", "stef").and("status", Status.Alive));
Parameters.with("name", "Loïc").and("status", Status.Alive));
--

Every query operation accepts passing parameters by index (`Object...`), or by name (`Map<String,Object>` or `Parameters`).

== Query projection

Query projection can be done with the `project()` method on the PanacheQuery object that is returned by the `find()` method.
You can use it to restrict which fields will be returned by the database. Note that the `_id` field will always be returned.
You can use it to restrict which fields will be returned by the database.
Note that the ID field of your entity (the one corresponding to the MongoDB `_id` field) will always be returned.

[source,java]
--
// only 'name' and 'id' fields will be returned
Person.find("status ", "Status.Alive).project("name");
Person.find("{'status': ?1}", Status.Alive).project("name");
PanacheQuery<Person> query = Person.find("status ", "Status.Alive).project("name");
PanacheQuery<Person> query = Person.find("{'status': ?1}", Status.Alive).project("name");
--

== The DAO/Repository option
Expand All @@ -380,8 +384,8 @@ public class PersonRepository implements PanacheMongoRepository<Person> {
return list("status", Status.Alive);
}

public void deleteStefs(){
delete("name", "Stef");
public void deleteLoics(){
delete("name", "Loïc");
}
}
--
Expand Down Expand Up @@ -410,7 +414,7 @@ MongoDB offers ACID transactions since version 4.0. MongoDB with Panache doesn't

== Custom IDs

IDs are often a touchy subject, in MongoDB they are usually auto-generated by the database with an `ObjectId`.
IDs are often a touchy subject, in MongoDB they are usually auto-generated by the database with an `ObjectId` type.
In MongoDB with Panache the ID are defined by a field named `id` of the `org.bson.types.ObjectId` type,
but if you want ot customize them, once again we have you covered.

Expand Down Expand Up @@ -448,10 +452,7 @@ you need to provide the value by yourself.
====

`ObjectId` can be difficult to use if you want to expose its value in your rest service.
So we create JSON-B providers to serialize/deserialize them as String and also Jackson equivalent.

JSON-B providers and Jackson serializer/deserializer are automatically registered as soon as one of Resteasy with JSON-B or Resteasy with Jackson extensions are used.

So we created JSON-B and Jackson providers to serialize/deserialize them as a `String` which are are automatically registered if your project depends on one of the Resteasy with JSON-B or Resteasy with Jackson extensions.
== How and why we simplify MongoDB API

When it comes to writing MongoDB entities, there are a number of annoying things that users have grown used to
Expand All @@ -467,7 +468,7 @@ the fields.
we would never do something like that for regular objects in the Object Oriented architecture, where state and methods are in the same class. Moreover, this requires two classes per entity, and requires injection of the DAO or Repository where you need to do entity operations, which breaks your edit flow and requires you to get out of the code you're writing to set up an injection point before coming back to use it.
- MongoDB queries are super powerful, but overly verbose for common operations, requiring you to write queries even
when you don't need all the parts.
- MongoDB queries are JSON based, so you will need some String manipulation or using the `Document` type and it will needs a lot of boilerplate code.
- MongoDB queries are JSON based, so you will need some String manipulation or using the `Document` type and it will need a lot of boilerplate code.

With Panache, we took an opinionated approach to tackle all these problems:

Expand All @@ -478,7 +479,7 @@ that are missing, and rewrite every access to these fields to use the accessor m
write _useful_ accessors when you need them, which will be used even though your entity users still use field accesses.
- Don't use DAOs or Repositories: put all your entity logic in static methods in your entity class. Your entity superclass comes with lots of super useful static methods and you can add your own in your entity class. Users can just start using your entity `Person` by typing `Person.` and getting completion for all the operations in a single place.
- Don't write parts of the query that you don't need: write `Person.find("order by name")` or
`Person.find("name = ?1 and status = ?2", "stef", Status.Alive)` or even better `Person.find("name", "stef")`.
`Person.find("name = ?1 and status = ?2", "Loïc", Status.Alive)` or even better `Person.find("name", "Loïc")`.

That's all there is to it: with Panache, MongoDB has never looked so trim and neat.

Expand Down
4 changes: 3 additions & 1 deletion extensions/panache/mongodb-panache/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,10 @@
<fileSet>
<directory>${project.build.directory}/classes</directory>
<excludes>
<!-- We avoid indexing at as it needs to be included in the apps only if jaxrs and jsonb are. -->
<!-- We avoid indexing it as it needs to be included in the apps only if jaxrs and jsonb are. -->
<exclude>**/PanacheMongoJsonbContextResolver.class</exclude>
<!-- We avoid indexing it as it needs to be included in the apps only if jackson is. -->
<exclude>**/ObjectMapperProducer.class</exclude>
</excludes>
</fileSet>
</fileSets>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@

/**
* This annotation can be used to specify some configuration of the mapping of an entity to MongoDB.
* It allows to set the following prioperties:
* <ul>
* <li><code>collection</code>: the name of the collection (if not set the name of the entity class will be used)</li>
* <li><code>database</code>: the name of the database (if not set the default from the property
* <code>quarkus.mongodb.database</code> will be used.</li>
* </ul>
*
* @author Loïc Mathieu - [email protected]
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface MongoEntity {
/**
* The name of the collection (if not set the name of the entity class will be used)
*/
String collection() default "";

/**
* the name of the database (if not set the default from the property
* <code>quarkus.mongodb.database</code> will be used.
*/
String database() default "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ public abstract class PanacheMongoEntity extends PanacheMongoEntityBase {

/**
* The auto-generated ID field. This field is set by Mongo when this entity
* is inserted.
* is persist.
*
* @see #insert()
* @see #persist()
*/
public ObjectId id;

Expand Down
Loading

0 comments on commit 5c4ff38

Please sign in to comment.