Add nullability constraints everywhere.

Change-Id: I80577b7784006070f29ce11af4e6fd87c10363bf
diff --git a/pom.xml b/pom.xml
index f903800..bd812b8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,6 +28,7 @@
     <quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
     <quarkus.platform.version>1.4.0.CR1</quarkus.platform.version>
 
+    <basic-annotations.version>0.2.0</basic-annotations.version>
     <findbugs-jsr305.version>3.0.2</findbugs-jsr305.version>
     <flexmark.version>0.61.10</flexmark.version>
     <hibernate.version>5.4.14.Final</hibernate.version>
@@ -58,6 +59,14 @@
         <version>${hibernate-types.version}</version>
       </dependency>
 
+      <!-- Annotations -->
+      <dependency>
+        <groupId>pl.tlinkowski.annotation</groupId>
+        <artifactId>pl.tlinkowski.annotation.basic</artifactId>
+        <version>${basic-annotations.version}</version>
+        <scope>provided</scope>
+      </dependency>
+
       <!-- Jsoup -->
       <dependency>
         <groupId>org.jsoup</groupId>
@@ -215,6 +224,13 @@
       <artifactId>hibernate-types-52</artifactId>
     </dependency>
 
+    <!-- Annotations -->
+    <dependency>
+      <groupId>pl.tlinkowski.annotation</groupId>
+      <artifactId>pl.tlinkowski.annotation.basic</artifactId>
+      <scope>provided</scope>
+    </dependency>
+
     <!-- Jsoup -->
     <dependency>
       <groupId>org.jsoup</groupId>
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/accesscontrol/Role.java b/src/main/java/eu/mulk/mulkcms2/benki/accesscontrol/Role.java
index 349322b..87b477d 100644
--- a/src/main/java/eu/mulk/mulkcms2/benki/accesscontrol/Role.java
+++ b/src/main/java/eu/mulk/mulkcms2/benki/accesscontrol/Role.java
@@ -7,6 +7,7 @@
 import java.util.Collection;
 import java.util.Objects;
 import java.util.Set;
+import javax.annotation.CheckForNull;
 import javax.persistence.CollectionTable;
 import javax.persistence.Column;
 import javax.persistence.ElementCollection;
@@ -32,6 +33,7 @@
   public Integer id;
 
   @Column(name = "name", nullable = true, length = -1)
+  @CheckForNull
   public String name;
 
   @OneToMany(mappedBy = "target", fetch = FetchType.LAZY)
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/accesscontrol/package-info.java b/src/main/java/eu/mulk/mulkcms2/benki/accesscontrol/package-info.java
new file mode 100644
index 0000000..6e008a4
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/benki/accesscontrol/package-info.java
@@ -0,0 +1,4 @@
+@NonNullPackage
+package eu.mulk.mulkcms2.benki.accesscontrol;
+
+import pl.tlinkowski.annotation.basic.NonNullPackage;
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/Bookmark.java b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/Bookmark.java
index 8d0b2f8..5c1342a 100644
--- a/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/Bookmark.java
+++ b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/Bookmark.java
@@ -21,9 +21,11 @@
   public String uri;
 
   @Column(name = "title", nullable = true, length = -1)
+  @CheckForNull
   public String title;
 
   @Column(name = "description", nullable = true, length = -1)
+  @CheckForNull
   public String description;
 
   @ElementCollection(fetch = FetchType.LAZY)
@@ -35,7 +37,11 @@
   public Set<String> tags;
 
   @Transient
+  @CheckForNull
   public String getDescriptionHtml() {
+    if (description == null) {
+      return null;
+    }
     return new MarkdownConverter().htmlify(description);
   }
 
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java
index cb4c20f..5ff8463 100644
--- a/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java
+++ b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java
@@ -14,12 +14,14 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.time.OffsetDateTime;
+import java.util.Objects;
 import java.util.Set;
 import javax.annotation.CheckForNull;
 import javax.inject.Inject;
 import javax.json.JsonObject;
 import javax.transaction.Transactional;
 import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
 import javax.ws.rs.FormParam;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
@@ -44,19 +46,19 @@
   @Transactional
   @Authenticated
   public Response postBookmark(
-      @FormParam("uri") URI uri,
+      @FormParam("uri") @NotNull URI uri,
       @FormParam("title") @NotEmpty String title,
-      @FormParam("description") String description,
-      @FormParam("visibility") Post.Visibility visibility)
+      @FormParam("description") @CheckForNull String description,
+      @FormParam("visibility") @NotNull Post.Visibility visibility)
       throws URISyntaxException {
 
-    var user = getCurrentUser();
+    var user = Objects.requireNonNull(getCurrentUser());
 
     var bookmark = new Bookmark();
     bookmark.uri = uri.toString();
     bookmark.title = title;
     bookmark.tags = Set.of();
-    bookmark.description = description != null ? description : "";
+    bookmark.description = description;
     bookmark.owner = user;
     bookmark.date = OffsetDateTime.now();
 
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/package-info.java b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/package-info.java
new file mode 100644
index 0000000..bc30b02
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/package-info.java
@@ -0,0 +1,4 @@
+@NonNullPackage
+package eu.mulk.mulkcms2.benki.bookmarks;
+
+import pl.tlinkowski.annotation.basic.NonNullPackage;
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatMessage.java b/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatMessage.java
index 1e92c38..ffafb96 100644
--- a/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatMessage.java
+++ b/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatMessage.java
@@ -17,6 +17,7 @@
 public class LazychatMessage extends Post {
 
   @Column(name = "content", nullable = true, length = -1)
+  @CheckForNull
   public String content;
 
   @Column(name = "format", nullable = false, length = -1)
@@ -28,7 +29,11 @@
 
   @Transient
   @JsonbTransient
+  @CheckForNull
   public String getContentHtml() {
+    if (content == null) {
+      return null;
+    }
     return new MarkdownConverter().htmlify(content);
   }
 
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatResource.java b/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatResource.java
index fa2da99..b919ad3 100644
--- a/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatResource.java
+++ b/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatResource.java
@@ -9,6 +9,7 @@
 import java.time.OffsetDateTime;
 import java.util.Objects;
 import javax.transaction.Transactional;
+import javax.validation.constraints.NotNull;
 import javax.ws.rs.ForbiddenException;
 import javax.ws.rs.FormParam;
 import javax.ws.rs.NotFoundException;
@@ -28,10 +29,11 @@
   @Transactional
   @Authenticated
   public Response postMessage(
-      @FormParam("text") String text, @FormParam("visibility") Post.Visibility visibility)
+      @FormParam("text") @NotNull String text,
+      @FormParam("visibility") @NotNull Post.Visibility visibility)
       throws URISyntaxException {
 
-    var user = getCurrentUser();
+    var user = Objects.requireNonNull(getCurrentUser());
 
     var message = new LazychatMessage();
     message.content = text;
@@ -56,7 +58,7 @@
       @FormParam("visibility") Post.Visibility visibility)
       throws URISyntaxException {
 
-    var user = getCurrentUser();
+    var user = Objects.requireNonNull(getCurrentUser());
 
     var message = getSession().byId(LazychatMessage.class).load(id);
 
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/lazychat/package-info.java b/src/main/java/eu/mulk/mulkcms2/benki/lazychat/package-info.java
new file mode 100644
index 0000000..9c27ef4
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/benki/lazychat/package-info.java
@@ -0,0 +1,4 @@
+@NonNullPackage
+package eu.mulk.mulkcms2.benki.lazychat;
+
+import pl.tlinkowski.annotation.basic.NonNullPackage;
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java b/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java
index 5ecccc7..c402265 100644
--- a/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java
+++ b/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java
@@ -55,6 +55,7 @@
   public Integer id;
 
   @Column(name = "date", nullable = true)
+  @CheckForNull
   public OffsetDateTime date;
 
   @ManyToOne(fetch = FetchType.LAZY)
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java b/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java
index ebf154e..59bfb89 100644
--- a/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java
+++ b/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java
@@ -229,12 +229,20 @@
   }
 
   @TemplateExtension
-  static String humanDateTime(TemporalAccessor x) {
+  @CheckForNull
+  static String humanDateTime(@CheckForNull TemporalAccessor x) {
+    if (x == null) {
+      return null;
+    }
     return humanDateFormatter.format(x);
   }
 
   @TemplateExtension
-  static String htmlDateTime(TemporalAccessor x) {
+  @CheckForNull
+  static String htmlDateTime(@CheckForNull TemporalAccessor x) {
+    if (x == null) {
+      return null;
+    }
     return htmlDateFormatter.format(x);
   }
 
@@ -293,7 +301,7 @@
   }
 
   protected final Post getPostIfVisible(int id) {
-    var user = getCurrentUser();
+    @CheckForNull var user = getCurrentUser();
     var message = getSession().byId(Post.class).load(id);
 
     if (!message.isVisibleTo(user)) {
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/posts/package-info.java b/src/main/java/eu/mulk/mulkcms2/benki/posts/package-info.java
new file mode 100644
index 0000000..cffcaaa
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/benki/posts/package-info.java
@@ -0,0 +1,4 @@
+@NonNullPackage
+package eu.mulk.mulkcms2.benki.posts;
+
+import pl.tlinkowski.annotation.basic.NonNullPackage;
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/users/User.java b/src/main/java/eu/mulk/mulkcms2/benki/users/User.java
index c5d491e..96feafc 100644
--- a/src/main/java/eu/mulk/mulkcms2/benki/users/User.java
+++ b/src/main/java/eu/mulk/mulkcms2/benki/users/User.java
@@ -10,6 +10,7 @@
 import java.util.Collection;
 import java.util.Objects;
 import java.util.Set;
+import javax.annotation.CheckForNull;
 import javax.persistence.CollectionTable;
 import javax.persistence.Column;
 import javax.persistence.ElementCollection;
@@ -36,21 +37,27 @@
   public Integer id;
 
   @Column(name = "first_name", nullable = true, length = -1)
+  @CheckForNull
   public String firstName;
 
   @Column(name = "middle_names", nullable = true, length = -1)
+  @CheckForNull
   public String middleNames;
 
   @Column(name = "last_name", nullable = true, length = -1)
+  @CheckForNull
   public String lastName;
 
   @Column(name = "email", nullable = true, length = -1)
+  @CheckForNull
   public String email;
 
   @Column(name = "website", nullable = true, length = -1)
+  @CheckForNull
   public String website;
 
   @Column(name = "status", nullable = true, length = -1)
+  @CheckForNull
   public String status;
 
   @OneToMany(mappedBy = "owner", fetch = FetchType.LAZY)
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/users/package-info.java b/src/main/java/eu/mulk/mulkcms2/benki/users/package-info.java
new file mode 100644
index 0000000..f5e909d
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/benki/users/package-info.java
@@ -0,0 +1,4 @@
+@NonNullPackage
+package eu.mulk.mulkcms2.benki.users;
+
+import pl.tlinkowski.annotation.basic.NonNullPackage;
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/wiki/WikiPageRevision.java b/src/main/java/eu/mulk/mulkcms2/benki/wiki/WikiPageRevision.java
index 4054312..df90421 100644
--- a/src/main/java/eu/mulk/mulkcms2/benki/wiki/WikiPageRevision.java
+++ b/src/main/java/eu/mulk/mulkcms2/benki/wiki/WikiPageRevision.java
@@ -6,6 +6,7 @@
 import java.util.function.Function;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
@@ -31,15 +32,19 @@
   public Integer id;
 
   @Column(name = "date", nullable = true)
+  @CheckForNull
   public OffsetDateTime date;
 
   @Column(name = "title", nullable = true, length = -1)
+  @CheckForNull
   public String title;
 
   @Column(name = "content", nullable = true, length = -1)
+  @CheckForNull
   public String content;
 
   @Column(name = "format", nullable = true, length = -1)
+  @CheckForNull
   public String format;
 
   @ManyToOne(fetch = FetchType.LAZY)
@@ -67,7 +72,11 @@
     this.author = author;
   }
 
+  @CheckForNull
   public String enrichedContent() {
+    if (content == null) {
+      return null;
+    }
     return wikilinkify(hrefify(Jsoup.parse(content))).select("body").html();
   }
 
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/wiki/WikiResource.java b/src/main/java/eu/mulk/mulkcms2/benki/wiki/WikiResource.java
index 0b827c1..5ed5dff 100644
--- a/src/main/java/eu/mulk/mulkcms2/benki/wiki/WikiResource.java
+++ b/src/main/java/eu/mulk/mulkcms2/benki/wiki/WikiResource.java
@@ -18,6 +18,7 @@
 import java.time.format.FormatStyle;
 import java.time.temporal.TemporalAccessor;
 import java.util.Optional;
+import javax.annotation.CheckForNull;
 import javax.inject.Inject;
 import javax.json.JsonObject;
 import javax.json.spi.JsonProvider;
@@ -87,8 +88,8 @@
   @Produces(APPLICATION_JSON)
   public JsonObject updatePage(
       @PathParam("pageName") String pageName,
-      @FormParam("wiki-title") String title,
-      @FormParam("wiki-content") String content) {
+      @FormParam("wiki-title") @CheckForNull String title,
+      @FormParam("wiki-content") @CheckForNull String content) {
 
     if (title == null && content == null) {
       // No changes, nothing to do.
@@ -163,12 +164,20 @@
   }
 
   @TemplateExtension
-  static String humanDateTime(TemporalAccessor x) {
+  @CheckForNull
+  static String humanDateTime(@CheckForNull TemporalAccessor x) {
+    if (x == null) {
+      return null;
+    }
     return humanDateFormatter.format(x);
   }
 
   @TemplateExtension
-  static String htmlDateTime(TemporalAccessor x) {
+  @CheckForNull
+  static String htmlDateTime(@CheckForNull TemporalAccessor x) {
+    if (x == null) {
+      return null;
+    }
     return htmlDateFormatter.format(x);
   }
 }
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/wiki/package-info.java b/src/main/java/eu/mulk/mulkcms2/benki/wiki/package-info.java
new file mode 100644
index 0000000..dc3ad4a
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/benki/wiki/package-info.java
@@ -0,0 +1,4 @@
+@NonNullPackage
+package eu.mulk.mulkcms2.benki.wiki;
+
+import pl.tlinkowski.annotation.basic.NonNullPackage;
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/about/package-info.java b/src/main/java/eu/mulk/mulkcms2/cms/about/package-info.java
new file mode 100644
index 0000000..2316652
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/about/package-info.java
@@ -0,0 +1,4 @@
+@NonNullPackage
+package eu.mulk.mulkcms2.cms.about;
+
+import pl.tlinkowski.annotation.basic.NonNullPackage;
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/comments/Comment.java b/src/main/java/eu/mulk/mulkcms2/cms/comments/Comment.java
index 11df62b..9f91c6b 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/comments/Comment.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/comments/Comment.java
@@ -3,6 +3,7 @@
 import eu.mulk.mulkcms2.cms.pages.Article;
 import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
 import java.util.Collection;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
@@ -24,6 +25,7 @@
   public Integer id;
 
   @Column(name = "global_id", nullable = true, length = -1)
+  @CheckForNull
   public String globalId;
 
   @OneToMany(mappedBy = "comment", fetch = FetchType.LAZY)
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/comments/CommentRevision.java b/src/main/java/eu/mulk/mulkcms2/cms/comments/CommentRevision.java
index 7d642d4..2835345 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/comments/CommentRevision.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/comments/CommentRevision.java
@@ -5,6 +5,7 @@
 import eu.mulk.mulkcms2.cms.users.User;
 import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
 import java.sql.Timestamp;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
@@ -27,6 +28,7 @@
   public Integer id;
 
   @Column(name = "date", nullable = true)
+  @CheckForNull
   public Timestamp date;
 
   @Column(name = "content", nullable = false, length = -1)
@@ -39,12 +41,15 @@
   public String status;
 
   @Column(name = "article_revision", nullable = true)
+  @CheckForNull
   public Integer articleRevision;
 
   @Column(name = "submitter_ip", nullable = true, columnDefinition = "inet")
+  @CheckForNull
   public Inet submitterIp;
 
   @Column(name = "submitter_user_agent", nullable = true, length = -1)
+  @CheckForNull
   public String submitterUserAgent;
 
   @ManyToOne(fetch = FetchType.LAZY)
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/comments/package-info.java b/src/main/java/eu/mulk/mulkcms2/cms/comments/package-info.java
new file mode 100644
index 0000000..216fcaf
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/comments/package-info.java
@@ -0,0 +1,4 @@
+@NonNullPackage
+package eu.mulk.mulkcms2.cms.comments;
+
+import pl.tlinkowski.annotation.basic.NonNullPackage;
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/journal/Journal.java b/src/main/java/eu/mulk/mulkcms2/cms/journal/Journal.java
index fe11ca0..a33ba4f 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/journal/Journal.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/journal/Journal.java
@@ -2,6 +2,7 @@
 
 import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
 import java.util.Collection;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
@@ -21,6 +22,7 @@
   public Integer id;
 
   @Column(name = "path_prefix", nullable = true, length = -1)
+  @CheckForNull
   public String pathPrefix;
 
   @OneToMany(mappedBy = "journal", fetch = FetchType.LAZY)
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/journal/package-info.java b/src/main/java/eu/mulk/mulkcms2/cms/journal/package-info.java
new file mode 100644
index 0000000..be02d57
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/journal/package-info.java
@@ -0,0 +1,4 @@
+@NonNullPackage
+package eu.mulk.mulkcms2.cms.journal;
+
+import pl.tlinkowski.annotation.basic.NonNullPackage;
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalComment.java b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalComment.java
index 06ca820..186d343 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalComment.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalComment.java
@@ -1,6 +1,7 @@
 package eu.mulk.mulkcms2.cms.legacyjournal;
 
 import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
@@ -30,15 +31,19 @@
   public String body;
 
   @Column(name = "author", nullable = true, length = -1)
+  @CheckForNull
   public String author;
 
   @Column(name = "email", nullable = true, length = -1)
+  @CheckForNull
   public String email;
 
   @Column(name = "website", nullable = true, length = -1)
+  @CheckForNull
   public String website;
 
   @Column(name = "spam_p", nullable = true)
+  @CheckForNull
   public Boolean spamP;
 
   @Column(name = "submitter_ip", nullable = false, length = -1)
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalEntry.java b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalEntry.java
index fcbf895..ad95270 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalEntry.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalEntry.java
@@ -2,6 +2,7 @@
 
 import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
 import java.util.Collection;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
@@ -30,6 +31,7 @@
   public long date;
 
   @Column(name = "last_modification", nullable = true)
+  @CheckForNull
   public Long lastModification;
 
   @Column(name = "body", nullable = false, length = -1)
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalPingback.java b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalPingback.java
index 2d2702b..f31e44e 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalPingback.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalPingback.java
@@ -1,6 +1,7 @@
 package eu.mulk.mulkcms2.cms.legacyjournal;
 
 import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
@@ -27,9 +28,11 @@
   public long date;
 
   @Column(name = "url", nullable = true, length = -1)
+  @CheckForNull
   public String url;
 
   @Column(name = "spam_p", nullable = true)
+  @CheckForNull
   public Boolean spamP;
 
   @Column(name = "submitter_ip", nullable = false, length = -1)
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalTrackback.java b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalTrackback.java
index 618a2e3..f86f95f 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalTrackback.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalTrackback.java
@@ -1,6 +1,7 @@
 package eu.mulk.mulkcms2.cms.legacyjournal;
 
 import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
@@ -30,15 +31,19 @@
   public String excerpt;
 
   @Column(name = "title", nullable = true, length = -1)
+  @CheckForNull
   public String title;
 
   @Column(name = "blog_name", nullable = true, length = -1)
+  @CheckForNull
   public String blogName;
 
   @Column(name = "url", nullable = true, length = -1)
+  @CheckForNull
   public String url;
 
   @Column(name = "spam_p", nullable = true)
+  @CheckForNull
   public Boolean spamP;
 
   @Column(name = "submitter_ip", nullable = false, length = -1)
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/package-info.java b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/package-info.java
new file mode 100644
index 0000000..df36a3e
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/package-info.java
@@ -0,0 +1,4 @@
+@NonNullPackage
+package eu.mulk.mulkcms2.cms.legacyjournal;
+
+import pl.tlinkowski.annotation.basic.NonNullPackage;
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleBranchTip.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleBranchTip.java
index f72d36e..5b45216 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleBranchTip.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleBranchTip.java
@@ -1,6 +1,7 @@
 package eu.mulk.mulkcms2.cms.pages;
 
 import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Id;
@@ -14,11 +15,12 @@
 @Immutable
 public class ArticleBranchTip extends PanacheEntityBase {
 
-  @Column(name = "article", nullable = true)
+  @Column(name = "article", nullable = false)
   @Id
-  private Integer articleId;
+  private int articleId;
 
   @Column(name = "revision", nullable = true)
   @Id
+  @CheckForNull
   private Integer revisionId;
 }
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleCommentCount.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleCommentCount.java
index 2c9af5f..f7993f1 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleCommentCount.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleCommentCount.java
@@ -12,10 +12,10 @@
 @Immutable
 public class ArticleCommentCount extends PanacheEntityBase {
 
-  @Column(name = "article", nullable = true)
+  @Column(name = "article", nullable = false)
   @Id
-  public Integer article;
+  public int articleId;
 
-  @Column(name = "comment_count", nullable = true)
-  public Long commentCount;
+  @Column(name = "comment_count", nullable = false)
+  public long commentCount;
 }
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticlePublishingDate.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticlePublishingDate.java
index 532c148..1fe92f3 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticlePublishingDate.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticlePublishingDate.java
@@ -2,6 +2,7 @@
 
 import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
 import java.sql.Timestamp;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Id;
@@ -13,10 +14,11 @@
 @Immutable
 public class ArticlePublishingDate extends PanacheEntityBase {
 
-  @Column(name = "article", nullable = true)
+  @Column(name = "article", nullable = false)
   @Id
-  public Integer article;
+  public int article;
 
   @Column(name = "publishing_date", nullable = true)
+  @CheckForNull
   public Timestamp publishingDate;
 }
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevision.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevision.java
index 2034e35..cf45142 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevision.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevision.java
@@ -5,6 +5,7 @@
 import java.sql.Timestamp;
 import java.util.Collection;
 import java.util.Set;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
@@ -28,6 +29,7 @@
   public Integer id;
 
   @Column(name = "date", nullable = true)
+  @CheckForNull
   public Timestamp date;
 
   @Column(name = "title", nullable = false, length = -1)
@@ -43,6 +45,7 @@
   public String status;
 
   @Column(name = "global_id", nullable = true, length = -1)
+  @CheckForNull
   public String globalId;
 
   @OneToMany(mappedBy = "articleRevision", fetch = FetchType.LAZY)
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevisionCharacteristic.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevisionCharacteristic.java
index d5ca828..0ac7ae5 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevisionCharacteristic.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevisionCharacteristic.java
@@ -1,6 +1,7 @@
 package eu.mulk.mulkcms2.cms.pages;
 
 import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
@@ -33,5 +34,6 @@
   public ArticleRevision articleRevision;
 
   @Column(name = "value", nullable = true, length = -1)
+  @CheckForNull
   public String value;
 }
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleType.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleType.java
index c59acaa..c2c50bb 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleType.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleType.java
@@ -2,6 +2,7 @@
 
 import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
 import java.util.Collection;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
@@ -21,9 +22,11 @@
   public Integer id;
 
   @Column(name = "name", nullable = true, length = -1)
+  @CheckForNull
   public String name;
 
   @Column(name = "page_template", nullable = true, length = -1)
+  @CheckForNull
   public String pageTemplate;
 
   @OneToMany(mappedBy = "type", fetch = FetchType.LAZY)
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/package-info.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/package-info.java
new file mode 100644
index 0000000..2cbe2ac
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/package-info.java
@@ -0,0 +1,4 @@
+@NonNullPackage
+package eu.mulk.mulkcms2.cms.pages;
+
+import pl.tlinkowski.annotation.basic.NonNullPackage;
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/users/User.java b/src/main/java/eu/mulk/mulkcms2/cms/users/User.java
index 929bc67..5ba5ff4 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/users/User.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/users/User.java
@@ -4,6 +4,7 @@
 import eu.mulk.mulkcms2.cms.pages.ArticleRevision;
 import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
 import java.util.Collection;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
@@ -23,15 +24,18 @@
   public Integer id;
 
   @Column(name = "name", nullable = true, length = -1)
+  @CheckForNull
   public String name;
 
   @Column(name = "status", nullable = false, length = -1)
   public String status;
 
   @Column(name = "email", nullable = true, length = -1)
+  @CheckForNull
   public String email;
 
   @Column(name = "website", nullable = true, length = -1)
+  @CheckForNull
   public String website;
 
   @OneToMany(mappedBy = "authors", fetch = FetchType.LAZY)
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/users/UserPermission.java b/src/main/java/eu/mulk/mulkcms2/cms/users/UserPermission.java
index 4962b68..76e3734 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/users/UserPermission.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/users/UserPermission.java
@@ -1,6 +1,7 @@
 package eu.mulk.mulkcms2.cms.users;
 
 import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
@@ -24,6 +25,7 @@
   public String permission;
 
   @Column(name = "status", nullable = true)
+  @CheckForNull
   public Boolean status;
 
   @ManyToOne(fetch = FetchType.LAZY)
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/users/UserSetting.java b/src/main/java/eu/mulk/mulkcms2/cms/users/UserSetting.java
index 56c6fca..43c61b2 100644
--- a/src/main/java/eu/mulk/mulkcms2/cms/users/UserSetting.java
+++ b/src/main/java/eu/mulk/mulkcms2/cms/users/UserSetting.java
@@ -1,6 +1,7 @@
 package eu.mulk.mulkcms2.cms.users;
 
 import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.annotation.CheckForNull;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
@@ -24,6 +25,7 @@
   public String setting;
 
   @Column(name = "value", nullable = true, length = -1)
+  @CheckForNull
   public String value;
 
   @ManyToOne(fetch = FetchType.LAZY)
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/users/package-info.java b/src/main/java/eu/mulk/mulkcms2/cms/users/package-info.java
new file mode 100644
index 0000000..d3d0e8d
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/users/package-info.java
@@ -0,0 +1,4 @@
+@NonNullPackage
+package eu.mulk.mulkcms2.cms.users;
+
+import pl.tlinkowski.annotation.basic.NonNullPackage;
diff --git a/src/main/java/eu/mulk/mulkcms2/common/markdown/package-info.java b/src/main/java/eu/mulk/mulkcms2/common/markdown/package-info.java
new file mode 100644
index 0000000..c120ba9
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/common/markdown/package-info.java
@@ -0,0 +1,4 @@
+@NonNullPackage
+package eu.mulk.mulkcms2.common.markdown;
+
+import pl.tlinkowski.annotation.basic.NonNullPackage;