<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.4">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2026-03-17T06:45:39+00:00</updated><id>/feed.xml</id><title type="html">smarterco.de</title><subtitle>Kamil Wozniak — Senior freelance software architect and engineer based in Hamburg, Germany. Available for Java, Spring Boot, and cloud architecture projects.</subtitle><author><name>Kamil Wozniak</name></author><entry><title type="html">Jekyll theme Minimal Mistakes with custom HTML</title><link href="/jekyll-customizing-minimal-mistakes-with-custom-html/" rel="alternate" type="text/html" title="Jekyll theme Minimal Mistakes with custom HTML" /><published>2023-12-21T10:00:00+00:00</published><updated>2023-12-21T10:00:00+00:00</updated><id>/jekyll-customizing-minimal-mistakes-with-custom-html</id><content type="html" xml:base="/jekyll-customizing-minimal-mistakes-with-custom-html/"><![CDATA[<h2 id="introduction">Introduction</h2>

<p>Jekyll is a tool that simplifies website creation. 
It converts text into websites without the need for complex components like databases. 
This efficiency makes Jekyll both fast and user-friendly. 
A popular theme for Jekyll websites is “Minimal Mistakes,” 
known for its appealing design and customizability. 
This article guides you through customizing templates from “Minimal Mistakes” using the Ruby gem theme.</p>

<h2 id="replacing-html-files-or-adding-code-to-existing-ones">Replacing HTML Files or Adding Code to Existing Ones</h2>

<p>Begin by referring to <a href="https://mmistakes.github.io/minimal-mistakes/docs/overriding-theme-defaults/" target="_blank">Minimal Mistakes - Overriding Theme Defaults</a> 
for foundational knowledge. Customizing the theme can be approached in two ways:</p>

<ul>
  <li>Replacing existing HTML files from the theme with your own.</li>
  <li>Adhering to a specific naming convention to layer your customizations atop the existing layouts and includes.</li>
</ul>

<h3 id="replacing-the-html-files-from-the-theme-with-your-own">Replacing the HTML Files from the Theme with Your Own</h3>

<p>To replace theme HTML files with personalized versions, 
create a <code class="language-plaintext highlighter-rouge">_includes</code> folder at your project’s root. 
Here, you can craft HTML files named identically to those in the theme. 
For instance, to customize the footer, generate <code class="language-plaintext highlighter-rouge">_includes/footer.html</code> and insert your unique HTML code.</p>

<p>A practical tip: start by copying the original HTML file from the theme into your project. This acts as a useful reference.</p>

<p class="notice--info">Unsure about file naming? Consult the <a href="https://github.com/mmistakes/minimal-mistakes">Minimal Mistakes repository</a> 
specifically the <code class="language-plaintext highlighter-rouge">_includes</code> folder, or use <code class="language-plaintext highlighter-rouge">gem fetch minimal-mistakes-jekyll</code> to download the gem and explore its <code class="language-plaintext highlighter-rouge">_includes</code> folder.</p>

<h3 id="following-a-specific-naming-convention-for-additional-customizations">Following a Specific Naming Convention for Additional Customizations</h3>

<p>In a project of mine, I wanted to augment the existing header with a few HTML lines without replacing the entire header. 
This goal was achievable by adhering to a specific naming convention. 
Similar to the previous method, create a <code class="language-plaintext highlighter-rouge">_includes</code> folder at your project’s root. 
Then, inside <code class="language-plaintext highlighter-rouge">_includes</code>, make a <code class="language-plaintext highlighter-rouge">head</code> directory. 
Within this, create <code class="language-plaintext highlighter-rouge">custom.html</code> and add your HTML enhancements. 
These additions will seamlessly integrate into the website’s existing header.</p>

<p>This method is equally applicable for footer customizations.</p>

<h3 id="example">Example</h3>

<p>Consider this example for organizing the <code class="language-plaintext highlighter-rouge">_includes</code> folder:</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>├── _includes
│   ├── footer.html
│   └── <span class="nb">head</span>
│       └── custom.html
</code></pre></div></div>

<h2 id="links">Links</h2>

<ul>
  <li><a href="https://jekyllrb.com/" target="_blank">Jekyll</a></li>
  <li><a href="https://mmistakes.github.io/minimal-mistakes/" target="_blank">Minimal Mistakes</a></li>
  <li><a href="https://mmistakes.github.io/minimal-mistakes/docs/overriding-theme-defaults/" target="_blank">Minimal Mistakes - Overriding Theme Defaults</a></li>
</ul>

<h2 id="appendix-structure-of-minimal-mistakes">Appendix: Structure of Minimal Mistakes</h2>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>├── minimal-mistakes-jekyll-4.24.0
│   ├── checksums.yaml.gz
│   ├── data
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── _data
│   │   │   ├── navigation.yml
│   │   │   └── ui-text.yml
│   │   ├── _includes
│   │   │   ├── analytics-providers
│   │   │   │   ├── custom.html
│   │   │   │   ├── google-gtag.html
│   │   │   │   ├── google-universal.html
│   │   │   │   └── google.html
│   │   │   ├── analytics.html
│   │   │   ├── archive-single.html
│   │   │   ├── author-profile-custom-links.html
│   │   │   ├── author-profile.html
│   │   │   ├── breadcrumbs.html
│   │   │   ├── browser-upgrade.html
│   │   │   ├── category-list.html
│   │   │   ├── comment.html
│   │   │   ├── comments-providers
│   │   │   │   ├── custom.html
│   │   │   │   ├── custom_scripts.html
│   │   │   │   ├── discourse.html
│   │   │   │   ├── disqus.html
│   │   │   │   ├── facebook.html
│   │   │   │   ├── giscus.html
│   │   │   │   ├── scripts.html
│   │   │   │   ├── staticman.html
│   │   │   │   ├── staticman_v2.html
│   │   │   │   └── utterances.html
│   │   │   ├── comments.html
│   │   │   ├── documents-collection.html
│   │   │   ├── feature_row
│   │   │   ├── figure
│   │   │   ├── footer
│   │   │   │   └── custom.html
│   │   │   ├── footer.html
│   │   │   ├── gallery
│   │   │   ├── group-by-array
│   │   │   ├── <span class="nb">head</span>
│   │   │   │   └── custom.html
│   │   │   ├── head.html
│   │   │   ├── masthead.html
│   │   │   ├── nav_list
│   │   │   ├── page__date.html
│   │   │   ├── page__hero.html
│   │   │   ├── page__hero_video.html
│   │   │   ├── page__meta.html
│   │   │   ├── page__taxonomy.html
│   │   │   ├── paginator.html
│   │   │   ├── post_pagination.html
│   │   │   ├── posts-category.html
│   │   │   ├── posts-tag.html
│   │   │   ├── scripts.html
│   │   │   ├── search
│   │   │   │   ├── algolia-search-scripts.html
│   │   │   │   ├── google-search-scripts.html
│   │   │   │   ├── lunr-search-scripts.html
│   │   │   │   └── search_form.html
│   │   │   ├── seo.html
│   │   │   ├── sidebar.html
│   │   │   ├── skip-links.html
│   │   │   ├── social-share.html
│   │   │   ├── tag-list.html
│   │   │   ├── toc
│   │   │   ├── toc.html
│   │   │   └── video
│   │   ├── _layouts
│   │   │   ├── archive-taxonomy.html
│   │   │   ├── archive.html
│   │   │   ├── categories.html
│   │   │   ├── category.html
│   │   │   ├── collection.html
│   │   │   ├── compress.html
│   │   │   ├── default.html
│   │   │   ├── home.html
│   │   │   ├── posts.html
│   │   │   ├── search.html
│   │   │   ├── single.html
│   │   │   ├── splash.html
│   │   │   ├── tag.html
│   │   │   └── tags.html
│   │   ├── _sass
│   │   │   ├── minimal-mistakes
│   │   │   │   ├── _animations.scss
│   │   │   │   ├── _archive.scss
│   │   │   │   ├── _base.scss
│   │   │   │   ├── _buttons.scss
│   │   │   │   ├── _footer.scss
│   │   │   │   ├── _forms.scss
│   │   │   │   ├── _masthead.scss
│   │   │   │   ├── _mixins.scss
│   │   │   │   ├── _navigation.scss
│   │   │   │   ├── _notices.scss
│   │   │   │   ├── _page.scss
│   │   │   │   ├── _print.scss
│   │   │   │   ├── _reset.scss
│   │   │   │   ├── _search.scss
│   │   │   │   ├── _sidebar.scss
│   │   │   │   ├── _syntax.scss
│   │   │   │   ├── _tables.scss
│   │   │   │   ├── _utilities.scss
│   │   │   │   ├── _variables.scss
│   │   │   │   ├── skins
│   │   │   │   │   ├── _air.scss
│   │   │   │   │   ├── _aqua.scss
│   │   │   │   │   ├── _contrast.scss
│   │   │   │   │   ├── _dark.scss
│   │   │   │   │   ├── _default.scss
│   │   │   │   │   ├── _dirt.scss
│   │   │   │   │   ├── _mint.scss
│   │   │   │   │   ├── _neon.scss
│   │   │   │   │   ├── _plum.scss
│   │   │   │   │   └── _sunrise.scss
│   │   │   │   └── vendor
│   │   │   │       ├── breakpoint
│   │   │   │       │   ├── _breakpoint.scss
│   │   │   │       │   ├── _context.scss
│   │   │   │       │   ├── _helpers.scss
│   │   │   │       │   ├── _legacy-settings.scss
│   │   │   │       │   ├── _no-query.scss
│   │   │   │       │   ├── _parsers.scss
│   │   │   │       │   ├── _respond-to.scss
│   │   │   │       │   ├── _settings.scss
│   │   │   │       │   └── parsers
│   │   │   │       │       ├── _double.scss
│   │   │   │       │       ├── _query.scss
│   │   │   │       │       ├── _resolution.scss
│   │   │   │       │       ├── _single.scss
│   │   │   │       │       ├── _triple.scss
│   │   │   │       │       ├── double
│   │   │   │       │       │   ├── _default-pair.scss
│   │   │   │       │       │   ├── _default.scss
│   │   │   │       │       │   └── _double-string.scss
│   │   │   │       │       ├── resolution
│   │   │   │       │       │   └── _resolution.scss
│   │   │   │       │       ├── single
│   │   │   │       │       │   └── _default.scss
│   │   │   │       │       └── triple
│   │   │   │       │           └── _default.scss
│   │   │   │       ├── magnific-popup
│   │   │   │       │   ├── _magnific-popup.scss
│   │   │   │       │   └── _settings.scss
│   │   │   │       └── susy
│   │   │   │           ├── _su.scss
│   │   │   │           ├── _susy-prefix.scss
│   │   │   │           ├── _susy.scss
│   │   │   │           ├── plugins
│   │   │   │           │   ├── _svg-grid.scss
│   │   │   │           │   └── svg-grid
│   │   │   │           │       ├── _prefix.scss
│   │   │   │           │       ├── _svg-api.scss
│   │   │   │           │       ├── _svg-grid-math.scss
│   │   │   │           │       ├── _svg-settings.scss
│   │   │   │           │       ├── _svg-unprefix.scss
│   │   │   │           │       └── _svg-utilities.scss
│   │   │   │           └── susy
│   │   │   │               ├── _api.scss
│   │   │   │               ├── _normalize.scss
│   │   │   │               ├── _parse.scss
│   │   │   │               ├── _settings.scss
│   │   │   │               ├── _su-math.scss
│   │   │   │               ├── _su-validate.scss
│   │   │   │               ├── _syntax-helpers.scss
│   │   │   │               ├── _unprefix.scss
│   │   │   │               └── _utilities.scss
│   │   │   └── minimal-mistakes.scss
│   │   └── assets
│   │       ├── css
│   │       │   └── main.scss
│   │       └── js
│   │           ├── _main.js
│   │           ├── lunr
│   │           │   ├── lunr-en.js
│   │           │   ├── lunr-gr.js
│   │           │   ├── lunr-store.js
│   │           │   ├── lunr.js
│   │           │   └── lunr.min.js
│   │           ├── main.min.js
│   │           ├── plugins
│   │           │   ├── gumshoe.js
│   │           │   ├── jquery.ba-throttle-debounce.js
│   │           │   ├── jquery.fitvids.js
│   │           │   ├── jquery.greedy-navigation.js
│   │           │   ├── jquery.magnific-popup.js
│   │           │   └── smooth-scroll.js
│   │           └── vendor
│   │               └── jquery
│   │                   └── jquery-3.5.1.js
│   ├── data.tar.gz
│   └── metadata.gz

</code></pre></div></div>]]></content><author><name>Kamil Wozniak</name></author><category term="jekyll" /><category term="minimal-mistakes" /><category term="html" /><summary type="html"><![CDATA[Overview on how to customize the Jekyll theme Minimal Mistakes with custom HTML, for example a new footer or header]]></summary></entry><entry><title type="html">Sign git commits with ssh and auto-sign with Intellij</title><link href="/sign-git-commits-with-ssh-and-autosign-with-intellij/" rel="alternate" type="text/html" title="Sign git commits with ssh and auto-sign with Intellij" /><published>2023-05-29T10:12:00+00:00</published><updated>2023-05-29T10:12:00+00:00</updated><id>/sign-git-commits-with-ssh-and-autosign-with-intellij</id><content type="html" xml:base="/sign-git-commits-with-ssh-and-autosign-with-intellij/"><![CDATA[<h2 id="introduction">Introduction</h2>

<p>Signing your GitHub commits adds an extra layer of authenticity and integrity to your codebase. 
In this article, we’ll explore how to sign your commits using your existing SSH key, without the need to create a separate GPG key. 
However, please note that SSH signature verification requires Git 2.34 or later.</p>

<h2 id="add-your-key-to-your-github-account">Add your key to your GitHub account</h2>

<p>If you haven’t already done so, follow the steps below to add your public key to your <a href="https://github.com/settings/keys" target="_blank">GitHub account</a> for authentication and signing purposes:
Refer to the GitHub documentation on <a href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account" target="_blank">Adding a new SSH key to your GitHub account</a> 
and follow the instructions provided.</p>

<h2 id="configure-your-system-with-your-ssh-key-as-signing-key">Configure your system with your ssh key as signing key</h2>

<p>GitHub also took care of this in the following documentation page <a href="https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key#telling-git-about-your-ssh-key" target="_blank">Telling Git about your SSH key</a>.</p>

<p>To configure Git to use your SSH key as the signing key, perform the following steps:</p>

<ol>
  <li>Open the Terminal.</li>
  <li>Set the <code class="language-plaintext highlighter-rouge">gpg.format</code> configuration to “ssh” by executing the following command:
    <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config <span class="nt">--global</span> gpg.format ssh
</code></pre></div>    </div>
  </li>
  <li>Substitute the path to your key with the appropriate value. For example, if your SSH key is located in the <code class="language-plaintext highlighter-rouge">$HOME/.ssh/</code> directory, run the following command:
    <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config <span class="nt">--global</span> user.signingkey /PATH/TO/.SSH/KEY.PUB
</code></pre></div>    </div>
  </li>
</ol>

<p><strong>Note</strong>: You can also use the <code class="language-plaintext highlighter-rouge">--local</code> flag instead of <code class="language-plaintext highlighter-rouge">--global</code> to add the configuration only to a specific repository.</p>

<h5 id="my-example">My Example</h5>

<p>Here’s an example of configuring your system with an SSH key as the signing key:</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config <span class="nt">--global</span> gpg.format ssh
git config <span class="nt">--global</span> user.signingkey /Users/a418/.ssh/id_rsa.pub
</code></pre></div></div>

<h2 id="signing-git-commits-manually">Signing git commits (manually)</h2>

<p>By following the previous steps, your system is now capable of signing commits. 
However, the signing process won’t happen automatically—you need to sign each commit explicitly while creating the commit message. 
Use the <code class="language-plaintext highlighter-rouge">-S</code> flag as shown in the example below:</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git commit <span class="nt">-S</span> <span class="nt">-m</span> <span class="s2">"feat: Implemented new version of bad SKYNET"</span>
</code></pre></div></div>

<h2 id="signing-all-git-commits-automatically">Signing all git commits (automatically)</h2>

<p>To configure Git to sign all your commits automatically, eliminating the need for the <code class="language-plaintext highlighter-rouge">-S</code> flag each time, 
modify the <code class="language-plaintext highlighter-rouge">$HOME/.gitconfig</code> file on your system as follows:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[user]
    signingKey = /Users/a418/.ssh/id_rsa.pub
[gpg]
    format = ssh
[commit]
    gpgsign = true
</code></pre></div></div>

<p>The crucial part is the <code class="language-plaintext highlighter-rouge">[commit]</code> section, where the <code class="language-plaintext highlighter-rouge">gpgsign</code> property is set to <code class="language-plaintext highlighter-rouge">true</code>.</p>

<h2 id="configure-git-commit-signing-in-intellij-idea">Configure git commit signing in Intellij IDEA</h2>

<p><strong>Note</strong>: This reflects only the current state as of IntelliJ IDEA 2023.1.2 or earlier.</p>

<p>As of the current IntelliJ IDEA version, there is no built-in UI for configuring commit signing with <code class="language-plaintext highlighter-rouge">ssh</code>. 
Therefore, to set up the signing key, either configure it per project or follow the global configuration steps mentioned earlier. 
IntelliJ IDEA automatically detects the <code class="language-plaintext highlighter-rouge">gitconfig</code> settings when committing.</p>

<h3 id="sources">Sources</h3>
<ul>
  <li><a href="https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key">GitHub Docs</a></li>
  <li><a href="https://youtrack.jetbrains.com/issue/IDEA-296588/Git-SSH-signing">Jetbrains Youtrack Issue</a></li>
</ul>]]></content><author><name>Kamil Wozniak</name></author><category term="git" /><category term="cli" /><category term="github" /><category term="intellij" /><summary type="html"><![CDATA[Overview on how to configure your git to sign commits with ssh on cli and with Intellij]]></summary></entry><entry><title type="html">Download the latest version of a software from Github</title><link href="/download-latest-version-from-github-with-curl/" rel="alternate" type="text/html" title="Download the latest version of a software from Github" /><published>2019-07-14T10:10:00+00:00</published><updated>2019-07-14T10:10:00+00:00</updated><id>/download-latest-version-from-github-with-curl</id><content type="html" xml:base="/download-latest-version-from-github-with-curl/"><![CDATA[<h3 id="introduction">Introduction</h3>

<p>We needed to download a software from <code class="language-plaintext highlighter-rouge">Github</code> in its latest release without specifying the version number. This had to be done with <code class="language-plaintext highlighter-rouge">curl</code>, so we came up with the following code.</p>

<h3 id="solution">Solution</h3>

<p>First we have to retrieve all the data about the latest release, which can be easily done by the use of the GitHub API. The URL follows the same scheme:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://api.github.com/repos/USERNAME/REPO/releases/latest
</code></pre></div></div>

<p>In our case:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://api.github.com/repos/felixb/swamp/releases/latest
</code></pre></div></div>

<p>The result is a JSON file with the description of the release and download links for specific files:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.github.com/repos/felixb/swamp/releases/assets/11040706"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">11040706</span><span class="p">,</span><span class="w">
  </span><span class="nl">"node_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"MDEyOlJlbGVhc2VBc3NldDExMDQwNzA2"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"swamp_amd64"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"label"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
  </span><span class="nl">"uploader"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"login"</span><span class="p">:</span><span class="w"> </span><span class="s2">"felixb"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">192135</span><span class="p">,</span><span class="w">
    </span><span class="nl">"node_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"MDQ6VXNlcjE5MjEzNQ=="</span><span class="p">,</span><span class="w">
    </span><span class="nl">"avatar_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://avatars1.githubusercontent.com/u/192135?v=4"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"gravatar_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
    </span><span class="nl">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.github.com/users/felixb"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"html_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://github.com/felixb"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"followers_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.github.com/users/felixb/followers"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"following_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.github.com/users/felixb/following{/other_user}"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"gists_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.github.com/users/felixb/gists{/gist_id}"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"starred_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.github.com/users/felixb/starred{/owner}{/repo}"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"subscriptions_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.github.com/users/felixb/subscriptions"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"organizations_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.github.com/users/felixb/orgs"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"repos_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.github.com/users/felixb/repos"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"events_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.github.com/users/felixb/events{/privacy}"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"received_events_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.github.com/users/felixb/received_events"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"User"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"site_admin"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"content_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"application/octet-stream"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"state"</span><span class="p">:</span><span class="w"> </span><span class="s2">"uploaded"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"size"</span><span class="p">:</span><span class="w"> </span><span class="mi">11765256</span><span class="p">,</span><span class="w">
  </span><span class="nl">"download_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">916</span><span class="p">,</span><span class="w">
  </span><span class="nl">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2019-02-12T06:39:41Z"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"updated_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2019-02-12T06:39:49Z"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"browser_download_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://github.com/felixb/swamp/releases/download/v0.10.0/swamp_amd64"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>Now we can write our curl command to retrieve the download URL for the Linux version.</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">DOWNLOAD_URL</span><span class="o">=</span><span class="si">$(</span>curl <span class="nt">-s</span> https://api.github.com/repos/felixb/swamp/releases/latest <span class="se">\</span>
        | <span class="nb">grep </span>browser_download_url <span class="se">\</span>
        | <span class="nb">grep </span>swamp_amd64 <span class="se">\</span>
        | <span class="nb">cut</span> <span class="nt">-d</span> <span class="s1">'"'</span> <span class="nt">-f</span> 4<span class="si">)</span>
curl <span class="nt">-s</span> <span class="nt">-L</span> <span class="nt">--create-dirs</span> <span class="nt">-o</span> ~/downloadDir <span class="s2">"</span><span class="nv">$DOWNLOAD_URL</span><span class="s2">"</span>
</code></pre></div></div>

<p>Note: Replace the repository URL and <code class="language-plaintext highlighter-rouge">grep swamp_amd64</code> with the file you need (<code class="language-plaintext highlighter-rouge">grep YOUR_FILE</code>).</p>]]></content><author><name>Kamil Wozniak</name></author><category term="curl" /><category term="Linux" /><category term="Github" /><category term="Latest Release" /><summary type="html"><![CDATA[Use curl to download the latest release of a software from Github]]></summary></entry><entry><title type="html">Postgres: role “postgres” does not exist</title><link href="/psql-role-does-not-exist/" rel="alternate" type="text/html" title="Postgres: role “postgres” does not exist" /><published>2019-07-11T19:04:00+00:00</published><updated>2019-07-11T19:04:00+00:00</updated><id>/psql-role-does-not-exist</id><content type="html" xml:base="/psql-role-does-not-exist/"><![CDATA[<h3 id="introduction">Introduction</h3>
<p>When using <a href="https://postgresapp.com/">Postgres.app</a> on MacOS it is quite possible that you will encounter the folling exception:</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>FATAL: role “postgres” does not exist
</code></pre></div></div>
<p>As it states you are trying to connect to Postgres with a role unknown to the database. The easies solution for this is to create one.
You can achieve this by running the following command:</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>╭─me@myMachine /Applications/Postgres.app/Contents/Versions/YOUR_VERSION/bin  
╰─<span class="nv">$ </span>./createuser <span class="nt">-s</span> missingRoleName
</code></pre></div></div>

<p>With the <code class="language-plaintext highlighter-rouge">-s</code> flag you are creating a superuser.</p>

<h3 id="have-you-changed-your-macos-username">Have you changed your MacOS username?</h3>

<p>A little background for <a href="https://postgresapp.com/">Postgres.app</a>: When you start the app the first time, it will create a <code class="language-plaintext highlighter-rouge">superuser</code> with the current <strong>MacOS</strong> username in your application.</p>

<p>In my case I migrated my system to a new MacBook and changed my MacOS username.</p>

<p>If you know your old <code class="language-plaintext highlighter-rouge">superuser</code> role name, create a new superuser corresponding to your current MacOS username:</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>╭─me@myMachine /Applications/Postgres.app/Contents/Versions/YOUR_VERSION/bin  
╰─<span class="nv">$ </span>./createuser <span class="nt">-s</span> missingRoleName <span class="nt">--username</span><span class="o">=</span>OldSuperUserRoleName
</code></pre></div></div>]]></content><author><name>Kamil Wozniak</name></author><category term="Java" /><category term="Spring" /><category term="Spring Boot" /><category term="Database" /><category term="Postgres" /><category term="PostgreSQL" /><summary type="html"><![CDATA[Fix FATAL: role “postgres” does not exist with Postgres.app on MacOs]]></summary></entry><entry><title type="html">Fix the GradleWorkerMain OutOfMemoryException</title><link href="/fix-the-gradleworkermain-outofmemoryexception/" rel="alternate" type="text/html" title="Fix the GradleWorkerMain OutOfMemoryException" /><published>2018-01-04T14:34:00+00:00</published><updated>2018-01-04T14:34:00+00:00</updated><id>/fix-the-gradleworkermain-outofmemoryexception</id><content type="html" xml:base="/fix-the-gradleworkermain-outofmemoryexception/"><![CDATA[<h3 id="introduction">Introduction</h3>
<p>In one of my clients projects we were working with <a href="https://gradle.org/">Gradle</a> and building the application on the console with <code class="language-plaintext highlighter-rouge">gradlew clean build</code>.</p>

<p>On each build <a href="https://gradle.org/">Gradle</a> runs all tests and while the application was growing, the amount of tests also increased accordingly.
The application has a few thousand tests and at some point we were receiving <code class="language-plaintext highlighter-rouge">OutOfMemoryException</code>s with increasing frequency.</p>

<h3 id="the-solutions">The solutions</h3>
<p>After some analyzing we pined down the cause to the - you guessed it - execution of the tests and their low memory.</p>

<p>There are two solutions, which you can use to solve this problem. Booth of them have to be inserted into the <code class="language-plaintext highlighter-rouge">test{}</code>-block.</p>

<h4 id="setting-the-jvmargs">Setting the jvmArgs</h4>
<div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">test</span> <span class="o">{</span>
  <span class="n">jvmArgs</span> <span class="o">=</span> <span class="o">[</span><span class="s1">'-Xmx2048m'</span><span class="o">]</span>  
<span class="o">}</span>
</code></pre></div></div>

<h4 id="setting-the-heapsize-directly">Setting the heapSize directly</h4>
<p>Gradle offers you the possibility to set the heapSize directly by the use of the keyword <a href="https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html#org.gradle.api.tasks.testing.Test:maxHeapSize">maxHeapSize</a>.</p>
<div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">test</span> <span class="o">{</span>
  <span class="n">maxHeapSize</span> <span class="o">=</span> <span class="s2">"2048m"</span>
<span class="o">}</span>
</code></pre></div></div>]]></content><author><name>Kamil Wozniak</name></author><category term="Java" /><category term="Spring" /><category term="Spring Boot" /><category term="Tomcat" /><category term="Gradle" /><category term="OutOfMemoryException" /><category term="Tests" /><summary type="html"><![CDATA[Setting the memory size in Gradle to prevent *OutOfMemoryException*s]]></summary></entry><entry><title type="html">AWS Elastic Beanstalk Environment Properties not passed for Tomcat</title><link href="/aws-elastic-beanstalk-environment-properties-not-set/" rel="alternate" type="text/html" title="AWS Elastic Beanstalk Environment Properties not passed for Tomcat" /><published>2017-11-19T16:14:00+00:00</published><updated>2017-11-19T16:14:00+00:00</updated><id>/aws-elastic-beanstalk-environment-properties-not-set</id><content type="html" xml:base="/aws-elastic-beanstalk-environment-properties-not-set/"><![CDATA[<h3 id="introduction">Introduction</h3>

<p>Lately I was working on a Micro-service based on <code class="language-plaintext highlighter-rouge">Spring Boot</code>. I deployed the Micro-service onto <code class="language-plaintext highlighter-rouge">AWS Elastic Beanstalk</code>, like I’ve done it a few hundred times with other apps, but this time the Micro-service was unable to start. Tomcat was giving me the cold shoulder with <code class="language-plaintext highlighter-rouge">404</code>s.
A look into the logs showed me, that the <code class="language-plaintext highlighter-rouge">JDBC_CONNECTION_STRING</code> was not set in the environment, even if it was set in the <code class="language-plaintext highlighter-rouge">Environment Properties</code> on the configuration page in <code class="language-plaintext highlighter-rouge">AWS Elastic Beanstalk</code>.</p>

<h3 id="the-problem">The Problem</h3>

<p>Analyzing the problem by comparing the version (<code class="language-plaintext highlighter-rouge">64bit Amazon Linux 2017.09 v2.7.0 running Tomcat 8 Java 8</code>) - on which the new app was running - against other instances (<code class="language-plaintext highlighter-rouge">64bit Amazon Linux 2015.03 v2.0.1 running Tomcat 8 Java 8</code>), revealed that the environment settings are handled differently:</p>

<ul>
  <li>The older version was handling them as you would expect it. The settings were set as <code class="language-plaintext highlighter-rouge">environment variables</code> and were visible for the app.</li>
  <li>The newer version was <strong>NOT</strong> using <code class="language-plaintext highlighter-rouge">environment variables</code>, but was setting all custom properties as <code class="language-plaintext highlighter-rouge">System Properties</code>. Tomcat received them as <code class="language-plaintext highlighter-rouge">-DJDBC_CONNECTION_STRING=something</code>.</li>
</ul>

<p>This changes the way on how to retrieve the properties from the server/Tomcat.</p>

<h3 id="the-solution">The solution</h3>

<p>The solution - at least for this <code class="language-plaintext highlighter-rouge">Spring Boot</code> Micro-service - was to add <code class="language-plaintext highlighter-rouge">spring.datasource.url</code> directly into the <code class="language-plaintext highlighter-rouge">Environment Properties</code> on the configuration page in <code class="language-plaintext highlighter-rouge">AWS Elastic Beanstalk</code>. The title of the settings is misleading at least and judging it by its name and by the many years of use you would not expect this behavior.</p>

<h3 id="addition">Addition</h3>

<p>After realizing what was happening I searched the <a href="http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environments-cfg-softwaresettings.html">docs for some clues</a>.
Here is an excerpt:</p>

<blockquote>

  <p>You can use environment properties to pass secrets, endpoints, debug settings, and other information to your application. Environment properties help you run your application in multiple environments for different purposes, such as development, testing, staging, and production.</p>

  <p><strong>Environment Variables</strong></p>

  <p>In most cases, environment properties are passed to your application as environment variables, but the behavior is platform dependent. For example, the Java SE platform sets environment variables that you retrieve with System.getenv, while the Tomcat platform sets Java system properties that you retrieve with System.getProperty.</p>
</blockquote>]]></content><author><name>Kamil Wozniak</name></author><category term="Java" /><category term="Spring" /><category term="Spring Boot" /><category term="Tomcat" /><category term="AWS" /><category term="Amazon Web Services" /><category term="Elastic Beanstalk" /><summary type="html"><![CDATA[Deploying apps to *Elastic Beanstalk* can bring surprises when using newer Tomcat versions]]></summary></entry><entry><title type="html">Set the Username and Email in git globally or per project</title><link href="/set-the-username-and-email-in-git-globally-and-per-project/" rel="alternate" type="text/html" title="Set the Username and Email in git globally or per project" /><published>2017-11-12T10:12:00+00:00</published><updated>2017-11-12T10:12:00+00:00</updated><id>/set-the-username-and-email-in-git-globally-and-per-project</id><content type="html" xml:base="/set-the-username-and-email-in-git-globally-and-per-project/"><![CDATA[<h3 id="introduction">Introduction</h3>

<p>Git offers three possibilities on how you can set your <code class="language-plaintext highlighter-rouge">username</code> and <code class="language-plaintext highlighter-rouge">email</code>.
The settings will be considered in the following order, where 1. will always override 2. and 2. will override 3..</p>

<ol>
  <li><code class="language-plaintext highlighter-rouge">project</code> - The data is stored directly in the corresponding project(repository) under <code class="language-plaintext highlighter-rouge">.git/config</code>.</li>
  <li><code class="language-plaintext highlighter-rouge">global</code> - for all repositories of the current user. The config file can be found in your home directory <code class="language-plaintext highlighter-rouge">~/.gitconfig</code>.</li>
  <li><code class="language-plaintext highlighter-rouge">system</code> - This is a system wide configuration and is available for all users and all repositories. You will find it in <code class="language-plaintext highlighter-rouge">/etc/gitconfig</code>.</li>
</ol>

<p>In the most cases you will setup a global config for your user and additionally - if you work for example for different companies - you will also setup project specific configurations.</p>

<h3 id="set-the-usernameemail-for-a-specific-repository">Set the username/email for a specific repository</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config user.name <span class="s2">"Your project specific name"</span>
git config user.email <span class="s2">"your@project-specific-email.com"</span>
</code></pre></div></div>
<p>Verify your settings:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config <span class="nt">--get</span> user.name
git config <span class="nt">--get</span> user.email
</code></pre></div></div>

<h3 id="set-the-usernameemail-globally">Set the username/email globally</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config <span class="nt">--global</span> user.name <span class="s2">"Your global username"</span>
git config <span class="nt">--global</span> user.email <span class="s2">"your@email.com"</span>
</code></pre></div></div>
<p>Verify your settings:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config <span class="nt">--global</span> <span class="nt">--get</span> user.name
git config <span class="nt">--global</span> <span class="nt">--get</span> user.email
</code></pre></div></div>

<h3 id="set-the-usernameemail-system-wide">Set the username/email system wide</h3>

<p>This is a case which is usually not needed, but we will list it in any case.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config <span class="nt">--system</span> user.name <span class="s2">"Your default name"</span>
git config <span class="nt">--system</span> user.email <span class="s2">"your@system-email.com"</span>
</code></pre></div></div>

<p>Verify your settings:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config <span class="nt">--system</span> <span class="nt">--get</span> user.name
git config <span class="nt">--system</span> <span class="nt">--get</span> user.email
</code></pre></div></div>]]></content><author><name>Kamil Wozniak</name></author><category term="git" /><category term="cli" /><summary type="html"><![CDATA[Overview on how to configure your git username and your email for different use cases.]]></summary></entry><entry><title type="html">Architecture documentation problems</title><link href="/architecture-documentation-problems/" rel="alternate" type="text/html" title="Architecture documentation problems" /><published>2017-09-26T12:41:00+00:00</published><updated>2017-09-26T12:41:00+00:00</updated><id>/architecture-documentation-problems</id><content type="html" xml:base="/architecture-documentation-problems/"><![CDATA[<p class="notice--info"><strong>Note:</strong> This is only a small reminder for myself and not a full article. You can write books about this topic.</p>

<h3 id="introduction">Introduction</h3>

<p>Architecture changes over time and sometimes it is not easy to keep the documentation up-to-date. As a result you get an invalid description of your architecture.</p>

<h3 id="the-problems">The Problems</h3>
<ul>
  <li>Architecture is not created by only one person, but - over time - by multiple persons.</li>
  <li>Often architecture is documented far away from the source code or repository in Word documents or wikis like <a href="https://www.atlassian.com/software/confluence">Confluence</a></li>
  <li>Changes are therefore not documented and later on nobody knows what information is still valid and which information was not updated.</li>
  <li>Usage of binary file formats like <em>docx</em> (Word) for example are bad to version: you don’t see the detailed changes. What you get instead is the whole document as a new binary file.</li>
</ul>

<h3 id="the-solution">The solution</h3>
<ul>
  <li>The best practice would be to document changes in the same repository like your code.</li>
  <li>Use text based files, like markdown, which can be used to generate the documentation.</li>
  <li>The generation of the documentation can be integrated into the build process. (<a href="https://gradle.org/">Gradle</a>/<a href="https://maven.apache.org/">Maven</a>)</li>
  <li>You get a changelog for free: A big plus is that they are text files, which allow you to see all changes in detail instead of a change of the whole file like it is the case with binary files(<em>docx</em>).</li>
  <li>Use templates like <a href="http://arc42.org/">arc42</a> and fill them with your data.</li>
  <li>For UML you can use <a href="http://plantuml.com/">PlantUML</a>, which allows you to describe you UML diagrams as text.</li>
</ul>

<h3 id="tools">Tools</h3>
<ul>
  <li><a href="https://en.wikipedia.org/wiki/Markdown">Markdown</a> as text based markup language</li>
  <li><a href="http://plantuml.com/">PlantUML</a>: UML generation from text files.</li>
  <li><a href="http://arc42.org/">arc42</a>, you will find different templates under <em>Download</em></li>
</ul>]]></content><author><name>Kamil Wozniak</name></author><category term="Architecture" /><category term="Documentation" /><category term="Markdown" /><category term="Maven" /><category term="Gradle" /><category term="PlantUML" /><summary type="html"><![CDATA[Architecture changes over time and it is not easy to keep the documentation up-to-date. As a result you get an invalid description of your architecture.]]></summary></entry><entry><title type="html">Spring Data JPA: Query result directly into DTO</title><link href="/spring-data-jpa-query-result-to-dto/" rel="alternate" type="text/html" title="Spring Data JPA: Query result directly into DTO" /><published>2017-07-20T00:00:00+00:00</published><updated>2017-07-20T00:00:00+00:00</updated><id>/spring-data-jpa-query-result-to-dto</id><content type="html" xml:base="/spring-data-jpa-query-result-to-dto/"><![CDATA[<h3 id="introduction">Introduction</h3>

<p>One of the hidden gems of Spring Data JPA is the possibility to put your query results directly into a DTO instead of having it transformed by a mapper on a higher level. Of course this depends on the question if you are okay with this way of handling data.</p>

<h3 id="what-is-spring-data">What is Spring data?</h3>

<p>Spring Data itself is an abstraction layer between the way of how you query data and the underlying different data source types. The way how you use Spring Data to write your queries does not change. It will transform the queries into the corresponding underlying query languages for JPA, MongoDB, Couchbase, Neo4j a.s.o..</p>

<p>The special about Spring Data is that it is sufficient to just create interface methods. There is no need of implementing any Repositories or DataAccessObjects.</p>

<h3 id="example-of-a-basic-interface-method-in-spring-data-jpa">Example of a basic interface method in Spring Data JPA</h3>

<p>This is just an example for a <code class="language-plaintext highlighter-rouge">JpaRepository</code> showing how Spring Data is working:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">de.smarterco.example.repositories</span><span class="o">;</span>

<span class="kn">import</span> <span class="nn">de.smarterco.example.entities.User</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.data.jpa.repository.JpaRepository</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.stereotype.Repository</span><span class="o">;</span>

<span class="kn">import</span> <span class="nn">java.util.List</span><span class="o">;</span>

<span class="nd">@Repository</span>
<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">UserRepository</span> <span class="kd">extends</span> <span class="nc">JpaRepository</span><span class="o">&lt;</span><span class="nc">User</span><span class="o">,</span> <span class="nc">Long</span><span class="o">&gt;</span> <span class="o">{</span>

    <span class="nc">List</span><span class="o">&lt;</span><span class="nc">User</span><span class="o">&gt;</span> <span class="nf">findAll</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>

<p>The keywords:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">@Repository</code> - Marks the class as a repository to get picked up by the dependency framework.</li>
  <li><code class="language-plaintext highlighter-rouge">JpaRepository</code> - Extends our interface <code class="language-plaintext highlighter-rouge">UserRepository</code> by base functionality for the use with <code class="language-plaintext highlighter-rouge">JPA</code> datasources.</li>
  <li><code class="language-plaintext highlighter-rouge">&lt;User, Long&gt;</code> - <code class="language-plaintext highlighter-rouge">User</code> is our entity on which this repository will perform its queries. The <code class="language-plaintext highlighter-rouge">Long</code> is the type of the id in the <code class="language-plaintext highlighter-rouge">User</code> entity.</li>
  <li><code class="language-plaintext highlighter-rouge">List&lt;User&gt; findAll()</code> - Example of a method, which will retrieve all Users from the repository and store them into a <code class="language-plaintext highlighter-rouge">List</code>. Query methods in Spring Data start with the keyword <code class="language-plaintext highlighter-rouge">find</code>, followed by restrictions and parameters.</li>
</ul>

<h3 id="using-the-query-annotation">Using the @Query annotation</h3>

<p>There is also another way of how you can achieve the same result using Spring Data JPA.
Spring Data JPA offers you the keyword <code class="language-plaintext highlighter-rouge">Query</code>, which allows you to write your own queries with JPQL - <a href="http://www.objectdb.com/java/jpa/query/jpql/expression"><code class="language-plaintext highlighter-rouge">Java Persistence Query Language</code></a>.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">de.smarterco.example.repositories</span><span class="o">;</span>

<span class="kn">import</span> <span class="nn">de.smarterco.example.entities.User</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.data.jpa.repository.JpaRepository</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.data.jpa.repository.Query</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.stereotype.Repository</span><span class="o">;</span>

<span class="kn">import</span> <span class="nn">java.util.List</span><span class="o">;</span>

<span class="nd">@Repository</span>
<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">UserRepository</span> <span class="kd">extends</span> <span class="nc">JpaRepository</span><span class="o">&lt;</span><span class="nc">User</span><span class="o">,</span> <span class="nc">Long</span><span class="o">&gt;</span> <span class="o">{</span>

    <span class="nd">@Query</span><span class="o">(</span><span class="s">"SELECT u FROM User AS u"</span><span class="o">)</span>
    <span class="nc">List</span><span class="o">&lt;</span><span class="nc">User</span><span class="o">&gt;</span> <span class="nf">findAll</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="querying-results-directly-to-a-dto">Querying results directly to a DTO</h3>

<p>This paragraph describes how to put results from a query directly into a DTO without mapping the data on a second layer outside of the <code class="language-plaintext highlighter-rouge">Repository</code>.</p>

<p>The first thing you will need is a DTO, like in our case our <code class="language-plaintext highlighter-rouge">UserNameDTO</code>.</p>

<p class="notice--info">Please note that you will need a constructor accepting all internal variables as parameters.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">de.smarterco.example.dto</span><span class="o">;</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserNameDTO</span> <span class="o">{</span>

    <span class="kd">private</span> <span class="nc">Long</span> <span class="n">id</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">name</span><span class="o">;</span>

    <span class="kd">public</span> <span class="nf">UserNameDTO</span><span class="o">(</span><span class="nc">Long</span> <span class="n">id</span><span class="o">,</span> <span class="nc">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">id</span> <span class="o">=</span> <span class="n">id</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="nc">Long</span> <span class="nf">getId</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">id</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="nc">String</span> <span class="nf">getName</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">name</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Storing the data directly into the DTO (explanation below) is done by writing a JPQL query in the <code class="language-plaintext highlighter-rouge">JpaRepository</code>:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">de.smarterco.example.repositories</span><span class="o">;</span>

<span class="kn">import</span> <span class="nn">de.smarterco.example.dto.UserNameDTO</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">de.smarterco.example.entities.User</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.data.jpa.repository.JpaRepository</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.data.jpa.repository.Query</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.data.repository.query.Param</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.stereotype.Repository</span><span class="o">;</span>

<span class="kn">import</span> <span class="nn">java.util.List</span><span class="o">;</span>

<span class="nd">@Repository</span>
<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">UserRepository</span> <span class="kd">extends</span> <span class="nc">JpaRepository</span><span class="o">&lt;</span><span class="nc">User</span><span class="o">,</span> <span class="nc">Long</span><span class="o">&gt;</span> <span class="o">{</span>

    <span class="nd">@Query</span><span class="o">(</span><span class="s">"SELECT u FROM User AS u"</span><span class="o">)</span>
    <span class="nc">List</span><span class="o">&lt;</span><span class="nc">User</span><span class="o">&gt;</span> <span class="nf">findAll</span><span class="o">();</span>

    <span class="nd">@Query</span><span class="o">(</span><span class="s">"SELECT new de.smarterco.example.dto.UserNameDTO(u.id, u.name) FROM User u WHERE u.name = :name"</span><span class="o">)</span>
    <span class="nc">List</span><span class="o">&lt;</span><span class="nc">UserNameDTO</span><span class="o">&gt;</span> <span class="nf">retrieveUsernameAsDTO</span><span class="o">(</span><span class="nd">@Param</span><span class="o">(</span><span class="s">"name"</span><span class="o">)</span> <span class="nc">String</span> <span class="n">name</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<ul>
  <li><code class="language-plaintext highlighter-rouge">List&lt;UserNameDTO&gt; retrieveUsernameAsDTO(...)</code> - This is the new method, which will retrieve the results as a <code class="language-plaintext highlighter-rouge">List</code> of <code class="language-plaintext highlighter-rouge">UserNameDTO</code>s instead of <code class="language-plaintext highlighter-rouge">User</code>.</li>
  <li><code class="language-plaintext highlighter-rouge">@Param("name") String name</code> - <code class="language-plaintext highlighter-rouge">@Param</code> helps the system to recognize the passed parameter and insert it into the query. Here <code class="language-plaintext highlighter-rouge">:name</code>.</li>
  <li><code class="language-plaintext highlighter-rouge">new de.smarterco.example.dto.UserNameDTO(u.id, u.name)</code> - This is where the <strong>magic</strong> happens. The JPQL query creates a new <code class="language-plaintext highlighter-rouge">UserNameDTO</code> by the use of the complete package name and the parameterized constructor created before. The only thing left is to map the necessary <code class="language-plaintext highlighter-rouge">User</code> variables(<code class="language-plaintext highlighter-rouge">u.id, u.name</code>) onto the DTO.</li>
</ul>]]></content><author><name>Kamil Wozniak</name></author><category term="Java" /><category term="Spring" /><category term="Spring Framework" /><category term="Spring Boot" /><category term="Spring Data JPA" /><category term="Spring Data" /><category term="JPA" /><summary type="html"><![CDATA[One of the hidden gems of Spring Data JPA is the possibility to put your query results directly into a DTO instead of having it transformed by a mapper]]></summary></entry><entry><title type="html">Java Persistence API: Creating a base entity</title><link href="/jpa-creating-a-base-entity/" rel="alternate" type="text/html" title="Java Persistence API: Creating a base entity" /><published>2017-07-17T00:00:00+00:00</published><updated>2017-07-17T00:00:00+00:00</updated><id>/jpa-creating-a-base-entity</id><content type="html" xml:base="/jpa-creating-a-base-entity/"><![CDATA[<h3 id="introduction">Introduction</h3>

<p>As a developer you get quite often confronted with the setup of a new Java project and some tasks repeat themselves.
One of them is thinking about how you would like to design your entities - if you work with JPA of course 🙂 - and if you would like to create a <code class="language-plaintext highlighter-rouge">BaseEntity</code>.</p>

<p>The advantage of a <code class="language-plaintext highlighter-rouge">BaseEntity</code>-class is, that it provides all extending classes with - like the name says - base functionality and you don’t need to create the <code class="language-plaintext highlighter-rouge">id</code> on each class for itself.</p>

<h3 id="baseentity">BaseEntity</h3>

<p>Let’s take a look at some of the keywords in this class:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">@MappedSuperclass</code> - By the use of <code class="language-plaintext highlighter-rouge">@MappedSuperclass</code> the <code class="language-plaintext highlighter-rouge">BaseEntity</code> class will not have a separate representation as table in the database. All fields in this class will be stored in the table of the extending class.</li>
  <li><code class="language-plaintext highlighter-rouge">public abstract class BaseEntity</code> - Making this class <code class="language-plaintext highlighter-rouge">abstract</code> prevents the developers from instantiating an instance of this class. Only extending classes can instantiate an instance.</li>
  <li><code class="language-plaintext highlighter-rouge">id</code> - The <code class="language-plaintext highlighter-rouge">id</code> is annotated with <code class="language-plaintext highlighter-rouge">@Id</code>, which marks it as the primary key to identify this entity.</li>
  <li><code class="language-plaintext highlighter-rouge">@GeneratedValue(strategy = GenerationType.AUTO)</code> - You can specify the generation strategy. <code class="language-plaintext highlighter-rouge">GenerationType.AUTO</code> will automatically choose a strategy for you, depending on the underlying database.</li>
  <li><code class="language-plaintext highlighter-rouge">version</code> - This field is not necessary, but with the <code class="language-plaintext highlighter-rouge">@Version</code> annotation you will get <a href="http://www.objectdb.com/java/jpa/persistence/lock"><code class="language-plaintext highlighter-rouge">Optimistic Locking</code></a> as addition. When you first instantiate an instance of a extending class, the value of <code class="language-plaintext highlighter-rouge">version</code> will be <code class="language-plaintext highlighter-rouge">0</code>. <code class="language-plaintext highlighter-rouge">Saving</code>/<code class="language-plaintext highlighter-rouge">Updating</code> this object in the database will increment this field by one. Did a change happen while you are trying to persist it into the database, an exception will get thrown.</li>
</ul>

<p class="notice--warning"><strong>Possible bottleneck <code class="language-plaintext highlighter-rouge">@GeneratedValue(strategy = GenerationType.AUTO)</code></strong> <br />
Using <code class="language-plaintext highlighter-rouge">@GeneratedValue(strategy = GenerationType.AUTO)</code> can be also a disadvantage, while using it with Postgres or Oracle. This databases do not have <code class="language-plaintext highlighter-rouge">autoincremental</code> fields as you know it from MySQL and they will use a sequence. Depending on how you created your database or sequences, it can happen that all your entities will share the same sequence: a possible bottleneck when performing a lot of insert operations.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">javax.persistence.*</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.io.Serializable</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.Objects</span><span class="o">;</span>

<span class="nd">@MappedSuperclass</span>
<span class="kd">public</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">BaseEntity</span> <span class="kd">implements</span> <span class="nc">Serializable</span> <span class="o">{</span>

    <span class="nd">@Id</span>
    <span class="nd">@GeneratedValue</span><span class="o">(</span><span class="n">strategy</span> <span class="o">=</span> <span class="nc">GenerationType</span><span class="o">.</span><span class="na">AUTO</span><span class="o">)</span>
    <span class="kd">private</span> <span class="nc">Long</span> <span class="n">id</span><span class="o">;</span>

    <span class="nd">@Version</span>
    <span class="kd">private</span> <span class="nc">Long</span> <span class="n">version</span><span class="o">;</span>

    <span class="kd">public</span> <span class="nc">Long</span> <span class="nf">getId</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">id</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setId</span><span class="o">(</span><span class="nc">Long</span> <span class="n">id</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">id</span> <span class="o">=</span> <span class="n">id</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="nc">Long</span> <span class="nf">getVersion</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">version</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setVersion</span><span class="o">(</span><span class="nc">Long</span> <span class="n">version</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">version</span> <span class="o">=</span> <span class="n">version</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="nc">Object</span> <span class="n">o</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="k">this</span> <span class="o">==</span> <span class="n">o</span><span class="o">)</span> <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">o</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">||</span> <span class="n">getClass</span><span class="o">()</span> <span class="o">!=</span> <span class="n">o</span><span class="o">.</span><span class="na">getClass</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
        <span class="nc">BaseEntity</span> <span class="n">that</span> <span class="o">=</span> <span class="o">(</span><span class="nc">BaseEntity</span><span class="o">)</span> <span class="n">o</span><span class="o">;</span>
        <span class="k">return</span> <span class="nc">Objects</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="n">that</span><span class="o">.</span><span class="na">id</span><span class="o">)</span> <span class="o">&amp;&amp;</span>
                <span class="nc">Objects</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">version</span><span class="o">,</span> <span class="n">that</span><span class="o">.</span><span class="na">version</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">int</span> <span class="nf">hashCode</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="nc">Objects</span><span class="o">.</span><span class="na">hash</span><span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="n">version</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="nc">String</span> <span class="nf">toString</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="s">"BaseEntity{"</span> <span class="o">+</span>
                <span class="s">"id="</span> <span class="o">+</span> <span class="n">id</span> <span class="o">+</span>
                <span class="s">", version="</span> <span class="o">+</span> <span class="n">version</span> <span class="o">+</span>
                <span class="sc">'}'</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="base-entity-with-temporal-and-changed-by-fields">Base entity with temporal and changed by fields</h3>

<p>While we have seen the <code class="language-plaintext highlighter-rouge">BaseEntity</code> class, it is also possible to go further and use additional keywords provided by JPA for our advantage.
The following entity contains additional fields like <code class="language-plaintext highlighter-rouge">createdBy</code>, <code class="language-plaintext highlighter-rouge">updatedBy</code>, <code class="language-plaintext highlighter-rouge">createdAt</code> and <code class="language-plaintext highlighter-rouge">updatedAt</code>. The last two are <code class="language-plaintext highlighter-rouge">TemporalType</code>, which contain a timestamp.</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">@PrePersist</code> - This annotation is a marker, which tells the underlying JPA implementation to execute this marked method. In our case it fills the <code class="language-plaintext highlighter-rouge">createdAt</code> field with the current time. This method will be executed on the first insert/creation/persist of the entity.</li>
  <li><code class="language-plaintext highlighter-rouge">@PreUpdate</code>- This annotation is a marker, which tells the underlying JPA implementation to execute this marked method on each update of the entity. In our case it fills the <code class="language-plaintext highlighter-rouge">updatedAt</code> field with the current time.</li>
</ul>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">javax.persistence.*</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.io.Serializable</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.Date</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.Objects</span><span class="o">;</span>

<span class="nd">@MappedSuperclass</span>
<span class="kd">public</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">BaseEntityAudit</span> <span class="kd">extends</span> <span class="nc">BaseEntity</span> <span class="kd">implements</span> <span class="nc">Serializable</span> <span class="o">{</span>

    <span class="kd">private</span> <span class="nc">String</span> <span class="n">createdBy</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">updatedBy</span><span class="o">;</span>

    <span class="nd">@Temporal</span><span class="o">(</span><span class="nc">TemporalType</span><span class="o">.</span><span class="na">TIMESTAMP</span><span class="o">)</span>
    <span class="kd">private</span> <span class="nc">Date</span> <span class="n">createdAt</span><span class="o">;</span>

    <span class="nd">@Temporal</span><span class="o">(</span><span class="nc">TemporalType</span><span class="o">.</span><span class="na">TIMESTAMP</span><span class="o">)</span>
    <span class="kd">private</span> <span class="nc">Date</span> <span class="n">updatedAt</span><span class="o">;</span>

    <span class="cm">/**
     * Sets createdAt before insert
     */</span>
    <span class="nd">@PrePersist</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setCreationDate</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">createdAt</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Date</span><span class="o">();</span>
    <span class="o">}</span>

    <span class="cm">/**
     * Sets updatedAt before update
     */</span>
    <span class="nd">@PreUpdate</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setChangeDate</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">updatedAt</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Date</span><span class="o">();</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="nc">Date</span> <span class="nf">getCreatedAt</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">createdAt</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setCreatedAt</span><span class="o">(</span><span class="nc">Date</span> <span class="n">createdAt</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">createdAt</span> <span class="o">=</span> <span class="n">createdAt</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="nc">Date</span> <span class="nf">getUpdatedAt</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">updatedAt</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setUpdatedAt</span><span class="o">(</span><span class="nc">Date</span> <span class="n">updatedAt</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">updatedAt</span> <span class="o">=</span> <span class="n">updatedAt</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="nc">String</span> <span class="nf">getCreatedBy</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">createdBy</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setCreatedBy</span><span class="o">(</span><span class="nc">String</span> <span class="n">createdBy</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">createdBy</span> <span class="o">=</span> <span class="n">createdBy</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="nc">String</span> <span class="nf">getUpdatedBy</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">updatedBy</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setUpdatedBy</span><span class="o">(</span><span class="nc">String</span> <span class="n">updatedBy</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">updatedBy</span> <span class="o">=</span> <span class="n">updatedBy</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="nc">Object</span> <span class="n">o</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="k">this</span> <span class="o">==</span> <span class="n">o</span><span class="o">)</span> <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">o</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">||</span> <span class="n">getClass</span><span class="o">()</span> <span class="o">!=</span> <span class="n">o</span><span class="o">.</span><span class="na">getClass</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
        <span class="k">if</span> <span class="o">(!</span><span class="kd">super</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">o</span><span class="o">))</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
        <span class="nc">BaseEntityAudit</span> <span class="n">that</span> <span class="o">=</span> <span class="o">(</span><span class="nc">BaseEntityAudit</span><span class="o">)</span> <span class="n">o</span><span class="o">;</span>
        <span class="k">return</span> <span class="nc">Objects</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">createdBy</span><span class="o">,</span> <span class="n">that</span><span class="o">.</span><span class="na">createdBy</span><span class="o">)</span> <span class="o">&amp;&amp;</span>
                <span class="nc">Objects</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">updatedBy</span><span class="o">,</span> <span class="n">that</span><span class="o">.</span><span class="na">updatedBy</span><span class="o">)</span> <span class="o">&amp;&amp;</span>
                <span class="nc">Objects</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">createdAt</span><span class="o">,</span> <span class="n">that</span><span class="o">.</span><span class="na">createdAt</span><span class="o">)</span> <span class="o">&amp;&amp;</span>
                <span class="nc">Objects</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">updatedAt</span><span class="o">,</span> <span class="n">that</span><span class="o">.</span><span class="na">updatedAt</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">int</span> <span class="nf">hashCode</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="nc">Objects</span><span class="o">.</span><span class="na">hash</span><span class="o">(</span><span class="kd">super</span><span class="o">.</span><span class="na">hashCode</span><span class="o">(),</span> <span class="n">createdBy</span><span class="o">,</span> <span class="n">updatedBy</span><span class="o">,</span> <span class="n">createdAt</span><span class="o">,</span> <span class="n">updatedAt</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="nc">String</span> <span class="nf">toString</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="s">"BaseEntityAudit{"</span> <span class="o">+</span>
                <span class="s">"createdBy='"</span> <span class="o">+</span> <span class="n">createdBy</span> <span class="o">+</span> <span class="sc">'\''</span> <span class="o">+</span>
                <span class="s">", updatedBy='"</span> <span class="o">+</span> <span class="n">updatedBy</span> <span class="o">+</span> <span class="sc">'\''</span> <span class="o">+</span>
                <span class="s">", createdAt="</span> <span class="o">+</span> <span class="n">createdAt</span> <span class="o">+</span>
                <span class="s">", updatedAt="</span> <span class="o">+</span> <span class="n">updatedAt</span> <span class="o">+</span>
                <span class="s">"} "</span> <span class="o">+</span> <span class="kd">super</span><span class="o">.</span><span class="na">toString</span><span class="o">();</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>]]></content><author><name>Kamil Wozniak</name></author><category term="Java" /><category term="JPA" /><category term="Base entity" /><summary type="html"><![CDATA[How to create a JPA base entity without mapping it onto a separate table]]></summary></entry></feed>