Thoughts and Ideas Related to Java ProgrammingJekyll2018-08-30T01:58:08-07:00http://ageofjava.com/Emil Forslundhttp://ageofjava.com/me@ageofjava.comhttp://ageofjava.com/java/Auto-Generate-REST-APIs2018-08-30T00:00:00-07:002018-08-30T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>If you have an existing database and you want to write a front-end to work with it, you often find yourself spending hours setting up the glue between the database and the frontend. It would be much more efficient use of your time if you could simply press a button and generate the entire REST API directly.</p>
<p>Speedment is a tool that uses code generation to produce a tailored domain model based on an existing database structure. Queries can either be sent directly to the database, or served from in-memory for better performance. In this article we will use the official plugin called “spring-generator” for Speedment Free to generate a complete Spring application to serve a simple REST API. We will add support for paging, remote filtering and sorting, without writing a single line of code.</p>
<h3 id="the-database">The Database</h3>
<p>In the examples below, we are using the <a href="https://dev.mysql.com/doc/sakila/en">Sakila database</a> for MySQL. Sakila is an example database that models a movie rental store. It has tables called Film, Actor, Category and so on.</p>
<h3 id="step-1-create-the-project">Step 1: Create the Project</h3>
<p>The first thing we need is to configure our <code class="highlighter-rouge">pom.xml</code>-file to use the latest Speedment dependencies and Maven plugin. The fastest way to do this is to generate a <code class="highlighter-rouge">pom.xml</code>-file using the Speedment Initializer that you <a href="https://speedment.com/initializer">can find here</a>. If you select “Spring” in the plugin list and press “Download”, you will get an entire project folder with a <code class="highlighter-rouge">Main.java</code>-file generated automatically.</p>
<p><img src="/images/2018-08-30/initializer.png" alt="The Speedment Initializer" /></p>
<p><img src="/images/2018-08-30/zip.png" alt="Structure of the downloaded folder" /></p>
<p>Next, open a command line where you downloaded the file and enter the following:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn speedment:tool
</code></pre></div></div>
<p>This will launch the Speedment tool and prompt you for a license key. Simply select “Start Free” and you will get a free license! Once you have registered, you can connect to the database and get started.</p>
<p><img src="/images/2018-08-30/connect.png" alt="Connecting to a Database with Speedment" /></p>
<h3 id="step-2-generate-a-controller">Step 2: Generate a Controller</h3>
<p>By default, the only thing the <code class="highlighter-rouge">spring-generator</code> plugin adds in addition to the regular Speedment classes is a <code class="highlighter-rouge">@Configuration</code>-bean. To actually generate controllers for your tables, you can select the table in the tree to the left and then check “Generate @RestController” on the right side.</p>
<p><img src="/images/2018-08-30/rest-enabled.png" alt="Make sure the checkbox is checked" /></p>
<p>This will enable a number of options below it, but we will get to these in a minute. For now, this is all you need to do to enable the controller logic. Click “Generate” to generate the code.</p>
<p><img src="/images/2018-08-30/generate.png" alt="Click on the Generate-button in the Toolbar" /></p>
<p>In the IDE, you can now see a number of classes. If you downloaded the <code class="highlighter-rouge">.zip</code>-file from the Initializer then you should already have a <code class="highlighter-rouge">Main.java</code>-file. Make sure it is in the correct folder, then build and run the application.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn clean install <span class="o">&&</span> java <span class="nt">-jar</span> target/example-app-1.0.0-SNAPSHOT.jar
</code></pre></div></div>
<p>You can try out the new REST API by calling:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl localhost:8080/film
</code></pre></div></div>
<p>Easy, huh?</p>
<h3 id="step-3-using-filters">Step 3: Using Filters</h3>
<p>A cool feature with the spring-generator plugin is that it supports remote filtering. It means that the frontend can send predicates encoded as JSON-objects to the server, and the server will respond with a filtered JSON response. Speedment automatically parses the JSON filters into a SQL <code class="highlighter-rouge">SELECT</code>-statement. If you want to be able to serve thousands of requests per second, you can also enable the Speedment Datastore to serve queries directly from memory, in which case the JSON filters will be parsed to find an appropriate in-memory index.</p>
<p>The syntax for the JSON filters is easy. To get films with a length less than 60 minutes, you simply call:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-G</span> localhost:8080/film <span class="nt">--data-urlencode</span> <span class="se">\</span>
<span class="s1">'filter={"property":"length","operator":"lt","value":60}'</span>
</code></pre></div></div>
<p>(The -G argument makes sure that the command is sent as a GET request and not a POST request)</p>
<p>You can add multiple filters by wrapping the object in a list.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-G</span> localhost:8080/film <span class="nt">--data-urlencode</span> <span class="se">\</span>
<span class="s1">'filter=[{"property":"length","operator":"lt","value":60},
{"property":"length","operator":"ge","value":30}]'</span>
</code></pre></div></div>
<p>This will return all films with a length between 30 and 60 minutes. By default, all the operators in the list are assumed to be separated with AND-operators. All the conditions must apply for a row to pass the filter. To change this, you can use an explicit OR-statement.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-G</span> localhost:8080/film <span class="nt">--data-urlencode</span> <span class="se">\</span>
<span class="s1">'filter={"or":[{"property":"length","operator":"lt","value":30},
{"property":"length","operator":"ge","value":60}]}'</span>
</code></pre></div></div>
<p>This will return all films that are either shorter than 30 minutes or longer than one hour.</p>
<h3 id="step-4-using-sorters">Step 4: Using Sorters</h3>
<p>By default, Speedment returns rows in the same order as the database returns them. If you add filters to the expression however, the returned order is undefined. To make sure the order is well defined in the frontend, you could therefore send a defined order to the generated backend to tell it how to sort elements. If you use Speedment Datastore to serve elements from in-memory, then it will use in-memory indexes to resolve the correct order.</p>
<p>Here is an example where the films are retrieved by their length.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-G</span> localhost:8080/film <span class="nt">--data-urlencode</span> <span class="se">\</span>
<span class="s1">'sort={"property":"length"}'</span>
</code></pre></div></div>
<p>To get the films in the opposite order, you can specify a descending order like this:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-G</span> localhost:8080/film <span class="nt">--data-urlencode</span> <span class="se">\</span>
<span class="s1">'sort={"property":"length","direction":"DESC"}'</span>
</code></pre></div></div>
<p>You can also send multiple sorters to the backend to define the primary order, the secondary order and so on.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-G</span> localhost:8080/film <span class="nt">--data-urlencode</span> <span class="se">\</span>
<span class="s1">'sort=[{"property":"length","direction":"DESC"},
{"property":"title","direction":"ASC"}]'</span>
</code></pre></div></div>
<h3 id="step-5-using-paging">Step 5: Using Paging</h3>
<p>The last feature of the <code class="highlighter-rouge">spring-generator</code> plugin is the ability to page results to avoid sending unnecessary large objects to the browser. This is enabled by default, which is why you won’t see more than 25 results when you query the backend. To skip a number of results (not pages), you can specify the <code class="highlighter-rouge">?start=</code> parameter.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl localhost:8080/film?start<span class="o">=</span>25
</code></pre></div></div>
<p>This will skip the first 25 elements and begin at the 26th. You can change the default page size by adding the <code class="highlighter-rouge">?limit=</code> parameter.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="s1">'localhost:8080/film?start=25&limit=5'</span>
</code></pre></div></div>
<p>This also begins at the 26th element, but only returns 5 elements instead of 25.</p>
<h3 id="summary">Summary</h3>
<p>In this article you have learned how easy it is to get a full REST API up and running using Speedment, Spring and the <code class="highlighter-rouge">generate-spring</code> plugin. There is <a href="https://speedment.com/initializer">a free option of Speedment</a> so do try it out!</p>
<p><a href="http://ageofjava.com/java/Auto-Generate-REST-APIs">Auto-Generate a REST API from a Database With Spring</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on August 30, 2018.</p>http://ageofjava.com/java/Super-Fast-Statistical-Queries2018-01-19T00:00:00-08:002018-01-19T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>Many organizations have enormous values in data stored in relational databases, but it is often slow to analyze. Calculating things like correlation coefficients or analyzing trends can take many minutes or even hours using a regular SQL database. Wouldn’t it be nice to be able to do it in seconds or even in milliseconds?</p>
<p>As some of you know, <a href="https://github.com/speedment/speedment">Speedment</a> is a modern Java ORM that is built around the new functionality of Java 8 and 9, like Streams. The <a href="https://www.speedment.com/solutions/enterprise/">enterprise edition</a> allows Java developers to easily run typesafe queries on an off-heap in-memory view of the data, without running into garbage collect limitations even when aggregating hundreds of millions of rows. In this article I will show you some nice examples of analytics that can be performed using these tools.</p>
<h2 id="correlation-analysis-in-spring">Correlation Analysis in Spring</h2>
<p>This article explains how to write a Java Spring application that queries a database of salary-entries to calculate a correlation analysis like this:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"M"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">1706321</span><span class="p">,</span><span class="w">
</span><span class="s2">"salaryMean"</span><span class="p">:</span><span class="w"> </span><span class="mi">63838</span><span class="p">,</span><span class="w">
</span><span class="s2">"daysEmployedMean"</span><span class="p">:</span><span class="w"> </span><span class="mf">2562.9950696092446</span><span class="p">,</span><span class="w">
</span><span class="s2">"salaryVariance"</span><span class="p">:</span><span class="w"> </span><span class="mf">287120292.49482954</span><span class="p">,</span><span class="w">
</span><span class="s2">"daysEmployedVariance"</span><span class="p">:</span><span class="w"> </span><span class="mf">2521092.66062704</span><span class="p">,</span><span class="w">
</span><span class="s2">"correlation"</span><span class="p">:</span><span class="w"> </span><span class="mf">0.38346220360987127</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="s2">"F"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">1137726</span><span class="p">,</span><span class="w">
</span><span class="s2">"salaryMean"</span><span class="p">:</span><span class="w"> </span><span class="mi">63769</span><span class="p">,</span><span class="w">
</span><span class="s2">"daysEmployedMean"</span><span class="p">:</span><span class="w"> </span><span class="mf">2562.467887479722</span><span class="p">,</span><span class="w">
</span><span class="s2">"salaryVariance"</span><span class="p">:</span><span class="w"> </span><span class="mf">283750106.3594864</span><span class="p">,</span><span class="w">
</span><span class="s2">"daysEmployedVariance"</span><span class="p">:</span><span class="w"> </span><span class="mf">2515737.630249606</span><span class="p">,</span><span class="w">
</span><span class="s2">"correlation"</span><span class="p">:</span><span class="w"> </span><span class="mf">0.3829530560640214</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>Even without caching, the result is computed over a dataset of 2.8 million rows and sent back in less than a second. If you were to do this on the heap using regular Java HashMaps to store intermediate values, the Garbage Collector would have to run several times over the course of every query, slowing down computation significantly. With Speedment, it is all offheap.</p>
<p>You can get the sources for <a href="https://github.com/speedment/speedment-code-samples/tree/master/enterprise/advanced-aggregator-example">the article here</a>.</p>
<h2 id="demo-database-with-28-million-rows">Demo Database with 2.8 Million Rows</h2>
<p>In the examples I used the <a href="https://dev.mysql.com/doc/employee/en/">Employees demo database</a> for MySQL. It has more than 2.8 million rows of salary information that we are going to analyze. I have not made any changes to the database-side. I am only accessing it using Speedment.</p>
<h2 id="step-1-creating-the-project">Step 1: Creating the Project</h2>
<p>To setup the project, I used <a href="https://speedment.com/initializer">the initializer</a> on the Speedment website to generate a <code class="highlighter-rouge">pom.xml</code>-file.</p>
<p><img src="/images/2018-01-19/initializer.png" alt="The Speedment Initializer" /></p>
<p>I selected “MySQL” as the Database Type, checked all the three “Plugins” and enabled “In-memory Acceleration”. On the right-hand side is a generated <code class="highlighter-rouge">Main.java</code>-file as well as a <code class="highlighter-rouge">pom.xml</code>-file. I am only going to use the <code class="highlighter-rouge">pom.xml</code>-file in this case. For the sake of keeping these examples short I also decided to manually add <a href="https://projectlombok.org/">Project Lombok</a> to the <code class="highlighter-rouge">pom.xml</code> to generate getters and setters automatically.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><dependency></span>
<span class="nt"><groupId></span>org.projectlombok<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>lombok<span class="nt"></artifactId></span>
<span class="nt"><version></span>1.16.20<span class="nt"></version></span>
<span class="nt"><scope></span>provided<span class="nt"></scope></span>
<span class="nt"></dependency></span>
</code></pre></div></div>
<p>Once I pasted the generated <code class="highlighter-rouge">pom.xml</code> file into an empty folder, I opened a shell window and ran:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn speedment:tool
</code></pre></div></div>
<p>This Maven command is used to launch the Speedment Tool. This is a nice way to connect to the database and generate all entities, serializers, managers, etc in a user friendly way.</p>
<p><img src="/images/2018-01-19/step1_connect.png" alt="The Speedment Connect Dialog" /></p>
<p>In the tool, I disabled all the tables except Salary. Tables can be disabled in bulk by right-clicking the “Schema” node in the tree and selecting “Disable All Tables”. The best way to limit the memory footprint of the application is to make sure you don’t pull more tables than necessary into memory.</p>
<p><img src="/images/2018-01-19/step2_disable_all.png" alt="Disable unused tables" /></p>
<p>We do need some piece of information about the Employees-table however to be able to analyze the salaries of different groups of employees. Normally, if you are using SQL, you would use a JOIN statement to achieve this. In Speedment however, you add something called Virtual Columns.</p>
<p>To create a Virtual Column, right-click the “Table” node in the tree and select “Add Virtual Column”.</p>
<p><img src="/images/2018-01-19/step4_add_virtualcolumn.png" alt="Add virtual columns by right-clicking" /></p>
<p>I added a total of two Virtual Columns, “gender” and “hire_date” to the “Salary” table. By doing this, I have defined a denormalized view containing both the Salary information as well as some information about the Employee. I am going to use this when computing the correlation.</p>
<p><img src="/images/2018-01-19/step5_finished_columns2.png" alt="The finished columns" /></p>
<p>The last step before we get to write our Java code is to press “Generate”.</p>
<p><img src="/images/2018-01-19/step6_generate-button.png" alt="Press generate-button to finish" /></p>
<p>The settings are automatically saved in a file called <code class="highlighter-rouge">speedment.json</code> when the “Generate”-button is pressed, so the tool can safely be closed afterwards.</p>
<h3 id="configuring-spring">Configuring Spring</h3>
<p>Since I added the “Spring” plugin in the Initializer, the project has been configured to generate the basic classes needed to use Speedment in a Spring context. There is already a <code class="highlighter-rouge">@Configuration</code> annotated class that defines Spring beans for all the managers (in this case just the <code class="highlighter-rouge">SalaryManager</code> since we disabled the other tables).</p>
<p>The only thing we need to add to create a basic Spring application is a <code class="highlighter-rouge">MainApp.java</code>-file.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@SpringBootApplication</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MainApp</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">...</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="n">SpringApplication</span><span class="o">.</span><span class="na">run</span><span class="o">(</span><span class="n">MainApp</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="n">args</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>If your database is running on a different host or has a password set, you probably need to add a Spring configuration file in the root of the project to let Speedment know how to access it. Here is an example of my <code class="highlighter-rouge">application.yml</code>-file:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">server</span><span class="pi">:</span>
<span class="na">port</span><span class="pi">:</span> <span class="s">9001</span>
<span class="na">spring</span><span class="pi">:</span>
<span class="na">speedment</span><span class="pi">:</span>
<span class="na">username</span><span class="pi">:</span> <span class="s">root</span>
<span class="na">password</span><span class="pi">:</span> <span class="s">password</span>
</code></pre></div></div>
<p>That’s all the setup we need. Now we can start writing the actual business logic.</p>
<h2 id="step-2-compute-mean-salary">Step 2: Compute Mean Salary</h2>
<p>The first thing to do, to get accustomed to the API, is to do a simple aggregation. I want to divide all salaries in the database based on the gender of the employee and then calculate the mean and count of each. So, I will create a Spring controller for this called <code class="highlighter-rouge">SalaryMeanController</code>.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@RestController</span>
<span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">"/salary/mean"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SalaryMeanController</span> <span class="o">{</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Great. Now, to access the in-memory view that Speedment builds automatically when Spring is loaded, we need a <code class="highlighter-rouge">DataStoreComponent</code>. Luckily, this can be autowired like this:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@RestController</span>
<span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">"/salary/mean"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SalaryMeanController</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nd">@Autowired</span> <span class="n">DataStoreComponent</span> <span class="n">dataStore</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The <code class="highlighter-rouge">DataStoreComponent</code> is a component in Speedment that holds all the data pulled from the database. The same instance will live on for the duration of the program, even if the data is replaced. That is why we can use the <code class="highlighter-rouge">@Autowire</code> annotation to access it. However, while processing a request, we want to look at a single view of the data. To get an object that is immutable and that only contains the salary information in that moment, we need to retrieve the <code class="highlighter-rouge">EntityStore<Salary></code>. I am going to create a helper method to access the current store so that I do not have to type it over and over again.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@RestController</span>
<span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">"/salary/mean"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SalaryMeanController</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="kd">static</span> <span class="n">TableIdentifier</span><span class="o"><</span><span class="n">Salary</span><span class="o">></span> <span class="n">TABLE</span> <span class="o">=</span>
<span class="n">Salary</span><span class="o">.</span><span class="na">EMP_NO</span><span class="o">.</span><span class="na">identifier</span><span class="o">().</span><span class="na">asTableIdentifier</span><span class="o">();</span>
<span class="kd">private</span> <span class="nd">@Autowired</span> <span class="n">DataStoreComponent</span> <span class="n">dataStore</span><span class="o">;</span>
<span class="kd">private</span> <span class="n">EntityStore</span><span class="o"><</span><span class="n">Salary</span><span class="o">></span> <span class="nf">entityStore</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">dataStore</span><span class="o">.</span><span class="na">currentHolder</span><span class="o">().</span><span class="na">getEntityStore</span><span class="o">(</span><span class="n">TABLE</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>I can now call <code class="highlighter-rouge">entityStore()</code> whenever I want to access the current view of the data. The last thing I need to do before I can create the actual controller is to define a result-type. To keep this code short, I will use Lombok to generate its constructor and getters.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Data</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">Result</span> <span class="o">{</span>
<span class="nd">@JsonIgnore</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="kt">long</span> <span class="n">ref</span><span class="o">;</span>
<span class="kd">private</span> <span class="kt">long</span> <span class="n">count</span><span class="o">;</span>
<span class="kd">private</span> <span class="kt">double</span> <span class="n">salaryMean</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The purpose of the <code class="highlighter-rouge">Result</code> class is to let Speedment know how the results are supposed to be delivered. We can design this any way we want. In addition to the count and salary values, I have decided to also store a <code class="highlighter-rouge">long</code> called “ref”. This is an internal Speedment reference that can be used to later go back and look at one of the entities that belong to each bucket. In our case, we will use this later to keep track of which <code class="highlighter-rouge">Result</code> refers to which gender. I have set the reference to final so that Lombok will include it in the constructor and also added the <code class="highlighter-rouge">@JsonIgnore</code>-annotation since I do not want this reference to be included in the final JSON result.</p>
<p>I am now ready to write the actual controller method. Speedment uses a builder pattern to define aggregations. The builder is decorated with one or more “keys” that define the buckets of the aggregation and one or more “operations” that define how values in the same bucket should be combined. I will set the key to the “gender” column and add two operations; “count” and “average”.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@GetMapping</span>
<span class="n">Map</span><span class="o"><</span><span class="n">Salary</span><span class="o">.</span><span class="na">Gender</span><span class="o">,</span> <span class="n">Result</span><span class="o">></span> <span class="nf">get</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">EntityStore</span><span class="o"><</span><span class="n">Salary</span><span class="o">></span> <span class="n">store</span> <span class="o">=</span> <span class="n">entityStore</span><span class="o">();</span>
<span class="kd">final</span> <span class="n">Aggregator</span><span class="o"><</span><span class="n">Result</span><span class="o">></span> <span class="n">agg</span> <span class="o">=</span> <span class="n">Aggregator</span><span class="o">.</span><span class="na">builder</span><span class="o">(</span><span class="n">store</span><span class="o">,</span> <span class="nl">Result:</span><span class="o">:</span><span class="k">new</span><span class="o">)</span>
<span class="o">.</span><span class="na">withEnumKey</span><span class="o">(</span><span class="n">Salary</span><span class="o">.</span><span class="na">GENDER</span><span class="o">)</span>
<span class="o">.</span><span class="na">withAverage</span><span class="o">(</span><span class="n">Salary</span><span class="o">.</span><span class="na">SALARY</span><span class="o">,</span> <span class="nl">Result:</span><span class="o">:</span><span class="n">setSalaryMean</span><span class="o">)</span>
<span class="o">.</span><span class="na">withCount</span><span class="o">(</span><span class="nl">Result:</span><span class="o">:</span><span class="n">setCount</span><span class="o">)</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
<span class="c1">// ...</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The code above should be self explanatory. When the <code class="highlighter-rouge">AggregatorBuilder</code> is created, I define the store it should aggregate on and how the <code class="highlighter-rouge">Result</code> object defined earlier can be constructed from a Speedment reference. To finish the method, I need to invoke the aggregator on a stream of references and collect the result to a <code class="highlighter-rouge">Map</code> user a standard Java <code class="highlighter-rouge">Collector</code>.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">return</span> <span class="n">agg</span><span class="o">.</span><span class="na">aggregate</span><span class="o">(</span><span class="n">entityStore</span><span class="o">().</span><span class="na">references</span><span class="o">())</span>
<span class="o">.</span><span class="na">collect</span><span class="o">(</span><span class="n">toMap</span><span class="o">(</span>
<span class="n">result</span> <span class="o">-></span> <span class="n">store</span><span class="o">.</span><span class="na">deserializeAny</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">ref</span><span class="o">,</span> <span class="n">Salary</span><span class="o">.</span><span class="na">GENDER</span><span class="o">),</span>
<span class="n">Function</span><span class="o">.</span><span class="na">identity</span><span class="o">()</span>
<span class="o">));</span>
</code></pre></div></div>
<p><code class="highlighter-rouge">Collections.toMap</code> is a regular Java collector that takes two functional references. For each result, it uses the first function to generate the “key” and the second to generate the “value”. Remember the “ref” value I stored in the Result object? It is used here to look up the gender of each bucket in the store.</p>
<p>The resulting JSON looks like this:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"F"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">1137726</span><span class="p">,</span><span class="w">
</span><span class="s2">"salaryMean"</span><span class="p">:</span><span class="w"> </span><span class="mi">63769</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="s2">"M"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">1706321</span><span class="p">,</span><span class="w">
</span><span class="s2">"salaryMean"</span><span class="p">:</span><span class="w"> </span><span class="mi">63838</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>The cool thing with this is that the entire aggregation is performed off-heap. The <code class="highlighter-rouge">Result</code> objects you are seeing are only allocated once the result has already been computed. This is vital for achieving high performance when you want to aggregate huge datasets.</p>
<p>The finished <code class="highlighter-rouge">SalaryMeanController</code> can be <a href="https://github.com/speedment/speedment-code-samples/blob/master/enterprise/advanced-aggregator-example/src/main/java/com/speedment/example/aggregator/controller/SalaryMeanController.java">seen here</a>.</p>
<h2 id="step-3-compute-salary-variances">Step 3: Compute Salary Variances</h2>
<p>So far I have only performed a quite simple single-pass aggregation. A more complex aggregation that can not be performed in a single pass is to calculate a variance or a standard deviation on the data. That is what I will show next.</p>
<p>To implement the variance controller, I begin by duplicating the <code class="highlighter-rouge">SalaryMeanController</code> from above and call it <code class="highlighter-rouge">SalaryVarianceController</code>.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@RestController</span>
<span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">"/salary/variance"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SalaryVarianceController</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="kd">static</span> <span class="n">TableIdentifier</span><span class="o"><</span><span class="n">Salary</span><span class="o">></span> <span class="n">TABLE</span> <span class="o">=</span> <span class="o">...</span> <span class="o">;</span>
<span class="kd">private</span> <span class="nd">@Autowired</span> <span class="n">DataStoreComponent</span> <span class="n">dataStore</span><span class="o">;</span>
<span class="nd">@Data</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">Result</span> <span class="o">{</span> <span class="o">...</span> <span class="o">}</span>
<span class="nd">@GetMapping</span>
<span class="n">Map</span><span class="o"><</span><span class="n">Salary</span><span class="o">.</span><span class="na">Gender</span><span class="o">,</span> <span class="n">Result</span><span class="o">></span> <span class="nf">get</span><span class="o">()</span> <span class="o">{</span> <span class="o">...</span> <span class="o">}</span>
<span class="kd">private</span> <span class="n">EntityStore</span><span class="o"><</span><span class="n">Salary</span><span class="o">></span> <span class="nf">entityStore</span><span class="o">()</span> <span class="o">{</span> <span class="o">...</span> <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The <code class="highlighter-rouge">Result</code> object we defined earlier works fine for the first pass, but for the second pass we also want to store the variance. I am therefore going to create a second class called <code class="highlighter-rouge">Result2</code>.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Data</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">Result2</span> <span class="o">{</span>
<span class="nd">@JsonIgnore</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="kt">long</span> <span class="n">ref</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="kt">long</span> <span class="n">count</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="kt">double</span> <span class="n">salaryMean</span><span class="o">;</span>
<span class="kd">private</span> <span class="kt">double</span> <span class="n">salaryVariance</span><span class="o">;</span>
<span class="n">Result2</span><span class="o">(</span><span class="n">Result</span> <span class="n">firstPass</span><span class="o">)</span> <span class="o">{</span>
<span class="n">ref</span> <span class="o">=</span> <span class="n">firstPass</span><span class="o">.</span><span class="na">ref</span><span class="o">;</span>
<span class="n">count</span> <span class="o">=</span> <span class="n">firstPass</span><span class="o">.</span><span class="na">count</span><span class="o">;</span>
<span class="n">salaryMean</span> <span class="o">=</span> <span class="n">firstPass</span><span class="o">.</span><span class="na">salaryMean</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Here I defined my own constructor so that I can copy values already computed from the previous result. The only value that needs to be computed in the second pass is the salary variance since I already have the mean and count from the first pass.</p>
<p>The controller method requires some modifications from the one used in <code class="highlighter-rouge">SalaryMeanController</code>. First, I should change the return type so that the new <code class="highlighter-rouge">Result2</code>-type is used instead of <code class="highlighter-rouge">Result</code>.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@GetMapping</span>
<span class="n">Map</span><span class="o"><</span><span class="n">Salary</span><span class="o">.</span><span class="na">Gender</span><span class="o">,</span> <span class="n">Result2</span><span class="o">></span> <span class="nf">get</span><span class="o">()</span> <span class="o">{</span> <span class="o">...</span> <span class="o">}</span>
</code></pre></div></div>
<p>The code computing the first pass remains the same so I won’t repeat it here. The interesting thing is the second pass. Instead of collecting the result stream immediately after aggregating the first pass, I inserted a <code class="highlighter-rouge">.flatMap()</code>-operation. It will be invoked once for each bucket produced by the first pass (so two times since we used gender as the key). The <code class="highlighter-rouge">flatMap()</code> will then return the <code class="highlighter-rouge">Stream<Result2></code> to be collected.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">.</span><span class="na">flatMap</span><span class="o">(</span><span class="n">previous</span> <span class="o">-></span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">Salary</span><span class="o">.</span><span class="na">Gender</span> <span class="n">gender</span> <span class="o">=</span>
<span class="n">store</span><span class="o">.</span><span class="na">deserializeAny</span><span class="o">(</span><span class="n">previous</span><span class="o">.</span><span class="na">ref</span><span class="o">,</span> <span class="n">Salary</span><span class="o">.</span><span class="na">GENDER</span><span class="o">);</span>
<span class="k">return</span> <span class="n">Aggregator</span><span class="o">.</span><span class="na">builder</span><span class="o">(</span><span class="n">store</span><span class="o">,</span> <span class="n">ref</span> <span class="o">-></span> <span class="k">new</span> <span class="n">Result2</span><span class="o">(</span><span class="n">previous</span><span class="o">))</span>
<span class="o">.</span><span class="na">withEnumKey</span><span class="o">(</span><span class="n">Salary</span><span class="o">.</span><span class="na">GENDER</span><span class="o">)</span>
<span class="o">.</span><span class="na">withVariance</span><span class="o">(</span>
<span class="n">Salary</span><span class="o">.</span><span class="na">SALARY</span><span class="o">,</span>
<span class="n">previous</span><span class="o">.</span><span class="na">salary</span><span class="o">,</span>
<span class="nl">Result2:</span><span class="o">:</span><span class="n">setSalaryVariance</span><span class="o">)</span>
<span class="o">.</span><span class="na">build</span><span class="o">()</span>
<span class="o">.</span><span class="na">aggregate</span><span class="o">(</span><span class="n">genderFieldCache</span><span class="o">().</span><span class="na">equal</span><span class="o">(</span>
<span class="n">gender</span><span class="o">,</span> <span class="n">Order</span><span class="o">.</span><span class="na">ASC</span><span class="o">,</span> <span class="mi">0</span><span class="o">,</span> <span class="n">Long</span><span class="o">.</span><span class="na">MAX_VALUE</span><span class="o">)</span>
<span class="o">);</span>
<span class="o">}</span>
<span class="o">)</span>
</code></pre></div></div>
<p>Inside the lambda, I look up which gender the bucket represents and use a new <code class="highlighter-rouge">Aggregator</code> to compute the variance. <code class="highlighter-rouge">withVariance(...)</code> is a convenience method that computes the squared difference from a mean. I simply input the mean computed in the first step and set the result just as previous. Instead of aggregating <code class="highlighter-rouge">entityStore().references()</code> like we did in the first step we use <code class="highlighter-rouge">genderFieldCache().equal(...)</code>. This is a method we haven’t defined yet, but the reason why we don’t use the store in the second pass is that we want only rows with the same gender to be included.</p>
<p>The method <code class="highlighter-rouge">genderFieldCache()</code> is also very simple.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="n">FieldCache</span><span class="o">.</span><span class="na">OfEnum</span><span class="o"><</span><span class="n">Salary</span><span class="o">.</span><span class="na">Gender</span><span class="o">></span> <span class="nf">genderFieldCache</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">dataStore</span><span class="o">.</span><span class="na">currentHolder</span><span class="o">().</span><span class="na">getFieldCache</span><span class="o">(</span>
<span class="n">Salary</span><span class="o">.</span><span class="na">GENDER</span><span class="o">.</span><span class="na">identifier</span><span class="o">()</span>
<span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>If I now run the application and access the new controller, I get this:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"F"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">1137726</span><span class="p">,</span><span class="w">
</span><span class="s2">"salaryMean"</span><span class="p">:</span><span class="w"> </span><span class="mi">63769</span><span class="p">,</span><span class="w">
</span><span class="s2">"salaryVariance"</span><span class="p">:</span><span class="w"> </span><span class="mf">283750106.3594864</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="s2">"M"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">1706321</span><span class="p">,</span><span class="w">
</span><span class="s2">"salaryMean"</span><span class="p">:</span><span class="w"> </span><span class="mi">63838</span><span class="p">,</span><span class="w">
</span><span class="s2">"salaryVariance"</span><span class="p">:</span><span class="w"> </span><span class="mf">287120292.49482954</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>The finished <code class="highlighter-rouge">SalaryVarianceController</code> can be <a href="https://github.com/speedment/speedment-code-samples/blob/master/enterprise/advanced-aggregator-example/src/main/java/com/speedment/example/aggregator/controller/SalaryVarianceController.java">seen here</a>.</p>
<h2 id="step-4-compute-correlation-between-salary-and-employment-days">Step 4: Compute Correlation Between Salary and Employment Days</h2>
<p>Looking at means and variances is one thing, but a much more powerful statistical tool is comparing two columns to see if there is a linear correlation. The goal of the fourth step of this article is to compute Pearson’s correlation coefficient between the salary of an employee and the number of days they have been employed. Computing the coefficient requires not only two passes, but also a way to express cross-column operations. Speedment supports this by using the <code class="highlighter-rouge">Aggregations</code> utility class.</p>
<p>First, I copy the <code class="highlighter-rouge">SalaryVarianceController</code> and name it <code class="highlighter-rouge">SalaryCorrelationController</code>.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@RestController</span>
<span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">"/salary/correlation"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SalaryCorrelationController</span> <span class="o">{</span> <span class="o">...</span> <span class="o">}</span>
</code></pre></div></div>
<p>The first obstacle working with the Salary table is that there is no column called “days_employed”. The closest thing is the two dates “from_date” and “hire_date”. Before I can calculate the correlation, I therefore need to create a custom “deserializer” that computes the difference between the epoch seconds of these two dates and then multiplies it with a constant to get the difference in days rather than seconds. I created this deserializer as a static variable called <code class="highlighter-rouge">DAYS_EMPLOYED</code> so that I do not have to repeat myself.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="kd">final</span> <span class="kd">static</span> <span class="kt">int</span> <span class="n">SECONDS_IN_A_DAY</span> <span class="o">=</span> <span class="mi">86_400</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="kd">static</span> <span class="n">DeserializeDouble</span><span class="o"><</span><span class="n">Salary</span><span class="o">></span> <span class="n">DAYS_EMPLOYED</span> <span class="o">=</span>
<span class="n">multiply</span><span class="o">(</span>
<span class="n">minus</span><span class="o">(</span>
<span class="n">getAsLongOrElse</span><span class="o">(</span><span class="n">Salary</span><span class="o">.</span><span class="na">FROM_DATE</span><span class="o">,</span> <span class="mi">0</span><span class="o">),</span>
<span class="n">getAsLongOrElse</span><span class="o">(</span><span class="n">Salary</span><span class="o">.</span><span class="na">HIRE_DATE</span><span class="o">,</span> <span class="mi">0</span><span class="o">)</span>
<span class="o">).</span><span class="na">asDeserializeDouble</span><span class="o">(),</span>
<span class="n">constant</span><span class="o">(</span><span class="mi">1</span><span class="n">d</span> <span class="o">/</span> <span class="n">SECONDS_IN_A_DAY</span><span class="o">)</span>
<span class="o">);</span>
</code></pre></div></div>
<p>Note that many of the methods used above must be imported statically from:
<code class="highlighter-rouge">com.speedment.enterprise.datastore.runtime.aggregator.Aggregators</code>.</p>
<p>I also need to modify the <code class="highlighter-rouge">Result2</code> class we created in Step 3 so that it also stores the mean and variance of the days employed. I also added two additional <code class="highlighter-rouge">double</code> values to store the covariance and correlation. The covariance is only needed to compute the correlation, so I excluded it from the JSON with the <code class="highlighter-rouge">@JsonIgnore</code>-annotation.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Data</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">Result2</span> <span class="o">{</span>
<span class="nd">@JsonIgnore</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="kt">long</span> <span class="n">ref</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="kt">long</span> <span class="n">count</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="kt">double</span> <span class="n">salaryMean</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="kt">double</span> <span class="n">daysEmployedMean</span><span class="o">;</span>
<span class="kd">private</span> <span class="kt">double</span> <span class="n">salaryVariance</span><span class="o">;</span>
<span class="kd">private</span> <span class="kt">double</span> <span class="n">daysEmployedVariance</span><span class="o">;</span>
<span class="nd">@JsonIgnore</span>
<span class="kd">private</span> <span class="kt">double</span> <span class="n">covariance</span><span class="o">;</span>
<span class="kd">private</span> <span class="kt">double</span> <span class="n">correlation</span><span class="o">;</span>
<span class="n">Result2</span><span class="o">(</span><span class="n">Result</span> <span class="n">firstPass</span><span class="o">)</span> <span class="o">{</span>
<span class="n">ref</span> <span class="o">=</span> <span class="n">firstPass</span><span class="o">.</span><span class="na">ref</span><span class="o">;</span>
<span class="n">count</span> <span class="o">=</span> <span class="n">firstPass</span><span class="o">.</span><span class="na">count</span><span class="o">;</span>
<span class="n">salaryMean</span> <span class="o">=</span> <span class="n">firstPass</span><span class="o">.</span><span class="na">salaryMean</span><span class="o">;</span>
<span class="n">daysEmployedMean</span> <span class="o">=</span> <span class="n">firstPass</span><span class="o">.</span><span class="na">daysEmployedMean</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>For the <code class="highlighter-rouge">get()</code>-method, I begun by modifying the <code class="highlighter-rouge">Aggregator</code> so that it also computes the mean days of employment in the first pass. The actual computation will be done using the static variable <code class="highlighter-rouge">DAYS_EMPLOYED</code> defined earlier.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@GetMapping</span>
<span class="n">Map</span><span class="o"><</span><span class="n">Salary</span><span class="o">.</span><span class="na">Gender</span><span class="o">,</span> <span class="n">Result2</span><span class="o">></span> <span class="nf">get</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">EntityStore</span><span class="o"><</span><span class="n">Salary</span><span class="o">></span> <span class="n">store</span> <span class="o">=</span> <span class="n">entityStore</span><span class="o">();</span>
<span class="kd">final</span> <span class="n">Aggregator</span><span class="o"><</span><span class="n">Result</span><span class="o">></span> <span class="n">agg</span> <span class="o">=</span> <span class="n">Aggregator</span><span class="o">.</span><span class="na">builder</span><span class="o">(</span><span class="n">store</span><span class="o">,</span> <span class="nl">Result:</span><span class="o">:</span><span class="k">new</span><span class="o">)</span>
<span class="o">.</span><span class="na">withEnumKey</span><span class="o">(</span><span class="n">Salary</span><span class="o">.</span><span class="na">GENDER</span><span class="o">)</span>
<span class="o">.</span><span class="na">withCount</span><span class="o">(</span><span class="nl">Result:</span><span class="o">:</span><span class="n">setCount</span><span class="o">)</span>
<span class="o">.</span><span class="na">withAverage</span><span class="o">(</span><span class="n">Salary</span><span class="o">.</span><span class="na">SALARY</span><span class="o">,</span> <span class="nl">Result:</span><span class="o">:</span><span class="n">setSalaryMean</span><span class="o">)</span>
<span class="o">.</span><span class="na">withAverage</span><span class="o">(</span><span class="n">DAYS_EMPLOYED</span><span class="o">,</span> <span class="nl">Result:</span><span class="o">:</span><span class="n">setDaysEmployedMean</span><span class="o">)</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
<span class="o">...</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The next thing to do is to modify is the second pass aggregation performed inside the <code class="highlighter-rouge">.flatMap()</code>. In addition to computing the variance of the salary and days of employment, I also need to compute the covariance in this step. I need this value later to compute the correlation coefficient.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">.</span><span class="na">flatMap</span><span class="o">(</span><span class="n">previous</span> <span class="o">-></span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">Salary</span><span class="o">.</span><span class="na">Gender</span> <span class="n">gender</span> <span class="o">=</span>
<span class="n">store</span><span class="o">.</span><span class="na">deserializeAny</span><span class="o">(</span><span class="n">previous</span><span class="o">.</span><span class="na">ref</span><span class="o">,</span> <span class="n">Salary</span><span class="o">.</span><span class="na">GENDER</span><span class="o">);</span>
<span class="k">return</span> <span class="n">Aggregator</span><span class="o">.</span><span class="na">builder</span><span class="o">(</span><span class="n">store</span><span class="o">,</span> <span class="n">ref</span> <span class="o">-></span> <span class="k">new</span> <span class="n">Result2</span><span class="o">(</span><span class="n">previous</span><span class="o">))</span>
<span class="o">.</span><span class="na">withEnumKey</span><span class="o">(</span><span class="n">Salary</span><span class="o">.</span><span class="na">GENDER</span><span class="o">)</span>
<span class="o">.</span><span class="na">withVariance</span><span class="o">(</span>
<span class="n">Salary</span><span class="o">.</span><span class="na">SALARY</span><span class="o">,</span>
<span class="n">previous</span><span class="o">.</span><span class="na">salaryMean</span><span class="o">,</span>
<span class="nl">Result2:</span><span class="o">:</span><span class="n">setSalaryVariance</span><span class="o">)</span>
<span class="o">.</span><span class="na">withVariance</span><span class="o">(</span>
<span class="n">DAYS_EMPLOYED</span><span class="o">,</span>
<span class="n">previous</span><span class="o">.</span><span class="na">daysEmployedMean</span><span class="o">,</span>
<span class="nl">Result2:</span><span class="o">:</span><span class="n">setDaysEmployedVariance</span><span class="o">)</span>
<span class="o">.</span><span class="na">withAverage</span><span class="o">(</span><span class="n">covariance</span><span class="o">(</span>
<span class="n">previous</span><span class="o">.</span><span class="na">salaryMean</span><span class="o">,</span>
<span class="n">previous</span><span class="o">.</span><span class="na">daysEmployedMean</span>
<span class="o">),</span> <span class="nl">Result2:</span><span class="o">:</span><span class="n">setCovariance</span><span class="o">)</span>
<span class="o">.</span><span class="na">build</span><span class="o">()</span>
<span class="o">.</span><span class="na">aggregate</span><span class="o">(</span><span class="n">genderFieldCache</span><span class="o">().</span><span class="na">equal</span><span class="o">(</span>
<span class="n">gender</span><span class="o">,</span> <span class="n">Order</span><span class="o">.</span><span class="na">ASC</span><span class="o">,</span> <span class="mi">0</span><span class="o">,</span> <span class="n">Long</span><span class="o">.</span><span class="na">MAX_VALUE</span><span class="o">)</span>
<span class="o">);</span>
<span class="o">}</span>
<span class="o">)</span>
</code></pre></div></div>
<p>The third operation is a new one. It uses a utility method called <code class="highlighter-rouge">covariance(double, double)</code> that is not defined yet to compute the covariance with two precalculated means. It is implemented like this.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="n">DeserializeDouble</span><span class="o"><</span><span class="n">Salary</span><span class="o">></span> <span class="nf">covariance</span><span class="o">(</span>
<span class="kt">double</span> <span class="n">salaryMean</span><span class="o">,</span>
<span class="kt">double</span> <span class="n">daysEmployedMean</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="nf">multiply</span><span class="o">(</span>
<span class="n">minus</span><span class="o">(</span>
<span class="n">getAsDouble</span><span class="o">(</span><span class="n">Salary</span><span class="o">.</span><span class="na">SALARY</span><span class="o">),</span>
<span class="n">constant</span><span class="o">(</span><span class="n">salaryMean</span><span class="o">)</span>
<span class="o">),</span>
<span class="n">minus</span><span class="o">(</span>
<span class="n">DAYS_EMPLOYED</span><span class="o">,</span>
<span class="n">constant</span><span class="o">(</span><span class="n">daysEmployedMean</span><span class="o">)</span>
<span class="o">)</span>
<span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>This is a good example of how the small building blocks of the <code class="highlighter-rouge">Aggregators</code>-class can be combined to create powerful statistics.</p>
<p>The final thing I need to add to the <code class="highlighter-rouge">get()</code>-method is to compute the correlation once the result stream is produced. I can do this with a regular <code class="highlighter-rouge">Stream.map()</code>-operation.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="n">result</span> <span class="o">-></span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">salaryVariance</span> <span class="o">==</span> <span class="mi">0</span>
<span class="o">||</span> <span class="n">result</span><span class="o">.</span><span class="na">daysEmployedVariance</span> <span class="o">==</span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
<span class="n">result</span><span class="o">.</span><span class="na">setCorrelation</span><span class="o">(</span><span class="n">Double</span><span class="o">.</span><span class="na">NaN</span><span class="o">);</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
<span class="n">result</span><span class="o">.</span><span class="na">setCorrelation</span><span class="o">(</span>
<span class="n">result</span><span class="o">.</span><span class="na">covariance</span> <span class="o">/</span> <span class="o">(</span>
<span class="n">Math</span><span class="o">.</span><span class="na">sqrt</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">salaryVariance</span><span class="o">)</span> <span class="o">*</span>
<span class="n">Math</span><span class="o">.</span><span class="na">sqrt</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">daysEmployedVariance</span><span class="o">)</span>
<span class="o">)</span>
<span class="o">);</span>
<span class="o">}</span>
<span class="k">return</span> <span class="n">result</span><span class="o">;</span>
<span class="o">})</span>
</code></pre></div></div>
<p>All the values have now been set, so the collecting should work just as before. Rerunning the application and querying <code class="highlighter-rouge">/salary/correlation</code>, I now see this:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"M"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">1706321</span><span class="p">,</span><span class="w">
</span><span class="s2">"salaryMean"</span><span class="p">:</span><span class="w"> </span><span class="mi">63838</span><span class="p">,</span><span class="w">
</span><span class="s2">"daysEmployedMean"</span><span class="p">:</span><span class="w"> </span><span class="mf">2562.9950696092446</span><span class="p">,</span><span class="w">
</span><span class="s2">"salaryVariance"</span><span class="p">:</span><span class="w"> </span><span class="mf">287120292.49482954</span><span class="p">,</span><span class="w">
</span><span class="s2">"daysEmployedVariance"</span><span class="p">:</span><span class="w"> </span><span class="mf">2521092.66062704</span><span class="p">,</span><span class="w">
</span><span class="s2">"correlation"</span><span class="p">:</span><span class="w"> </span><span class="mf">0.38346220360987127</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="s2">"F"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">1137726</span><span class="p">,</span><span class="w">
</span><span class="s2">"salaryMean"</span><span class="p">:</span><span class="w"> </span><span class="mi">63769</span><span class="p">,</span><span class="w">
</span><span class="s2">"daysEmployedMean"</span><span class="p">:</span><span class="w"> </span><span class="mf">2562.467887479722</span><span class="p">,</span><span class="w">
</span><span class="s2">"salaryVariance"</span><span class="p">:</span><span class="w"> </span><span class="mf">283750106.3594864</span><span class="p">,</span><span class="w">
</span><span class="s2">"daysEmployedVariance"</span><span class="p">:</span><span class="w"> </span><span class="mf">2515737.630249606</span><span class="p">,</span><span class="w">
</span><span class="s2">"correlation"</span><span class="p">:</span><span class="w"> </span><span class="mf">0.3829530560640214</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>As you can see, there is a positive trend that the salary of both groups seems to be correlating with the number of days employed. The correlation is still quite weak since the Employees-database is a generated database, so feel free to try it yourself on your own numbers!</p>
<h2 id="summary">Summary</h2>
<p>Over the course of this article, you have learned how to do in-memory off-heap aggregations on a relational database using <a href="https://github.com/speedment/speedment">Speedment</a>. I have shown you how to compute the mean and variance of a column, compute the mean and variance of an expression over two columns and also how to compute Pearson’s correlation coefficient between the two.</p>
<p>All the sources for this article <a href="https://github.com/speedment/speedment-code-samples/tree/master/enterprise/advanced-aggregator-example">can be found here</a>. You can get a free trial of Speedment Enterprise using <a href="https://speedment.com/initializer">the Initializer on the Speedment website</a> if you want to try it out yourself.</p>
<p>Until next time, keep coding!</p>
<p><a href="http://ageofjava.com/java/Super-Fast-Statistical-Queries">Super-Fast Statistical Queries in Java</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on January 19, 2018.</p>http://ageofjava.com/java/Bridging-the-Gap2017-10-16T00:00:00-07:002017-10-16T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>Do you also like the Stream Interface? What if you could use Streams to query databases without having to write any SQL?</p>
<p>Speedment is an open source implementation of the <code class="highlighter-rouge">Stream</code>-interface that lazily evaluates the operations performed on it to produce an optimal SQL query, fetching only the results needed for the terminating operation. Speedment also comes with a handy maven plugin that generates all the entity and manager classes needed to model the database using the database metadata as the domain. This means that you can get a database application up and running in no time.</p>
<p>In this video, me and Per Minborg demonstrates the database streams using JShell, the new REPL loop that comes with Java 9. We also explain how the Speedment implementation can optimize the streams before execution and why this is legal according to the Stream documentation. At the end of the video you have all the tools you need to quickly write Java 9-ready database applications using Streams instead of SQL.</p>
<p>Speedment is open-source and can be <a href="https://github.com/speedment/speedment">downloaded from GitHub</a>.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/89lVMmIr8MQ" frameborder="0" allowfullscreen=""></iframe>
<p><a href="http://ageofjava.com/java/Bridging-the-Gap">Bridging the Gap Between Database and Stream (Webinar)</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on October 16, 2017.</p>http://ageofjava.com/java/Aggregate-Millions-Of-Rows-In-Spring2017-09-15T00:00:00-07:002017-09-15T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>The <a href="https://spring.io/">Spring Framework</a> makes it really easy to quickly setup a RESTful API to a relational database using JPA and Spring Web, as long as the API matches the structure of the database. In many APIs however, the REST-endpoint doesn’t correspond to a particular table but rather an aggregate of the fields. In those cases you still need to write your own REST Controllers, but if the database has millions of rows, then those aggregates might take some time to compute.</p>
<p><img src="https://lh5.googleusercontent.com/gtMR6zjtD0CvzduKQoWCY7yXhNZX7ECseCweVsr9_8bMwPr6OfNLLgzDgIrZXilEs3y-yxzF_IbJGc7CCCYxJB4Wqe1kFBjylFCUmf9jCpUvuZ4wTPCCd_Ljow8TlM1Ds11LgkS0" alt="Spire and Duke driving a Formula 1 Car" /></p>
<p>In this article I will show you how to write a very efficient REST Controller representing a JSON aggregate by using the json-stream plugin in Speedment Enterprise to quickly aggregate large JSON sequences without materializing them on the heap. The demo uses the Enterprise Edition of Speedment, for which you can get a free trial using <a href="https://speedment.com/initializer">the Initializer on the Speedment Website</a>.</p>
<h3 id="background">Background</h3>
<p><a href="https://speedment.com">Speedment</a> is an open source stream-oriented ORM for Java that generates entity and manager classes using a relational database as the source-of-truth. The data is then queried using standard Java 8 streams, without a single line of SQL.</p>
<p>Speedment Enterprise adds a highly efficient in-JVM-memory datastore to this ORM. Instead of translating the streams to SQL, the streams can be executed natively on the in-memory model. To avoid garbage collection limitations, entities are stored in DirectBuffers outside the main heap. Only the columns used in the stream need to be materialized on the heap and most predicates can be short-circuited without iterating over the entire set.</p>
<p><code class="highlighter-rouge">json-stream</code> is an official plugin for Speedment Enterprise that makes it possible to aggregate Speedment streams as JSON objects in a very efficient manner. It is different from, for an example, Jackson and Gson in that it knows the internal storage layout used in Speedment Enterprise and therefore doesn’t need to materialize the entities to aggregate them into JSON.</p>
<h3 id="introduction">Introduction</h3>
<p>In this article I am using an example database called Employees designed for MySQL to illustrate a common aggregation problem. A company keeps records on the salary of each employee going back to 1985. They want to be able to select a time period and see what the average salary was during that time, based on the criteria specified by the user.</p>
<p>Using regular SQL, we can express it like this:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mysql> <span class="k">select </span>count<span class="o">(</span>emp_no<span class="o">)</span>,min<span class="o">(</span>from_date<span class="o">)</span>,max<span class="o">(</span>to_date<span class="o">)</span>,avg<span class="o">(</span>salary<span class="o">)</span>
from salaries where from_date < <span class="s1">'1989-01-01'</span>
and to_date <span class="o">>=</span> <span class="s1">'1988-01-01'</span><span class="p">;</span>
+---------------+----------------+--------------+-------------+
| count<span class="o">(</span>emp_no<span class="o">)</span> | min<span class="o">(</span>from_date<span class="o">)</span> | max<span class="o">(</span>to_date<span class="o">)</span> | avg<span class="o">(</span>salary<span class="o">)</span> |
+---------------+----------------+--------------+-------------+
| 133923 | 1987-01-01 | 1989-12-31 | 55477.8502 |
+---------------+----------------+--------------+-------------+
1 row <span class="k">in </span><span class="nb">set</span> <span class="o">(</span>0.66 sec<span class="o">)</span>
</code></pre></div></div>
<p>If we want to create a simple REST service in Spring that performs this calculation and returns it as a JSON Object, we could do the following:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@GetMapping</span>
<span class="n">Result</span> <span class="nf">getEmployeeSalaries</span><span class="o">(</span><span class="nd">@RequestParam</span> <span class="n">String</span> <span class="n">from</span><span class="o">,</span>
<span class="nd">@RequestParam</span> <span class="n">String</span> <span class="n">to</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">template</span><span class="o">.</span><span class="na">queryForObject</span><span class="o">(</span>
<span class="s">"select count(emp_no),min(from_date),max(to_date),avg(salary) "</span> <span class="o">+</span>
<span class="s">"from salaries where from_date < ? and to_date >= ?;"</span><span class="o">,</span>
<span class="o">(</span><span class="n">rs</span><span class="o">,</span> <span class="n">n</span><span class="o">)</span> <span class="o">-></span> <span class="k">new</span> <span class="n">Result</span><span class="o">(</span><span class="n">rs</span><span class="o">),</span>
<span class="n">to</span><span class="o">,</span> <span class="n">from</span>
<span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The Result-class is defined like this (using <a href="https://projectlombok.org/">Project Lombok</a> to reduce boilerplate):</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Data</span>
<span class="kd">static</span> <span class="kd">class</span> <span class="nc">Result</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="kt">long</span> <span class="n">count</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">from</span><span class="o">,</span> <span class="n">to</span><span class="o">,</span> <span class="n">average</span><span class="o">;</span>
<span class="n">Result</span><span class="o">(</span><span class="n">ResultSet</span> <span class="n">rs</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">SQLException</span> <span class="o">{</span>
<span class="n">count</span> <span class="o">=</span> <span class="n">rs</span><span class="o">.</span><span class="na">getLong</span><span class="o">(</span><span class="mi">1</span><span class="o">);</span>
<span class="n">from</span> <span class="o">=</span> <span class="n">rs</span><span class="o">.</span><span class="na">getString</span><span class="o">(</span><span class="mi">2</span><span class="o">);</span>
<span class="n">to</span> <span class="o">=</span> <span class="n">rs</span><span class="o">.</span><span class="na">getString</span><span class="o">(</span><span class="mi">3</span><span class="o">);</span>
<span class="n">average</span> <span class="o">=</span> <span class="n">Utils</span><span class="o">.</span><span class="na">CASH</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="n">rs</span><span class="o">.</span><span class="na">getDouble</span><span class="o">(</span><span class="mi">4</span><span class="o">));</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>If we now point the browser to <code class="highlighter-rouge">/jdbc?from=1988-01-01&to=1989-01-01</code>, we will see the aggregated result:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">133923</span><span class="p">,</span><span class="w">
</span><span class="s2">"from"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1987-01-01"</span><span class="p">,</span><span class="w">
</span><span class="s2">"to"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1989-12-31"</span><span class="p">,</span><span class="w">
</span><span class="s2">"average"</span><span class="p">:</span><span class="w"> </span><span class="s2">"$55,477.85"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>However, the performance is far from the best. This simple service takes about 700 ms to produce the aggregate.</p>
<p><img src="https://lh4.googleusercontent.com/Zu2Uw2b0z-3A_c9QE9oIGdVRH9BsFDqBhIVjaLzPAgzDhBq41_Egh58ZVkUXv8ob6XdpCc3o0T45rr24PHyFk3GbsDHLn-_Xs-cXG0mjXdarEhURix7L-L9Lnjjily00E6q51Hyk" alt="Performance measure before using Speedment to aggregate JSON" /></p>
<p>Of course, we could cache the most common queries on the server, but it would still take us time to calculate results that has never been requested. Instead, let’s try to rewrite the same service but with Speedment.</p>
<h3 id="step-1-configuration">Step 1: Configuration</h3>
<p>I have prepared a Speedment configuration file and put in the <code class="highlighter-rouge">/src/main/json</code> folder in my project. I can then call mvn speedment:generate to generate all necessary entities and managers.</p>
<p>Next, we need to configure the Speedment application. To do this, I created a file called <code class="highlighter-rouge">SpeedmentConfig.java</code> like this:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Configuration</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SpeedmentConfig</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">Environment</span> <span class="n">env</span><span class="o">;</span>
<span class="n">SpeedmentConfig</span><span class="o">(</span><span class="n">Environment</span> <span class="n">env</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">env</span> <span class="o">=</span> <span class="n">requireNonNull</span><span class="o">(</span><span class="n">env</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Bean</span><span class="o">(</span><span class="n">destroyMethod</span> <span class="o">=</span> <span class="s">"stop"</span><span class="o">)</span>
<span class="n">EmployeesApplication</span> <span class="nf">getApplication</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">EmployeesApplicationBuilder</span><span class="o">()</span>
<span class="o">.</span><span class="na">withConnectionUrl</span><span class="o">(</span><span class="n">env</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">"spring.datasource.url"</span><span class="o">))</span>
<span class="o">.</span><span class="na">withUsername</span><span class="o">(</span><span class="n">env</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">"spring.datasource.username"</span><span class="o">))</span>
<span class="o">.</span><span class="na">withPassword</span><span class="o">(</span><span class="n">env</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">"spring.datasource.password"</span><span class="o">))</span>
<span class="o">.</span><span class="na">withBundle</span><span class="o">(</span><span class="n">DataStoreBundle</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
<span class="o">.</span><span class="na">withBundle</span><span class="o">(</span><span class="n">JsonBundle</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">...</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The username and password is set in the Spring <code class="highlighter-rouge">application.properties</code>-file. I still need to define 3 additional beans, however. We need a <code class="highlighter-rouge">Manager</code> so that I can query the Salaries-table, a <code class="highlighter-rouge">DataStoreComponent</code> that allows us to initialize the Speedment <code class="highlighter-rouge">DataStoreComponent</code> and a <code class="highlighter-rouge">JsonComponent</code> so that we can setup custom JSON aggregators.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Bean</span>
<span class="n">DataStoreComponent</span> <span class="nf">getDataStoreComponent</span><span class="o">(</span><span class="n">EmployeesApplication</span> <span class="n">app</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">app</span><span class="o">.</span><span class="na">getOrThrow</span><span class="o">(</span><span class="n">DataStoreComponent</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Bean</span>
<span class="n">JsonComponent</span> <span class="nf">getJsonComponent</span><span class="o">(</span><span class="n">EmployeesApplication</span> <span class="n">app</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">app</span><span class="o">.</span><span class="na">getOrThrow</span><span class="o">(</span><span class="n">JsonComponent</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Bean</span>
<span class="n">SalaryManager</span> <span class="nf">getSalaryManager</span><span class="o">(</span><span class="n">EmployeesApplication</span> <span class="n">app</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">app</span><span class="o">.</span><span class="na">getOrThrow</span><span class="o">(</span><span class="n">SalaryManager</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>We have now integrated Speedment with Spring!</p>
<h3 id="step-2-controller-class">Step 2: Controller Class</h3>
<p>Let’s take a look at the <code class="highlighter-rouge">Controller</code>-class. First, we need to make these three beans accessible in the controller by autowiring them. I prefer to have all my member variables <code class="highlighter-rouge">final</code>, so I will use Project Lombok to generate an all-argument constructor.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@RestController</span>
<span class="nd">@AllArgsConstructor</span>
<span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">"/speedment"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SpeedmentController</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">SalaryManager</span> <span class="n">salaries</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">DataStoreComponent</span> <span class="n">datastore</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">JsonComponent</span> <span class="n">json</span><span class="o">;</span>
<span class="o">...</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Next, we need to tell Spring to populate the in-memory store as soon as the beans have been initialized. We can do this with the <code class="highlighter-rouge">@PostConstruct</code>-annotation.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@PostConstruct</span>
<span class="kt">void</span> <span class="nf">loadInitialState</span><span class="o">()</span> <span class="o">{</span>
<span class="n">datastore</span><span class="o">.</span><span class="na">load</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The controller logic is pretty much the same as earlier, except that we will use a Java 8 Stream to query the database instead of a SQL String. The big advantage of this is that we can add more criterias to the service later on with very little modifications to the code. Filtering the stream is as simple as adding a <code class="highlighter-rouge">.filter()</code> operation.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@GetMapping</span>
<span class="n">String</span> <span class="nf">getEmployeeSalaries</span><span class="o">(</span><span class="nd">@RequestParam</span> <span class="n">String</span> <span class="n">from</span><span class="o">,</span>
<span class="nd">@RequestParam</span> <span class="n">String</span> <span class="n">to</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">salaries</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">Salary</span><span class="o">.</span><span class="na">FROM_DATE</span><span class="o">.</span><span class="na">lessThan</span><span class="o">(</span><span class="n">Utils</span><span class="o">.</span><span class="na">toEpochSecond</span><span class="o">(</span><span class="n">to</span><span class="o">)))</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">Salary</span><span class="o">.</span><span class="na">TO_DATE</span><span class="o">.</span><span class="na">greaterOrEqual</span><span class="o">(</span><span class="n">Utils</span><span class="o">.</span><span class="na">toEpochSecond</span><span class="o">(</span><span class="n">from</span><span class="o">)))</span>
<span class="o">.</span><span class="na">collect</span><span class="o">(</span>
<span class="n">json</span><span class="o">.</span><span class="na">collector</span><span class="o">(</span><span class="n">Salary</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
<span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"count"</span><span class="o">,</span> <span class="n">count</span><span class="o">())</span>
<span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"from"</span><span class="o">,</span> <span class="n">min</span><span class="o">(</span><span class="n">Salary</span><span class="o">.</span><span class="na">FROM_DATE</span><span class="o">,</span> <span class="nl">Utils:</span><span class="o">:</span><span class="n">fromEpochSecond</span><span class="o">))</span>
<span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"to"</span><span class="o">,</span> <span class="n">max</span><span class="o">(</span><span class="n">Salary</span><span class="o">.</span><span class="na">TO_DATE</span><span class="o">,</span> <span class="nl">Utils:</span><span class="o">:</span><span class="n">fromEpochSecond</span><span class="o">))</span>
<span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"average"</span><span class="o">,</span> <span class="n">average</span><span class="o">(</span><span class="n">Salary</span><span class="o">.</span><span class="na">SALARY</span><span class="o">,</span> <span class="nl">Utils:</span><span class="o">:</span><span class="n">toCurrency</span><span class="o">))</span>
<span class="o">.</span><span class="na">build</span><span class="o">()</span>
<span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>(I have mapped the dates to epoch second integers in Speedment for performance reasons. That is why you see <code class="highlighter-rouge">Utils.toEpochSecond</code> and <code class="highlighter-rouge">Utils.fromEpochSecond</code> in the logic above).</p>
<h3 id="step-3-re-deploy">Step 3: Re-deploy</h3>
<p>If we rerun the service, we can see that the endpoint still works just as before:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">133923</span><span class="p">,</span><span class="w">
</span><span class="s2">"from"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1987-01-01"</span><span class="p">,</span><span class="w">
</span><span class="s2">"to"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1989-12-31"</span><span class="p">,</span><span class="w">
</span><span class="s2">"average"</span><span class="p">:</span><span class="w"> </span><span class="s2">"$55,477.85"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>The difference is that the request is 60 times faster. Imagine what a speedup factor of 60 would do to your existing applications: For example, instead of a 10 second delay you get a delay of less than 200 ms which is hardly noticeable by end-users.</p>
<p><img src="https://lh4.googleusercontent.com/_AolX-RHN5roZfFSSEnpg320eE93noOFTR_0edrRxKtBzC_WCgkRHomXB4YcJK8XTeJQxvIUXwuGd52-dBKyj1EzzjcBuzj0FNbQIg6TqMLxf_ygfxXInlY0LCrgxsWBSZ7jzHAm" alt="Performance measure after using Speedment to aggregate JSON" /></p>
<h3 id="conclusion">Conclusion</h3>
<p>JSON aggregation of relational data in Spring can be done very efficiently using Speedment Enterprise with the datastore and json-stream plugins. It fits nicely with other Spring components and is very easy to setup.</p>
<p>If you want to try this example for yourself, you can download it <a href="https://github.com/speedment/speedment-code-samples/tree/master/enterprise/aggregate-json-example">from this GitHub page</a>. You can get a free trial of Speedment Enterprise on <a href="https://speedment.com/initializer">the Speedment website</a>.</p>
<p><a href="http://ageofjava.com/java/Aggregate-Millions-Of-Rows-In-Spring">Aggregate Millions of Database Rows in a Spring Controller</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on September 15, 2017.</p>http://ageofjava.com/java/Secure-REST-API-with-Spring2017-03-20T00:00:00-07:002017-03-20T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>As you all know, <a href="https://projects.spring.io/spring-boot/">Spring Boot</a> is a toolkit that makes it super easy to quickly develop powerful web services. It is very modular and made to play well with other frameworks and tools. In this tutorial I am going to show you how easy it is to set up a RESTful API towards an existing SQL database by using Speedment as the ORM.</p>
<p><img src="https://lh5.googleusercontent.com/gRYzRnk7N0J93gWeWpgPeS_UKsODvOJEdjn_CzYHstScaaJLUjmXfh0ANJh2HOSbCpZvCwRixh6lQwcb2CkIxhO0AQabM0JxS2w7Ho4HMyqlXy-kOQhBDibNjS4HbCShhNLO8H4F" alt="Happy Spring Wishes from Spire and Crew" /></p>
<h3 id="background">Background</h3>
<p><a href="https://github.com/speedment/speedment">Speedment is an open-source toolkit</a> that connects to a database, analyzes the metadata and uses it to generate entity- and managers classes to model the database in an object-oriented fashion. It also contains a runtime library that turns Java 8 Streams into optimized SQL queries, allowing you to write your code in a very type-safe and modern way. As it turns out, this is perfect for a Spring Application.</p>
<h3 id="goal-of-this-tutorial">Goal of This Tutorial</h3>
<p>The goal of this tutorial is to develop a REST API with Spring that grants access to different endpoints depending on the role of the user. If you want to look ahead, you can find <a href="https://github.com/Pyknic/speedment-secure-rest-example">all the sources from the guide here</a>.</p>
<table>
<tbody>
<tr>
<td><code class="highlighter-rouge">POST /account</code></td>
<td>Accessible by anyone</td>
</tr>
<tr>
<td><code class="highlighter-rouge">GET /account/{id}</code></td>
<td>Accessible by admins, as well as the user in question</td>
</tr>
<tr>
<td><code class="highlighter-rouge">GET /account</code></td>
<td>Lists all accounts and is only accessible by admins</td>
</tr>
</tbody>
</table>
<p>Authentication will be made using a MySQL database that we will query using standard Java 8 Streams. In the end, we will have a fully object-oriented solution ready to be expanded with custom business logic!</p>
<p>If you would like to follow along with the finished project, you can clone it at GitHub.</p>
<h3 id="step-1-the-database">Step 1: The Database</h3>
<p>For the sake of simplicity, I am using a custom MySQL database that I created using the following statement. The idea is however that you can use any existing database that you happen to have access to.</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">create</span> <span class="k">database</span> <span class="nv">`securerest`</span><span class="p">;</span>
<span class="n">use</span> <span class="nv">`securerest`</span><span class="p">;</span>
<span class="k">create</span> <span class="k">table</span> <span class="nv">`account`</span> <span class="p">(</span>
<span class="nv">`id`</span> <span class="n">bigint</span> <span class="k">not</span> <span class="k">null</span> <span class="n">auto_increment</span> <span class="k">primary</span> <span class="k">key</span><span class="p">,</span>
<span class="nv">`username`</span> <span class="n">varchar</span><span class="p">(</span><span class="mi">30</span><span class="p">)</span> <span class="k">not</span> <span class="k">null</span> <span class="k">unique</span><span class="p">,</span>
<span class="nv">`password`</span> <span class="n">char</span><span class="p">(</span><span class="mi">60</span><span class="p">)</span> <span class="k">not</span> <span class="k">null</span><span class="p">,</span>
<span class="nv">`role`</span> <span class="n">enum</span><span class="p">(</span><span class="s1">'USER'</span><span class="p">,</span> <span class="s1">'ADMIN'</span><span class="p">)</span> <span class="k">not</span> <span class="k">null</span>
<span class="p">);</span>
</code></pre></div></div>
<h3 id="step-2-create-the-maven-project">Step 2: Create the Maven Project</h3>
<p>To quickly get up a new Spring Project, I recommend the awesome <a href="http://start.spring.io/">Spring Initializr</a> website. There you can easily enter the dependencies you need for your project.</p>
<p>We need the following Spring dependencies:</p>
<ul>
<li>spring-boot-starter-security</li>
<li>spring-boot-starter-web</li>
<li>mysql-connector-java</li>
</ul>
<p>Secondly, we also need to add the Speedment dependency as well as the Speedment plugin to generate our code.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>runtime<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><type></span>pom<span class="nt"></type></span>
<span class="nt"></dependency></span>
...
<span class="nt"><plugin></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>speedment-maven-plugin<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>mysql<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>mysql-connector-java<span class="nt"></artifactId></span>
<span class="nt"><version></span>${mysql.version}<span class="nt"></version></span>
<span class="nt"><scope></span>runtime<span class="nt"></scope></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
<span class="nt"></plugin></span>
</code></pre></div></div>
<h3 id="step-3-generate-domain-model">Step 3: Generate Domain Model</h3>
<p>With the plugin added, we can run the following Maven Goal to launch the Speedment UI.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn speedment:tool
</code></pre></div></div>
<p><img src="https://lh5.googleusercontent.com/TCUkpc71xpM8kA86yt-1ElT19LzFxhADTMkUFfg4fEXtT3Z4LP56dwf1vN8KhJqcqzTmz4j4sSgHtxYPhYlqHoaaVzQ62y2Gl-sjIrzkr6NXvzidwBRrKqyNs-AUoMNd5rQc8h-N" alt="Connect to Database using Speedment" /></p>
<p>This will open up the Speedment Tool. It will ask you for the username, password, schema name, etc. for your database. Enter values for the fields and press “Connect”.</p>
<p><img src="https://lh6.googleusercontent.com/iAAgVtgT_0xe6Hek-coEzvs8YNb3Fn255j0tmYU4ip2X04C-3dngzlV9M7ssGKQ9BzQx3HlTWaURs3xscjmMGNOChRHOJfuvsmuXWVKDiEiFulZyJfos0WUV7iRPL3A0s1m_fyK-" alt="The main window in Speedment" /></p>
<p>Inside the UI there are many configurations you can do. You can specify the exact location of the generated code, disable tables or columns that are irrelevant for the application and create aliases if you want a field or table to appear as something else in the code.</p>
<p>For this tutorial, it is enough to press “Generate”. You should now see how a number of new java classes and packages are generated into your project!</p>
<h3 id="step-4-configure-spring-security">Step 4: Configure Spring Security</h3>
<p>To allow Spring to launch Speedment as a Spring Bean, we need to specify how the instance is created. To do this, we create a class named SpeedmentConfiguration.</p>
<h6 id="speedmentconfigurationjava">SpeedmentConfiguration.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Configuration</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SpeedmentConfiguration</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nd">@Value</span><span class="o">(</span><span class="s">"${dbms.host}"</span><span class="o">)</span> <span class="n">String</span> <span class="n">host</span><span class="o">;</span>
<span class="kd">private</span> <span class="nd">@Value</span><span class="o">(</span><span class="s">"${dbms.port}"</span><span class="o">)</span> <span class="kt">int</span> <span class="n">port</span><span class="o">;</span>
<span class="kd">private</span> <span class="nd">@Value</span><span class="o">(</span><span class="s">"${dbms.schema}"</span><span class="o">)</span> <span class="n">String</span> <span class="n">schema</span><span class="o">;</span>
<span class="kd">private</span> <span class="nd">@Value</span><span class="o">(</span><span class="s">"${dbms.username}"</span><span class="o">)</span> <span class="n">String</span> <span class="n">username</span><span class="o">;</span>
<span class="kd">private</span> <span class="nd">@Value</span><span class="o">(</span><span class="s">"${dbms.password}"</span><span class="o">)</span> <span class="n">String</span> <span class="n">password</span><span class="o">;</span>
<span class="nd">@Bean</span>
<span class="kd">public</span> <span class="n">SpeedmentApplication</span> <span class="nf">getSpeedmentApplication</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">SpeedmentApplicationBuilder</span><span class="o">()</span>
<span class="o">.</span><span class="na">withIpAddress</span><span class="o">(</span><span class="n">host</span><span class="o">)</span>
<span class="o">.</span><span class="na">withPort</span><span class="o">(</span><span class="n">port</span><span class="o">)</span>
<span class="o">.</span><span class="na">withUsername</span><span class="o">(</span><span class="n">username</span><span class="o">)</span>
<span class="o">.</span><span class="na">withPassword</span><span class="o">(</span><span class="n">password</span><span class="o">)</span>
<span class="o">.</span><span class="na">withSchema</span><span class="o">(</span><span class="n">schema</span><span class="o">)</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
<span class="o">}</span>
<span class="nd">@Bean</span>
<span class="kd">public</span> <span class="n">AccountManager</span> <span class="nf">getAccountManager</span><span class="o">(</span><span class="n">SpeedmentApplication</span> <span class="n">app</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">app</span><span class="o">.</span><span class="na">getOrThrow</span><span class="o">(</span><span class="n">AccountManager</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The <code class="highlighter-rouge">@Value</code> fields in the top are loaded by default from a file called <code class="highlighter-rouge">application.properties</code>. We should therefore specify the values there:</p>
<h6 id="applicationproperties">application.properties</h6>
<div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Speedment Settings
</span><span class="py">dbms.host</span><span class="p">=</span><span class="s">localhost</span>
<span class="py">dbms.port</span><span class="p">=</span><span class="s">3306</span>
<span class="py">dbms.schema</span><span class="p">=</span><span class="s">securerest</span>
<span class="py">dbms.username</span><span class="p">=</span><span class="s">root</span>
<span class="py">dbms.password</span><span class="p">=</span><span class="s">password</span>
<span class="c"># Server Settings
</span><span class="py">server.port</span><span class="p">=</span><span class="s">9777</span>
</code></pre></div></div>
<p>Next, we need to create a configuration class for the authentication of users. We call this class <code class="highlighter-rouge">AuthenticationConfiguration</code>.</p>
<h6 id="authenticationconfigurationjava">AuthenticationConfiguration.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Configuration</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">AuthenticationConfiguration</span>
<span class="kd">extends</span> <span class="n">GlobalAuthenticationConfigurerAdapter</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nd">@Autowired</span> <span class="n">AccountManager</span> <span class="n">accounts</span><span class="o">;</span>
<span class="nd">@Bean</span>
<span class="kd">public</span> <span class="n">DaoAuthenticationProvider</span> <span class="nf">authProvider</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">DaoAuthenticationProvider</span> <span class="n">authProvider</span> <span class="o">=</span>
<span class="k">new</span> <span class="nf">DaoAuthenticationProvider</span><span class="o">();</span>
<span class="n">authProvider</span><span class="o">.</span><span class="na">setUserDetailsService</span><span class="o">(</span><span class="n">getUserDetailsService</span><span class="o">());</span>
<span class="n">authProvider</span><span class="o">.</span><span class="na">setPasswordEncoder</span><span class="o">(</span><span class="n">getPasswordEncoder</span><span class="o">());</span>
<span class="k">return</span> <span class="n">authProvider</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Bean</span>
<span class="kd">public</span> <span class="n">UserDetailsService</span> <span class="nf">getUserDetailsService</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">username</span> <span class="o">-></span> <span class="n">accounts</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">Account</span><span class="o">.</span><span class="na">USERNAME</span><span class="o">.</span><span class="na">equal</span><span class="o">(</span><span class="n">username</span><span class="o">))</span>
<span class="o">.</span><span class="na">findAny</span><span class="o">()</span>
<span class="o">.</span><span class="na">orElseThrow</span><span class="o">(()</span> <span class="o">-></span> <span class="k">new</span> <span class="n">UsernameNotFoundException</span><span class="o">(</span>
<span class="s">"Could not find the user '"</span> <span class="o">+</span> <span class="n">username</span> <span class="o">+</span> <span class="s">"'"</span>
<span class="o">));</span>
<span class="o">}</span>
<span class="nd">@Bean</span>
<span class="kd">public</span> <span class="n">PasswordEncoder</span> <span class="nf">getPasswordEncoder</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">BCryptPasswordEncoder</span><span class="o">();</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">init</span><span class="o">(</span>
<span class="n">AuthenticationManagerBuilder</span> <span class="n">auth</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span>
<span class="n">auth</span><span class="o">.</span><span class="na">userDetailsService</span><span class="o">(</span><span class="n">getUserDetailsService</span><span class="o">())</span>
<span class="o">.</span><span class="na">passwordEncoder</span><span class="o">(</span><span class="n">getPasswordEncoder</span><span class="o">());</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Note how we can use <code class="highlighter-rouge">@Autowired</code> on the generated <code class="highlighter-rouge">AccountManager</code> since it is specified as a Spring Bean in the <code class="highlighter-rouge">SpeedmentConfiguration</code> class.</p>
<p>In the method <code class="highlighter-rouge">getUserDetailsService()</code>, we use the Stream API with a custom predicate, allowing the stream to be turned into an optimized SQL query. There is one thing we need to do to make this method work, however. We need to make sure the generated <code class="highlighter-rouge">Account</code> interface extends <code class="highlighter-rouge">UserDetails</code> so that it can be used seamlessly with the Spring API. This is easy to do, since Speedment doesn’t overwrite files that doesn’t begin with the prefix “Generated”.</p>
<h6 id="accountjava">Account.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Account</span> <span class="kd">extends</span> <span class="n">GeneratedAccount</span><span class="o">,</span> <span class="n">UserDetails</span> <span class="o">{</span>
<span class="o">}</span>
</code></pre></div></div>
<p>We also need to add a few methods to the implementation class to support the interface.</p>
<h6 id="accountimpljava">AccountImpl.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@JsonIgnoreProperties</span><span class="o">(</span><span class="s">"password"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">AccountImpl</span> <span class="kd">extends</span> <span class="n">GeneratedAccountImpl</span>
<span class="kd">implements</span> <span class="n">Account</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">long</span> <span class="n">serialVersionUID</span> <span class="o">=</span> <span class="o">-</span><span class="mi">7552975849070084309L</span><span class="o">;</span>
<span class="nd">@Override</span> <span class="nd">@JsonIgnore</span>
<span class="kd">public</span> <span class="n">Collection</span><span class="o"><?</span> <span class="kd">extends</span> <span class="n">GrantedAuthority</span><span class="o">></span> <span class="nf">getAuthorities</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="nf">createAuthorityList</span><span class="o">(</span><span class="n">getRole</span><span class="o">());</span>
<span class="o">}</span>
<span class="nd">@Override</span> <span class="nd">@JsonIgnore</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">isAccountNonExpired</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Override</span> <span class="nd">@JsonIgnore</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">isAccountNonLocked</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Override</span> <span class="nd">@JsonIgnore</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">isCredentialsNonExpired</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Override</span> <span class="nd">@JsonIgnore</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">isEnabled</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>We then create a third configuration file to define what authorities are required to access the various REST endpoints.</p>
<h6 id="securityconfigurationjava">SecurityConfiguration.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Configuration</span>
<span class="nd">@EnableWebSecurity</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SecurityConfiguration</span>
<span class="kd">extends</span> <span class="n">WebSecurityConfigurerAdapter</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">configure</span><span class="o">(</span><span class="n">HttpSecurity</span> <span class="n">http</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span>
<span class="n">http</span><span class="o">.</span><span class="na">authorizeRequests</span><span class="o">()</span>
<span class="o">.</span><span class="na">antMatchers</span><span class="o">(</span><span class="n">POST</span><span class="o">,</span> <span class="s">"/account"</span><span class="o">).</span><span class="na">permitAll</span><span class="o">()</span>
<span class="o">.</span><span class="na">antMatchers</span><span class="o">(</span><span class="n">GET</span><span class="o">,</span> <span class="s">"/account"</span><span class="o">).</span><span class="na">hasAuthority</span><span class="o">(</span><span class="s">"ROLE_ADMIN"</span><span class="o">)</span>
<span class="o">.</span><span class="na">anyRequest</span><span class="o">().</span><span class="na">fullyAuthenticated</span><span class="o">()</span>
<span class="o">.</span><span class="na">and</span><span class="o">().</span><span class="na">httpBasic</span><span class="o">()</span>
<span class="o">.</span><span class="na">and</span><span class="o">().</span><span class="na">csrf</span><span class="o">().</span><span class="na">disable</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h3 id="step-5-create-the-controller">Step 5: Create the Controller</h3>
<p>The final step is to create the Controller class where our business logic is located. The class is annotated with <code class="highlighter-rouge">@RestController</code> to allow Spring to pick it up automatically. It defines three mappings, one for each REST endpoint.</p>
<h6 id="accountcontrollerjava">AccountController.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@RestController</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">AccountController</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nd">@Autowired</span> <span class="n">AccountManager</span> <span class="n">accounts</span><span class="o">;</span>
<span class="kd">private</span> <span class="nd">@Autowired</span> <span class="n">PasswordEncoder</span> <span class="n">passwordEncoder</span><span class="o">;</span>
<span class="o">...</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The first endpoint is the registration command. It will be located on “POST /account”. We take two parameters, username and password, hash the password and then persist it to the database. The operation will fail if the username already exists since it is defined as <code class="highlighter-rouge">UNIQUE</code> in the database.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nd">@PostMapping</span><span class="o">(</span><span class="s">"/account"</span><span class="o">)</span>
<span class="kt">long</span> <span class="nf">onPostAccount</span><span class="o">(</span>
<span class="nd">@RequestParam</span><span class="o">(</span><span class="s">"username"</span><span class="o">)</span> <span class="n">String</span> <span class="n">username</span><span class="o">,</span>
<span class="nd">@RequestParam</span><span class="o">(</span><span class="s">"password"</span><span class="o">)</span> <span class="n">String</span> <span class="n">password</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">Account</span> <span class="n">created</span> <span class="o">=</span> <span class="n">accounts</span><span class="o">.</span><span class="na">persist</span><span class="o">(</span><span class="k">new</span> <span class="n">AccountImpl</span><span class="o">()</span>
<span class="o">.</span><span class="na">setUsername</span><span class="o">(</span><span class="n">username</span><span class="o">)</span>
<span class="o">.</span><span class="na">setPassword</span><span class="o">(</span><span class="n">passwordEncoder</span><span class="o">.</span><span class="na">encode</span><span class="o">(</span><span class="n">password</span><span class="o">))</span>
<span class="o">.</span><span class="na">setRole</span><span class="o">(</span><span class="s">"USER"</span><span class="o">)</span>
<span class="o">);</span>
<span class="k">return</span> <span class="n">created</span><span class="o">.</span><span class="na">getId</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Next up is the “GET /account” endpoint. It is quite simple. We will initiate a stream using the generated manager class. The stream is then optimized into a SQL query by Speedment.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nd">@GetMapping</span><span class="o">(</span><span class="s">"/account"</span><span class="o">)</span>
<span class="n">List</span><span class="o"><</span><span class="n">Account</span><span class="o">></span> <span class="nf">onGetAllAccounts</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">accounts</span><span class="o">.</span><span class="na">stream</span><span class="o">().</span><span class="na">collect</span><span class="o">(</span><span class="n">toList</span><span class="o">());</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The last endpoint is a bit more complicated. We have configured Spring to only allow logged in users to access “GET /account{id}”, but we want to make sure users can only access their own information unless they have the “ADMIN” role.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nd">@GetMapping</span><span class="o">(</span><span class="s">"/account/{id}"</span><span class="o">)</span>
<span class="n">Account</span> <span class="nf">onGetAccount</span><span class="o">(</span>
<span class="nd">@PathVariable</span><span class="o">(</span><span class="s">"id"</span><span class="o">)</span> <span class="kt">long</span> <span class="n">accountId</span><span class="o">,</span>
<span class="n">Authentication</span> <span class="n">auth</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">Account</span> <span class="n">account</span> <span class="o">=</span> <span class="o">(</span><span class="n">Account</span><span class="o">)</span> <span class="n">auth</span><span class="o">.</span><span class="na">getPrincipal</span><span class="o">();</span>
<span class="k">if</span> <span class="o">(</span><span class="n">account</span><span class="o">.</span><span class="na">getId</span><span class="o">()</span> <span class="o">==</span> <span class="n">accountId</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">account</span><span class="o">;</span>
<span class="o">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="s">"ADMIN"</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">account</span><span class="o">.</span><span class="na">getRole</span><span class="o">()))</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">accounts</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">Account</span><span class="o">.</span><span class="na">ID</span><span class="o">.</span><span class="na">equal</span><span class="o">(</span><span class="n">accountId</span><span class="o">))</span>
<span class="o">.</span><span class="na">findAny</span><span class="o">().</span><span class="na">orElseThrow</span><span class="o">(</span><span class="nl">NotFoundException:</span><span class="o">:</span><span class="k">new</span><span class="o">);</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">ForbiddenException</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Done! We now have a REST API that uses a database to store users and Basic Authentication to make sure users can only invoke the commands they have access to!</p>
<h3 id="trying-it-out">Trying It Out</h3>
<p>To try the REST API we just created, simply fire up a terminal and use the cURL command!</p>
<p>To register an account:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-X</span> POST <span class="s2">"http://localhost:9777/account
?username=my_user
&password=my_pass"</span>
</code></pre></div></div>
<p>To see our own information (in this case we are the user with ID 1):</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-X</span> GET <span class="nt">-u</span> my_user:my_pass <span class="s2">"http://localhost:9777/account/1"</span>
</code></pre></div></div>
<p>To list all users (requires ADMIN role):</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-X</span> GET <span class="nt">-u</span> my_user:my_pass <span class="s2">"http://localhost:9777/account"</span>
</code></pre></div></div>
<h3 id="summary">Summary</h3>
<p>In this tutorial we have created a new Spring Boot project to quickly map up a RESTful API with a simple registration system and used Speedment to generate an object-oriented database access layer for this API. We have also configured Spring Security to require users to authenticate themselves to access particular endpoints.</p>
<p>For more guides and tutorials on how to use Speedment, <a href="https://github.com/speedment/speedment">check out the GitHub page</a>! There you can also find some example projects on how to use more of the cool code-generation features available in Speedment!</p>
<p>The full sources for this tutorial <a href="https://github.com/Pyknic/speedment-secure-rest-example">can be found here</a>!</p>
<p>Until next time!</p>
<p><a href="http://ageofjava.com/java/Secure-REST-API-with-Spring">How to Set Up a Secure REST API with Spring</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on March 20, 2017.</p>http://ageofjava.com/java/Query-Databases-Using-Streams-Video2017-03-02T00:00:00-08:002017-03-02T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>Java 8 introduced a completely new way of working with data in Java with the <code class="highlighter-rouge">Stream</code> interface. In these quick-start videos I explain how easy it is to write database applications with Streams by using Speedment to generate the necessary entity and field classes.</p>
<p>(Spoiler: In the last video I explain why the performance will be just as good as a normal JDBC query!)</p>
<h3 id="part-1-create-a-new-speedment-project">Part 1: Create a New Speedment Project</h3>
<iframe width="560" height="315" src="https://www.youtube.com/embed/KXJEjDM2Mvw?list=PLaFOZkiTLGF_7-XQvIf6QBcmUF37Dgiid" frameborder="0" allowfullscreen=""></iframe>
<h3 id="part-2-configuration-options-in-speedment">Part 2: Configuration Options in Speedment</h3>
<iframe width="560" height="315" src="https://www.youtube.com/embed/acZeSkPBC0w?list=PLaFOZkiTLGF_7-XQvIf6QBcmUF37Dgiid" frameborder="0" allowfullscreen=""></iframe>
<h3 id="part-3-how-to-query-a-database-using-streams">Part 3: How to Query a Database Using Streams</h3>
<iframe width="560" height="315" src="https://www.youtube.com/embed/RfGBmJrF32Y?list=PLaFOZkiTLGF_7-XQvIf6QBcmUF37Dgiid" frameborder="0" allowfullscreen=""></iframe>
<p>Let me know what you think of the videos in the comment section!</p>
<p><a href="http://ageofjava.com/java/Query-Databases-Using-Streams-Video">Query Databases Using Streams (Videos)</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on March 02, 2017.</p>http://ageofjava.com/java/Prevent-Your-Caches-From-Exploding2016-12-20T00:00:00-08:002016-12-20T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>There are many scenarios when you can benefit from caching commonly used objects in your application, especially in web and micro-service oriented environments. The most simple type of caching you can do in Java is probably to introduce a private <code class="highlighter-rouge">HashMap</code> that you query before calculating an object to make sure you don’t do the job twice.</p>
<p>Here is an example of that:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">PrimeService</span> <span class="o">{</span>
<span class="kd">private</span> <span class="n">Map</span><span class="o"><</span><span class="n">Long</span><span class="o">,</span> <span class="n">BigInteger</span><span class="o">></span> <span class="n">cache</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HashMap</span><span class="o"><>();</span>
<span class="kd">public</span> <span class="n">BigInteger</span> <span class="nf">getPrime</span><span class="o">(</span><span class="kt">long</span> <span class="n">minimum</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">cache</span><span class="o">.</span><span class="na">computeIfAbsent</span><span class="o">(</span><span class="n">minimum</span><span class="o">,</span>
<span class="n">m</span> <span class="o">-></span> <span class="n">BigInteger</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">m</span><span class="o">).</span><span class="na">nextProbablePrime</span><span class="o">()</span>
<span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>This is a quick solution to the problem, but sadly not very efficient. After a few months of people entering all kinds of crazy numbers into the service, we will have a very large <code class="highlighter-rouge">HashMap</code> that might cause us to run out of memory.</p>
<p>Here is a quick trick to solve that. Instead of using a <code class="highlighter-rouge">HashMap</code>, you can use a <code class="highlighter-rouge">LinkedHashMap</code> and simply override the method <code class="highlighter-rouge">removeEldestEntry</code>. That allows you to configure your own limit function to prevent the map from exploding.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">PrimeService</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kd">static</span> <span class="kt">int</span> <span class="n">CACHE_MAX_SIZE</span> <span class="o">=</span> <span class="mi">1_000</span><span class="o">;</span>
<span class="kd">private</span> <span class="n">Map</span><span class="o"><</span><span class="n">Long</span><span class="o">,</span> <span class="n">BigInteger</span><span class="o">></span> <span class="n">cache</span> <span class="o">=</span> <span class="k">new</span> <span class="n">LinkedHashMap</span><span class="o"><>()</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">boolean</span> <span class="nf">removeEldestEntry</span><span class="o">(</span><span class="n">Map</span><span class="o">.</span><span class="na">Entry</span><span class="o"><</span><span class="n">ID</span><span class="o">,</span> <span class="n">Boolean</span><span class="o">></span> <span class="n">eldest</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="nf">size</span><span class="o">()</span> <span class="o">></span> <span class="n">PrimeService</span><span class="o">.</span><span class="na">CACHE_MAX_SIZE</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">};</span>
<span class="kd">public</span> <span class="n">BigInteger</span> <span class="nf">getPrime</span><span class="o">(</span><span class="kt">long</span> <span class="n">minimum</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">cache</span><span class="o">.</span><span class="na">computeIfAbsent</span><span class="o">(</span><span class="n">minimum</span><span class="o">,</span>
<span class="n">m</span> <span class="o">-></span> <span class="n">BigInteger</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">m</span><span class="o">).</span><span class="na">nextProbablePrime</span><span class="o">()</span>
<span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>We have now successfully limited the cache, preventing it from explosion. Old entries will be removed as new ones are added. It should be noted that this soluton works well in small applications, but for more advanced scenarious you might want to use an external caching solution instead. If you are interested in caching entries in a SQL database without writing tons of SQL code, I would recommend <a href="https://github.com/speedment/speedment">Speedment</a> since it is lightweight and has a very fluent API.</p>
<p>Until next time!</p>
<p><a href="http://ageofjava.com/java/Prevent-Your-Caches-From-Exploding">Quick Tip To Prevent Your Caches From Exploding</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on December 20, 2016.</p>http://ageofjava.com/java/Create-a-REST-API-with-Speedment-and-Spring2016-12-09T00:00:00-08:002016-04-08T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>With the 4th release of Spring Boot, developing enterprise applications for the web have become so much easier. Something that still requires a lot of time on the developer’s behalf is modelling an existing database in for an example Hibernate to get an object-oriented view of the data. In this tutorial we are going to explore how to use <a href="https://github.com/speedment/speedment">the open source tool Speedment</a> together with Spring to generate entities, managers and controllers with the press of a button, enabling you to get started with the development so much faster.</p>
<p><img src="https://lh4.googleusercontent.com/wAYjDb76RG2Sw5MqYapCvnGfud1WA3OhLfIYkK_miWZ4m7rKxgh7M1RdPmECElhzS9Xs7_4TCxog1CheV5FO24HvAGTrCq4Dp0YT7apdFLy0xaymFfqbUHA4N_yqlL_jnOgI6Yk4" alt="Happy Spring Wishes from Speedment and Crew" /></p>
<h3 id="about-speedment">About Speedment</h3>
<p>Speedment is an open source java toolkit that makes it possible for a developer to rapidly generate all the glue required to communicate with a database. Using a graphical tool, you can connect to a database and generate java sources in seconds. Speedment is built in a modular fashion, just like Spring, making it easy to learn and use only the parts you are interested in. In this article we are going to use a plugin for Speedment to generate Spring controllers in addition to the standard files.</p>
<h3 id="step-1-creating-a-new-spring-boot-project">Step 1: Creating a New Spring Boot Project</h3>
<p>Spring Boot consists of a number of templates that make it easy to get started with a new application. We are going to use one called “spring-boot-starter-web” to set the stage for our web application.</p>
<p>Begin by creating a new Maven Project and add the following to your “pom.xml”-file:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp"><?xml version="1.0" encoding="UTF-8"?></span>
<span class="nt"><project</span> <span class="na">xmlns=</span><span class="s">"http://maven.apache.org/POM/4.0.0"</span> <span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span> <span class="na">xsi:schemaLocation=</span><span class="s">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"</span><span class="nt">></span>
<span class="nt"><modelVersion></span>4.0.0<span class="nt"></modelVersion></span>
<span class="nt"><parent></span>
<span class="nt"><groupId></span>org.springframework.boot<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>spring-boot-starter-parent<span class="nt"></artifactId></span>
<span class="nt"><version></span>1.4.1.RELEASE<span class="nt"></version></span>
<span class="nt"></parent></span>
<span class="nt"><groupId></span>com.github.pyknic<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>speedment-spring-example<span class="nt"></artifactId></span>
<span class="nt"><version></span>1.0.0-SNAPSHOT<span class="nt"></version></span>
<span class="nt"><packaging></span>jar<span class="nt"></packaging></span>
<span class="nt"><properties></span>
<span class="nt"><java.version></span>1.8<span class="nt"></java.version></span>
<span class="nt"><speedment.version></span>3.0.1<span class="nt"></speedment.version></span>
<span class="nt"><mysql.version></span>5.1.39<span class="nt"></mysql.version></span>
<span class="nt"></properties></span>
<span class="nt"><build></span>
<span class="nt"><plugins></span>
<span class="nt"><plugin></span>
<span class="nt"><groupId></span>org.springframework.boot<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>spring-boot-maven-plugin<span class="nt"></artifactId></span>
<span class="nt"></plugin></span>
<span class="nt"><plugin></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>speedment-maven-plugin<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>mysql<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>mysql-connector-java<span class="nt"></artifactId></span>
<span class="nt"><version></span>${mysql.version}<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.speedment.plugins<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>spring-generator<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
<span class="nt"><configuration></span>
<span class="nt"><components></span>
<span class="nt"><component></span>com.speedment.plugins.spring.SpringGeneratorBundle<span class="nt"></component></span>
<span class="nt"></components></span>
<span class="nt"></configuration></span>
<span class="nt"></plugin></span>
<span class="nt"></plugins></span>
<span class="nt"></build></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>runtime<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><type></span>pom<span class="nt"></type></span>
<span class="nt"></dependency></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.speedment.plugins<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>spring-generator<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>mysql<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>mysql-connector-java<span class="nt"></artifactId></span>
<span class="nt"><version></span>${mysql.version}<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>org.springframework.boot<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>spring-boot-starter-web<span class="nt"></artifactId></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
<span class="nt"></project></span>
</code></pre></div></div>
<p>This will configure your project as a Spring Boot application and tell it to use Speedment with the Spring Generator Plugin.</p>
<h3 id="step-2-using-speedment-to-generate-sources">Step 2: Using Speedment to Generate Sources</h3>
<p>Once the pom-file has been modified, a number of new Maven goals will be available in the IDE. Speedment can be used both graphically or from the command line. In this tutorial, we are going to use the UI. To start the Speedment Tool, execute the following Maven goal on the project:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn speedment:tool
</code></pre></div></div>
<p>A dialog will open that let you connect to a database. Once connected, you will see a window with an overview of the database on the left and various configuration options in the center. For this tutorial the default settings will suffice, so simply press “Generate” in the toolbar.</p>
<p><img src="https://lh5.googleusercontent.com/J0lYYTwXNkNS9UeoBkG-K0Buni7VmLLZWAG7cFk4hBXasOGJKhHh-R0hKdGGupDtpHrmxi3IaOaG19yYrgDHKIHlt8T71a9PHAQcv-1zZPne-Nt3gvSOThsnqcNflBVQRglFMHhG" alt="Screenshot of the Speedment Open Source Tool" /></p>
<p>If you switch back to the IDE you will see the new generated sources. You will notice that every class exists in two copies, one of them with the “Generated”-prefix. The reason for this is to allow modifications without the risk of overwriting your changes should you need to regenerate the sources at some point. Files with the “Generated”-prefix will always be overwritten and files without it will only be created once.</p>
<h3 id="step-3-create-a-main-file">Step 3: Create a Main File</h3>
<p>Speedment has generated a complete object-oriented model of the database, but we still need to create an entry point for the application. We will put this in the main package and call it <code class="highlighter-rouge">Main.java</code>.</p>
<h6 id="mainjava">Main.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">github</span><span class="o">.</span><span class="na">pyknic</span><span class="o">.</span><span class="na">spring</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.speedment.common.logger.Level</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.speedment.common.logger.LoggerManager</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.boot.SpringApplication</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.boot.autoconfigure.SpringBootApplication</span><span class="o">;</span>
<span class="nd">@SpringBootApplication</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Main</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">...</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="n">SpringApplication</span><span class="o">.</span><span class="na">run</span><span class="o">(</span><span class="n">Main</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="n">args</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>If we start the application, Spring Boot will setup a self-contained web application with a generated controller for every table in the database. We can try it out by going to the following path in a browser:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://localhost:8080/hare/
</code></pre></div></div>
<p>A JSON representation of the “hare” table in my database will now be returned.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[
{"id":1, "name":"Harry", "color":"Gray", "age":3},
{"id":2, "name":"Henrietta", "color":"White", "age":2},
{"id":3, "name":"Henry", "color":"Black", "age":9}
]
</code></pre></div></div>
<p><em>Note #1:</em> If you get an exception that says something in style of this…</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>There was an unexpected error (type=Internal Server Error, status=500).
Could not write content: No value present (through reference chain:
java.util.ArrayList[0]...
</code></pre></div></div>
<p>…it probably means that you have nullable columns in your database that Speedment chooses to implement as <code class="highlighter-rouge">OptionalLong</code>, <code class="highlighter-rouge">OptionalInt</code> etc. You can turn this feature off in the Speedment Tool by setting the “Nullable Implementation” field to <code class="highlighter-rouge">WRAPPER</code> instead of <code class="highlighter-rouge">OPTIONAL</code> for those columns.</p>
<p><em>Note #2:</em> If you get an exception in the style of this…</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>java.sql.SQLException: Access denied for user 'root'@'localhost'
(using password: YES)
</code></pre></div></div>
<p>…you will need to create an <code class="highlighter-rouge">application.properties</code>-file in the root of the project and add the authentication details for your database.</p>
<h6 id="applicationproperties">application.properties</h6>
<div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">jdbc.username</span><span class="p">=</span><span class="s">root</span>
<span class="py">jdbc.password</span><span class="p">=</span><span class="s">password</span>
</code></pre></div></div>
<h3 id="summary">Summary</h3>
<p>In this article we have used <a href="http://speedment.org">Speedment</a> and the Spring Generator plugin to automatically create a complete Spring Boot Application. Speedment has generated entities, managers and REST controllers for communicating with the database. If you want to know more about Speedment and how you can control the generated code, check out the many examples <a href="https://github.com/speedment/speedment">at the Speedment GitHub page</a>!</p>
<p><a href="http://ageofjava.com/java/Create-a-REST-API-with-Speedment-and-Spring">Creating a REST API with Speedment and Spring</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on December 09, 2016.</p>http://ageofjava.com/java/Hack-Speedment-Into-Your-Own-Code-Generator2016-11-21T00:00:00-08:002016-11-21T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p><a href="https://github.com/speedment/speedment">Speedment is an Open Source toolkit</a> that can be used to generate Java entities and managers for communicating with a database. This is great if you need an Object Relational Mapping of the domain model, but in some cases, you might want to generate something completely different using your database as the template. In this article I am going to show you a hack that you can use to take over that code generator in Speedment and use it for your own personal purposes. At the end of the article we will have a completely blank code generator that we can program to do our bidding!</p>
<p><img src="https://lh3.googleusercontent.com/nhxCiGJnv4ynMY7iiDwicFBDNtK3EMs9Pi4EQfw06wCgycN0i2e9sgAshaGUjrbCo3yMalpQdVJCfHwSF_hqV2IeYmidHHOL8AkgMjKpDRSIzHpla-wqKooHGnuQ6J2bbPU82ZIh" alt="Spire and Duke dressed as Neo from Matrix" /></p>
<h3 id="background">Background</h3>
<p>Speedment is designed to operate as a plugin to Maven. By invoking various new Maven goals we can instruct Speedment to connect to a database, generate source code and also remove any generated files from our project. It also contains a graphical user interface that makes it easy to configure the generation job based on metadata collected from our database. Now, imagine all this information that we can collect from analyzing that metadata. We know what tables exist, we know of all the constraints they have and what types the individual columns have. There are probably millions of use-cases where we can benefit from automatically generating stuff from that metadata. Following the steps in this article, we can do all those things.</p>
<p><img src="https://lh4.googleusercontent.com/UUm_oO_opFhRMh8oalWhpLq9ErgAJTXrTBDPQjWMAJarY922Pl-yMseN4JhnLeAcmhAHT9ga001glER6FFBNKlWvfMbihE1T8X4hP3XfvAc2B-buScCEeHd9gYTZJWoOzMhCuAh4" alt="Screenshot of the Speedment User Interface" /></p>
<h3 id="step-1-set-up-a-regular-speedment-project">Step 1: Set Up a Regular Speedment Project</h3>
<p>Create a new Maven Project and add the following to the <code class="highlighter-rouge">pom.xml</code>-file:</p>
<h6 id="pomxml">pom.xml</h6>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><properties></span>
<span class="nt"><speedment.version></span>3.0.1<span class="nt"></speedment.version></span>
<span class="nt"><mysql.version></span>5.1.39<span class="nt"></mysql.version></span>
<span class="nt"></properties></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>runtime<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><type></span>pom<span class="nt"></type></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
<span class="nt"><build></span>
<span class="nt"><plugins></span>
<span class="nt"><plugin></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>speedment-maven-plugin<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>mysql<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>mysql-connector-java<span class="nt"></artifactId></span>
<span class="nt"><version></span>${mysql.version}<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
<span class="nt"></plugin></span>
<span class="nt"></plugins></span>
<span class="nt"></build></span>
</code></pre></div></div>
<p>We have added Speedment as a runtime dependency and configured the Maven plugin to use the standard MySQL JDBC driver to connect to our database. Great! You now have access to a number of new Maven goals. For an example, if we wanted to launch the Speedment UI we could do that by running:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn speedment:tool
</code></pre></div></div>
<p>If we did that now, Speedment would launch in normal mode allowing us to connect to a database and from it generate entities and managers for communicating with that database using Java 8 streams. That is not what we want to do this time around. We want to hack it so that it does exactly what we need it to do. We therefore continue to modify the pom.</p>
<h3 id="step-2-modify-the-plugin-declaration">Step 2: Modify the Plugin Declaration</h3>
<p>Speedment is built up in a modular fashion with different artifacts responsible for different tasks. All the pre-existing generator tasks are located in an artifact called “com.speedment.generator:generator-standard”. That is where we are going to strike! By removing that artifact from the classpath we can prevent Speedment from generating anything we don’t want it to.</p>
<p>We modify the <code class="highlighter-rouge">pom</code> as follows:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code>...
<span class="nt"><plugin></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>speedment-maven-plugin<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>mysql<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>mysql-connector-java<span class="nt"></artifactId></span>
<span class="nt"><version></span>${mysql.version}<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="c"><!-- Add this: --></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>tool<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><type></span>pom<span class="nt"></type></span>
<span class="nt"><exclusions></span>
<span class="nt"><exclusion></span>
<span class="nt"><groupId></span>com.speedment.generator<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>generator-standard<span class="nt"></artifactId></span>
<span class="nt"></exclusion></span>
<span class="nt"></exclusions></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
<span class="nt"></plugin></span>
...
</code></pre></div></div>
<p>What is that? We exclude a dependency by adding one? How can that even work? Well, Speedment is designed to include as little code as possible unless it is explicitly needed by the application. The “com.speedment:tool-artifact” is a dependency to the maven plugin already, and by mentioning it in the <code class="highlighter-rouge"><dependencies></code>-section of the maven plugin we can append settings to its configuration. In this case, we say that we want the plugin to have access to the tool except we don’t want the standard generator.</p>
<p>There is a problem here though. If we try and launch the speedment:tool goal, we will get an exception. The reason for this is that Speedment <em>expects</em> the standard translators to be on the classpath.</p>
<p>Here is where the second ugly hack comes in. In our project, we create a new package called <code class="highlighter-rouge">com.speedment.generator.standard</code> and in it define a new java file called <code class="highlighter-rouge">StandardTranslatorBundle.java</code>. As it turns out, that is the only file that Speedment really needs to work. We give it the following content:</p>
<h6 id="standardtranslatorbundlejava">StandardTranslatorBundle.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">speedment</span><span class="o">.</span><span class="na">generator</span><span class="o">.</span><span class="na">standard</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.speedment.common.injector.InjectBundle</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.stream.Stream</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">StandardTranslatorBundle</span> <span class="kd">implements</span> <span class="n">InjectBundle</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Stream</span><span class="o"><</span><span class="n">Class</span><span class="o"><?>></span> <span class="n">injectables</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">Stream</span><span class="o">.</span><span class="na">empty</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Next, we need to replace the excluded artifact with our own project so that the plugin never realizes that the files are missing. We return to the <code class="highlighter-rouge">pom.xml</code>-file and add our own project to the <code class="highlighter-rouge"><dependencies></code>-section of the <code class="highlighter-rouge">speedment-maven-plugin</code>. The full pom file looks like this:</p>
<h6 id="pomxml-1">pom.xml</h6>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp"><?xml version="1.0" encoding="UTF-8"?></span>
<span class="nt"><project</span> <span class="na">xmlns=</span><span class="s">"http://maven.apache.org/POM/4.0.0"</span>
<span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span>
<span class="na">xsi:schemaLocation=</span><span class="s">"http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"</span><span class="nt">></span>
<span class="nt"><modelVersion></span>4.0.0<span class="nt"></modelVersion></span>
<span class="nt"><groupId></span>com.github.pyknic<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>speedment-general-purpose<span class="nt"></artifactId></span>
<span class="nt"><version></span>1.0.0-SNAPSHOT<span class="nt"></version></span>
<span class="nt"><packaging></span>jar<span class="nt"></packaging></span>
<span class="nt"><properties></span>
<span class="nt"><project.build.sourceEncoding></span>UTF-8<span class="nt"></project.build.sourceEncoding></span>
<span class="nt"><maven.compiler.source></span>1.8<span class="nt"></maven.compiler.source></span>
<span class="nt"><maven.compiler.target></span>1.8<span class="nt"></maven.compiler.target></span>
<span class="nt"><speedment.version></span>3.0.1<span class="nt"></speedment.version></span>
<span class="nt"></properties></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>runtime<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><type></span>pom<span class="nt"></type></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
<span class="nt"><build></span>
<span class="nt"><plugins></span>
<span class="nt"><plugin></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>speedment-maven-plugin<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>tool<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><type></span>pom<span class="nt"></type></span>
<span class="nt"><exclusions></span>
<span class="nt"><exclusion></span>
<span class="nt"><groupId></span>com.speedment.generator<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>generator-standard<span class="nt"></artifactId></span>
<span class="nt"></exclusion></span>
<span class="nt"></exclusions></span>
<span class="nt"></dependency></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.github.pyknic<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>speedment-general-purpose<span class="nt"></artifactId></span>
<span class="nt"><version></span>1.0.0-SNAPSHOT<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>mysql<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>mysql-connector-java<span class="nt"></artifactId></span>
<span class="nt"><version></span>5.1.39<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
<span class="nt"></plugin></span>
<span class="nt"></plugins></span>
<span class="nt"></build></span>
<span class="nt"></project></span>
</code></pre></div></div>
<p>If we now build our project and then run the goal speedment:tool, we should be able to launch the graphical user interface without problem. If we connect to the database and then press “Generate”, nothing will happen at all! We have successfully hacked Speedment into doing absolutely nothing!</p>
<h3 id="step-3-turn-speedment-into-what-you-want-it-to-be">Step 3: Turn Speedment Into What You Want It To Be</h3>
<p>Now when we have a fresh, clean Speedment, we can start turning it into the application we want it to be. We still have a powerful user interface where we can configure the code generation based on a database model. We have an expressive library of utilities and helper classes to work with generated code. And above all, we have a structure for analyzing the database metadata in an object-oriented fashion.</p>
<p>To learn more about how to write your own code generation templates and hook them into the platform, <a href="http://www.ageofjava.com/2016/04/how-to-generate-customized-java-8-code.html">check out this article</a>. You should also check out the <a href="https://github.com/speedment/speedment">Speedment GitHub page</a> to learn how the existing generators work (the ones we just disabled) and maybe get some inspiration on how you can build your own.</p>
<p>Until next time, continue hacking!</p>
<p><a href="http://ageofjava.com/java/Hack-Speedment-Into-Your-Own-Code-Generator">Hack Speedment into Your Own Personal Code Generator</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on November 21, 2016.</p>http://ageofjava.com/java/Auto-Generate-Optimized-Java-Class-Specializations2016-11-14T00:00:00-08:002016-04-08T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>If you visited JavaOne this year you might have attended my presentation on “How to Generate Customized Java 8 Code from your Database”. In that talk I showcased how the <a href="https://github.com/speedment/speedment">Speedment Open Source toolkit</a> is used to generate all kinds of Java code using a database as the domain model. One thing we didn’t have time to go into though is the fact that Speedment is not only making code generation easier, it is also itself made up by generated code. In this article I will show you have we set up Speedment to generate specialized versions of many classes to reduce the memory footprint of performance critical parts of the system.</p>
<h3 id="background">Background</h3>
<p><img src="https://lh5.googleusercontent.com/oCF8wcMf4KdPMSw77jaIx7g07ci3U8OU2aB-sMQHVL8rbGJUstfAfkxFHAUbwgUW5zIryuHJjBR_xmT1Vywu7X9BuBs4cuaqUShjTzky2VClHEGXpFn8IP29nXQ2NQTbw1Dxj0X_" alt="Spire and Duke are playing with specialized geometric shapes" /></p>
<p>As you might know, Java has a number of built-in value types. These are bytes, shorts, integers, longs, floats, doubles, booleans and characters. Primitive value types are different from ordinary objects primarily in that they can be allocated directly on the memory stack, reducing the burden on the Garbage Collector. A problem with not inheriting from Object is that they can’t be put into collections or passed as parameters to methods that take object parameters without being <em>wrapped</em>. Typical wrapper classes are therefore “Integer”, “Double”, “Boolean” etc.</p>
<p>Wrapping a value type is not always a bad thing. The JIT (Just-In-Time) compiler is very good at optimizing away wrapper types if they can safely be replaced with primitive values, but that is not always possible. If this occur in a performance critical section of your code like in an inner loop, this can heavily impact the performance of the entire application.</p>
<p>That’s what happened to us when working on Speedment. We had special predicates and functions that contained metadata about their purpose. That metadata needed to be analyzed very rapidly inside an inner loop, but we was slowed down by the fact that most of this metadata was wrapped inside generic types so that they could be instantiated dynamically.</p>
<p>A common solution to this problem is to create a number of “specializations” of the classes that contain the wrapper types. The specializations are identical to the original class except that they use one of the primitive value types instead of a generic (object only) type. A good example of specializations are the various Stream interfaces that exist in Java 8. In addition to “Stream” we also have an “IntStream”, a “DoubleStream” and a “LongStream”. These specializations are more efficient for their particular value type since they don’t have to rely on wrapping types in objects.</p>
<p>The problem with specialization classes is that they add a lot of boilerplate to the system. Say that the parts that need to be optimized consist of 20 components. If you want to support all the 8 primitive variations that Java has you suddenly have 160 components. That is a lot of code to maintain. A better solution would be to generate all the extra classes.</p>
<h3 id="template-based-code-generation">Template Based Code Generation</h3>
<p>The most common form of code generation in higher languages is template based. This means that you write a template file and then do keyword replacement to modify the text depending on what you are generating. Good examples of these are <a href="https://maven.apache.org/guides/introduction/introduction-to-archetypes.html">Maven Archetypes</a> or <a href="http://www.thymeleaf.org/">Thymeleaf</a>. A good template engine will have support for more advanced syntax like repeating sections, expressing conditions etc. If you want to generate specialization classes using a template engine you would replace all occurrences of “int”, “Integer”, “IntStream” with a particular keyword like “${primitive}”, “${wrapper}”, “${stream}” and then specify the dictionary of words to associate with each new value type.</p>
<p>Advantages of template based code generation is that it is easy to setup and easy to maintain. I think most programmers that read this could probably figure out how to write a template engine fairly easy. A disadvantage is that a templates are difficult to reuse. Say that you have a basic template for a specialized, but you want floating types to also have an additional method. You could solve this with a conditional statement, but if you want that extra method to also exist in other places, you will need to duplicate code. A typical example of code that often need to be duplicated is hashCode()-methods or toString(). This is where model based code generation is stronger.</p>
<h3 id="model-based-code-generation">Model Based Code Generation</h3>
<p>In model based code generation, you build an abstract syntax tree over the code you want generated and then render that tree using a suitable renderer. The syntax tree can be mutated depending on the context that it is being used in, for an example by adding or removing methods to implement a certain interface. The main advantage of this is higher flexibility. You can dynamically take an existing model and manipulate which methods and fields to include. The downside is that model based code generation generally take a bit longer to set up.</p>
<h3 id="case-study-speedment-field-generator">Case Study: Speedment Field Generator</h3>
<p>At Speedment, we developed a code generator called <a href="https://github.com/speedment/speedment/tree/master/common-parent/codegen">CodeGen</a> that uses the model based approach to automatically generate field specializations for all the primitive value types. In total around 300 classes are generated on each build.</p>
<p>Speedment CodeGen uses an abstract syntax tree built around the basic concepts of object oriented design. You have classes, interfaces, fields, methods, constructors, etc that you use to build the domain model. Below the method level you still need to write templated code. To define a new main class, you would write:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">com.speedment.common.codegen.model.Class</span><span class="o">;</span> <span class="c1">// Not java.lang.Class</span>
<span class="o">...</span>
<span class="n">Class</span> <span class="nf">createMainClass</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">Class</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Main"</span><span class="o">)</span>
<span class="o">.</span><span class="na">public_</span><span class="o">().</span><span class="na">final_</span><span class="o">()</span>
<span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="n">Javadoc</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"The main entry point of the application"</span><span class="o">)</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">AUTHOR</span><span class="o">.</span><span class="na">setValue</span><span class="o">(</span><span class="s">"Emil Forslund"</span><span class="o">))</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">SINCE</span><span class="o">.</span><span class="na">setValue</span><span class="o">(</span><span class="s">"1.0.0"</span><span class="o">))</span>
<span class="o">)</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">Method</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"main"</span><span class="o">,</span> <span class="kt">void</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
<span class="o">.</span><span class="na">public_</span><span class="o">().</span><span class="na">static_</span><span class="o">()</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">Field</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"args"</span><span class="o">,</span> <span class="n">String</span><span class="o">[].</span><span class="na">class</span><span class="o">))</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span>
<span class="s">"if (args.length == 0) "</span> <span class="o">+</span> <span class="n">block</span><span class="o">(</span>
<span class="s">"System.out.println(\"Hello, World!\");"</span>
<span class="o">)</span> <span class="o">+</span> <span class="s">" else "</span> <span class="o">+</span> <span class="n">block</span><span class="o">(</span>
<span class="s">"System.out.format(\"Hi, %s!%n\", args[0]);"</span>
<span class="o">)</span>
<span class="o">)</span>
<span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>This would generate the following code:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* The main entry point of the application.
*
* @author Emil Forslund
* @since 1.0.0
*/</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">Main</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">args</span><span class="o">.</span><span class="na">length</span> <span class="o">==</span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Hello, World!"</span><span class="o">);</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="s">"Hi, %s!%n"</span><span class="o">,</span> <span class="n">args</span><span class="o">[</span><span class="mi">0</span><span class="o">]);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The entire model doesn’t have to be generated at once. If we for an example want to generate a <code class="highlighter-rouge">toString()</code>-method automatically, we can define that as an individual method.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kt">void</span> <span class="nf">generateToString</span><span class="o">(</span><span class="n">File</span> <span class="n">file</span><span class="o">)</span> <span class="o">{</span>
<span class="n">file</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">Import</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="n">StringBuilder</span><span class="o">.</span><span class="na">class</span><span class="o">));</span>
<span class="n">file</span><span class="o">.</span><span class="na">getClasses</span><span class="o">().</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">HasFields</span><span class="o">.</span><span class="na">class</span><span class="o">::</span><span class="n">isInstance</span><span class="o">)</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">HasMethods</span><span class="o">.</span><span class="na">class</span><span class="o">::</span><span class="n">isInstance</span><span class="o">)</span>
<span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="n">c</span> <span class="o">-></span> <span class="o">(</span><span class="n">HasFields</span> <span class="o">&</span> <span class="n">HasMethods</span><span class="o">)</span> <span class="n">c</span><span class="o">)</span>
<span class="o">.</span><span class="na">forEach</span><span class="o">(</span><span class="n">clazz</span> <span class="o">-></span>
<span class="n">clazz</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">Method</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"toString"</span><span class="o">,</span> <span class="kt">void</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">OVERRIDE</span><span class="o">)</span>
<span class="o">.</span><span class="na">public_</span><span class="o">()</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"return new StringBuilder()"</span><span class="o">)</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">clazz</span><span class="o">.</span><span class="na">getFields</span><span class="o">().</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="n">f</span> <span class="o">-></span> <span class="s">".append(\""</span> <span class="o">+</span> <span class="n">f</span><span class="o">.</span><span class="na">getName</span><span class="o">()</span> <span class="o">+</span> <span class="s">"\")"</span><span class="o">)</span>
<span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="nl">Formatting:</span><span class="o">:</span><span class="n">indent</span><span class="o">)</span>
<span class="o">.</span><span class="na">toArray</span><span class="o">(</span><span class="n">String</span><span class="o">[]::</span><span class="k">new</span><span class="o">)</span>
<span class="o">)</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">indent</span><span class="o">(</span><span class="s">".toString();"</span><span class="o">))</span>
<span class="o">)</span>
<span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Here you can see how the <a href="http://www.ageofjava.com/2016/02/definition-of-trait-pattern-in-java.html">Trait Pattern</a> is used to abstract away the underlying implementation from the logic. The code will work for <code class="highlighter-rouge">Enum</code> as well as <code class="highlighter-rouge">Class</code> since both implement both the traits “HasFields” and “HasMethods”.</p>
<h3 id="summary">Summary</h3>
<p>In this article I have explained what specialization classes are and why they are sometimes necessary to improve performance in critical sections of an application. I have also showed you how Speedment use model based code generation to automatically produce specialization classes. If you are interested in generating code with these tools yourself, go ahead and check out the <a href="https://github.com/speedment/speedment">latest version of the generator at GitHub</a>!</p>
<p><a href="http://ageofjava.com/java/Auto-Generate-Optimized-Java-Class-Specializations">Auto-Generate Optimized Java Class Specializations</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on November 14, 2016.</p>http://ageofjava.com/java/Whats-New-in-Speedment-3.02016-10-31T00:00:00-07:002016-10-31T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>If you have followed my blog you know that I have been involved in the <a href="https://github.com/speedment/speedment">open-source project Speedment</a> for a while. During the summer and fall I have worked a lot with finishing up the next big <a href="https://github.com/speedment/speedment/releases/tag/3.0.0">3.0.0 release</a> of the toolkit. In this post I will showcase some of the cool new features we have built into the platform and also explain how you can get started!</p>
<p><img src="https://lh3.googleusercontent.com/Qm93wI3PLGiIxuXXFUcO6CdPe9oy_81XpNlwnKORv1M8BNDEv6Am7KvpCCh4qSjurbVrSAoDdaEyRbcdgByU3TLzIDnbg2QDQ3GjNOcc9EI4cDK5bP4SoJCaez_J9z_5yOHDC4tc" alt="Spire standing in front of a sign that says Forest" /></p>
<h3 id="new-module-system">New Module System</h3>
<p>The biggest change from the previous version of Speedment, and the one that took us most time to get right, is the new module system. If you have been following the progress of the new <a href="http://openjdk.java.net/projects/jigsaw/">JDK 9 project Jigsaw</a>, you will recognize this subject. Previously, Speedment consisted of one big artifact called <strong>com.speedment:speedment</strong>. In addition to this, we had a few minor projects like the <strong>speedment-maven-plugin</strong> and <strong>speedment-archetypes</strong> that made the tool easier to use. There was several issues with this design. First, it was very tedious to develop in it since we often needed to rebuild the entire thing multiple times each day and every build could take minutes. It was also not very plugin-friendly since a plugin had to depend on the entire code base, even if it only modified a small group of classes.</p>
<p>In 3.0 however, <strong>com.speedment</strong> is actually a multi-module pom-project with a clear build order. Inside it are groups of artifacts, also realized as multi-module projects, that separate artifacts based on when they are needed. We now have the following artifact groups:</p>
<ol>
<li><strong>common-parent</strong> contains artifacts that are mature, reusable in a number of situations and that doesn’t have any dependencies (except on our own <a href="https://github.com/speedment/speedment/tree/master/common-parent/logger">lightweight logging framework</a>). Here you will find some of the core utilities of Speedment like <a href="https://github.com/speedment/speedment/tree/master/common-parent/mapstream">MapStream</a> and <a href="https://github.com/speedment/speedment/tree/master/common-parent/codegen">CodeGen</a>.</li>
<li><strong>runtime-parent</strong> contains artifacts that are required by the end-user during the runtime of their application. We wanted to separate these into their own group to make sure that the final jar of the user’s app has as small footprint as possible.</li>
<li><strong>generator-parent</strong> contains artifacts related to the code generation and database analyzation parts of Speedment. These classes doesn’t require a graphical environment which is useful if you want to use Speedment as a general purpose code generator in a non-graphical environment.</li>
<li><strong>tool-parent</strong> contains all the artifacts used by the graphical Speedment tool. Here we put all our home-brewed JavaFX-components as well as resources like icons used by the UI.</li>
<li><strong>build-parent</strong> is a meta group that contains various artifacts that we build simply to make Speedment easier to use for the end user. Here we for an example have a number of shaded artifacts that you can use when you deploy your application on a server and the Maven Plugin that users use to launch Speedment as a Maven goal.</li>
<li><strong>plugins-parent</strong> is a whole new group where we put official plugins for Speedment that doesn’t quite fit into the general framework but that many users request. This makes it possible for us to automatically rebuild them in the general build cycle, making sure they are always up-to-date with the latest changes in the platform.</li>
<li><strong>archetypes-parent</strong> is a group of all the official Maven Archetypes for Speedment. This was previously a separate project but has now been lifted into the main project so that they can be automatically reinstalled every time Speedment is built.</li>
</ol>
<p>All these groups are built in the same order as specified above. This makes it much easier to keep dependencies single-directional and the overall design of the system more comprehensive.</p>
<h3 id="so-how-do-i-use-it">So how do I use it?</h3>
<p>The beautiful thing is that you barely have to change a thing! We automatically build an artifact that is called <strong>com.speedment:runtime</strong> that you can depend on in your project. It contains transitive dependencies to the exact set of artifacts that are required to run Speedment.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>runtime<span class="nt"></artifactId></span>
<span class="nt"><version></span>3.0.1<span class="nt"></version></span>
<span class="nt"><type></span>pom<span class="nt"></type></span>
<span class="nt"></dependency></span>
</code></pre></div></div>
<p>When it is time for deployment, you simply replace this dependency with <strong>com.speedment:runtime-deploy</strong> and you will get a shaded jar with all the Speedment-stuff bundled together and ready to ship!</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>runtime-deploy<span class="nt"></artifactId></span>
<span class="nt"><version></span>3.0.1<span class="nt"></version></span>
<span class="nt"></dependency></span>
</code></pre></div></div>
<p>For more details about the new release, go to <a href="https://github.com/speedment/speedment">this official GitHub page</a> and fork it!</p>
<p><a href="http://ageofjava.com/java/Whats-New-in-Speedment-3.0">What’s New in Speedment 3.0</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on October 31, 2016.</p>http://ageofjava.com/java/Database-CRUD-Operations-in-Java-8-Streams2016-10-24T00:00:00-07:002016-10-24T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>The biggest obstacle to overcome when starting out with a new tool is to get your head around how to do the little things. By now you might feel confident in how the new Java 8 Stream API works, but you might not have used it for database querying yet. To help you get started creating, modifying and reading from your SQL database using the Stream API, I have put together this quick start. Hopefully it can help you take your streams to the next level!</p>
<p><img src="https://lh3.googleusercontent.com/17K5cRtmbFf1dmtiD1m-jeYvnsZYRQpEm3V7d7x1qAu_su-TuoAF5tpiCOYsLMRNDXrMk_mu5QU_175TdUqH0j-ug8G05hyVBjngSx470Jr_UD3k8Acb73tqmTRz9RAAg37WxL-v" alt="Spire and Duke in front of the letters CRUD" /></p>
<h3 id="background">Background</h3>
<p><a href="https://github.com/speedment/speedment">Speedment is an Open Source toolkit</a> that can be used to generate java entities and managers for communicating with a database. Using a graphical tool you connect to your database and generate a complete ORM tailored to represent your domain model. But Speedment is not only a code generator but also a runtime that plugs into your application and makes it possible to translate your Java 8 streams into optimized SQL queries. That is the part that I will focus on in this article.</p>
<h3 id="generate-code">Generate Code</h3>
<p>To begin using Speedment in a Maven project, add the following lines to your pom.xml-file. In this example I am using MySQL, but you can use PostgreSQL or MariaDB as well. Connectors to proprietary databases like Oracle are available for enterprise customers.</p>
<h6 id="pomxml">pom.xml</h6>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><properties></span>
<span class="nt"><speedment.version></span>3.0.1<span class="nt"></speedment.version></span>
<span class="nt"><db.groupId></span>mysql<span class="nt"></db.groupId></span>
<span class="nt"><db.artifactId></span>mysql-connector-java<span class="nt"></db.artifactId></span>
<span class="nt"><db.version></span>5.1.39<span class="nt"></db.version></span>
<span class="nt"></properties></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>runtime<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><type></span>pom<span class="nt"></type></span>
<span class="nt"></dependency></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>${db.groupId}<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>${db.artifactId}<span class="nt"></artifactId></span>
<span class="nt"><version></span>${db.version}<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
<span class="nt"><build></span>
<span class="nt"><plugins></span>
<span class="nt"><plugin></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>speedment-maven-plugin<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>${db.groupId}<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>${db.artifactId}<span class="nt"></artifactId></span>
<span class="nt"><version></span>${db.version}<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
<span class="nt"></plugin></span>
<span class="nt"></plugins></span>
<span class="nt"></build></span>
</code></pre></div></div>
<p>You now have access to a number of new Maven Goals that make it easier to use the toolkit. The launch the Speedment UI, execute:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn speedment:tool
</code></pre></div></div>
<p>This will guide you through the process of connecting to the database and configure the code generation. The simplest way in the beginning is you just run along with the default settings. Once you press “Generate”, Speedment will analyze your database metadata and fill your project with new sources like entity and manager classes.</p>
<h3 id="initialize-speedment">Initialize Speedment</h3>
<p>Once you have generated your domain model, setting up Speedment is easy. Create a new <code class="highlighter-rouge">Main.java</code>-file and add the following lines. All the classes you see are generated so their names will depend on the names of your database schemas, tables and columns.</p>
<h6 id="mainjava">Main.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Main</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">...</span> <span class="n">param</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">HaresApplication</span> <span class="n">app</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HaresApplicationBuilder</span><span class="o">()</span>
<span class="o">.</span><span class="na">withPassword</span><span class="o">(</span><span class="s">"password"</span><span class="o">)</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The code above creates a new application instance using a generated builder pattern. The builder makes it possible to set any runtime configuration details like database passwords.</p>
<p>Once we have an app instance, we can use it to get access to the generated managers. In this case, I have four tables in the database; “hare”, “carrot”, “human” and “friend”. (You can see <a href="https://github.com/speedment/speedment-code-samples/tree/master/hares/src/main/resources">the entire database definition here</a>).</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="n">CarrotManager</span> <span class="n">carrots</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="na">getOrThrow</span><span class="o">(</span><span class="n">CarrotManager</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="kd">final</span> <span class="n">HareManager</span> <span class="n">hares</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="na">getOrThrow</span><span class="o">(</span><span class="n">HareManager</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="kd">final</span> <span class="n">HumanManager</span> <span class="n">humans</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="na">getOrThrow</span><span class="o">(</span><span class="n">HumanManager</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="kd">final</span> <span class="n">FriendManager</span> <span class="n">friends</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="na">getOrThrow</span><span class="o">(</span><span class="n">FriendManager</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
</code></pre></div></div>
<p>These managers can now be used to perform all our CRUD operations.</p>
<h3 id="create-entities">Create Entities</h3>
<p>Creating entities is very straight forward. We use the generated implementation of our entities, set the values we want for columns and then persist it to the data source.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">hares</span><span class="o">.</span><span class="na">persist</span><span class="o">(</span>
<span class="k">new</span> <span class="nf">HareImpl</span><span class="o">()</span>
<span class="o">.</span><span class="na">setName</span><span class="o">(</span><span class="s">"Harry"</span><span class="o">)</span>
<span class="o">.</span><span class="na">setColor</span><span class="o">(</span><span class="s">"Gray"</span><span class="o">)</span>
<span class="o">.</span><span class="na">setAge</span><span class="o">(</span><span class="mi">8</span><span class="o">)</span>
<span class="o">);</span>
</code></pre></div></div>
<p>The persist method returns a (potentially) new instance of Hare where auto-generated keys like “id” has been set. If we want to use Harry after persisting him we should therefore use the instance returned by persist.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="n">Hare</span> <span class="n">harry</span> <span class="o">=</span> <span class="n">hares</span><span class="o">.</span><span class="na">persist</span><span class="o">(</span>
<span class="k">new</span> <span class="nf">HareImpl</span><span class="o">()</span>
<span class="o">.</span><span class="na">setName</span><span class="o">(</span><span class="s">"Harry"</span><span class="o">)</span>
<span class="o">.</span><span class="na">setColor</span><span class="o">(</span><span class="s">"Gray"</span><span class="o">)</span>
<span class="o">.</span><span class="na">setAge</span><span class="o">(</span><span class="mi">8</span><span class="o">)</span>
<span class="o">);</span>
</code></pre></div></div>
<p>If the persistence fails, for an example if a foreign key or a unique constraint fails, a <code class="highlighter-rouge">SpeedmentException</code> is thrown. We should check for this and show an error if something prevented us from persisting the hare.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">try</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">Hare</span> <span class="n">harry</span> <span class="o">=</span> <span class="n">hares</span><span class="o">.</span><span class="na">persist</span><span class="o">(</span>
<span class="k">new</span> <span class="nf">HareImpl</span><span class="o">()</span>
<span class="o">.</span><span class="na">setName</span><span class="o">(</span><span class="s">"Harry"</span><span class="o">)</span>
<span class="o">.</span><span class="na">setColor</span><span class="o">(</span><span class="s">"Gray"</span><span class="o">)</span>
<span class="o">.</span><span class="na">setAge</span><span class="o">(</span><span class="mi">8</span><span class="o">)</span>
<span class="o">);</span>
<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="kd">final</span> <span class="n">SpeedmentException</span> <span class="n">ex</span><span class="o">)</span> <span class="o">{</span>
<span class="n">System</span><span class="o">.</span><span class="na">err</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">ex</span><span class="o">.</span><span class="na">getMessage</span><span class="o">());</span>
<span class="k">return</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>
<h3 id="read-entities">Read Entities</h3>
<p>The coolest feature in the Speedment runtime is the ability to stream over data in your database using Java 8 Streams. <em>“Why is that so cool?”</em> you might ask yourself. <em>“Even <a href="http://javadeau.lawesson.se/2016/10/java-8-streams-in-hibernate-and-beyond.html">Hibernate have support for streaming</a> nowadays!”</em></p>
<p>The beautiful thing with Speedment streams is that they take intermediary and terminating actions into consideration when constructing the stream. This means that if you add a filter to the stream after it has been created, it will still be taken into consideration when building the SQL statement.</p>
<p>Here is an example. We want to count the total number of hares in the database.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="kt">long</span> <span class="n">haresTotal</span> <span class="o">=</span> <span class="n">hares</span><span class="o">.</span><span class="na">stream</span><span class="o">().</span><span class="na">count</span><span class="o">();</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="s">"There are %d hares in total.%n"</span><span class="o">,</span> <span class="n">haresTotal</span><span class="o">);</span>
</code></pre></div></div>
<p>The SQL query that will be generated is the following:</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span> <span class="k">FROM</span> <span class="n">hares</span><span class="p">.</span><span class="n">hare</span><span class="p">;</span>
</code></pre></div></div>
<p>The terminating operation was a <code class="highlighter-rouge">.count()</code> so Speedment knows that it is a <code class="highlighter-rouge">SELECT COUNT(...)</code>-statement that is to be created. It also knows that the primary key for the “hare” table is the column “id”, which makes it possible to reduce the entire statement sent to the database down into this.</p>
<p>A more complex example might be to find the number of hares that has a name that ends with the letters “rry” and an age greater or equal to 5. That can be written as this:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="kt">long</span> <span class="n">complexTotal</span> <span class="o">=</span> <span class="n">hares</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">Hare</span><span class="o">.</span><span class="na">NAME</span><span class="o">.</span><span class="na">endsWith</span><span class="o">(</span><span class="s">"rry"</span><span class="o">))</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">Hare</span><span class="o">.</span><span class="na">AGE</span><span class="o">.</span><span class="na">greaterOrEqual</span><span class="o">(</span><span class="mi">5</span><span class="o">))</span>
<span class="o">.</span><span class="na">count</span><span class="o">();</span>
</code></pre></div></div>
<p>We use the predicate builders generated to us by Speedment to define the filters. This make it possible for us to analyze the stream programmatically and reduce it down to the following SQL statement:</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="k">COUNT</span><span class="p">(</span><span class="n">id</span><span class="p">)</span> <span class="k">FROM</span> <span class="n">hares</span><span class="p">.</span><span class="n">hare</span>
<span class="k">WHERE</span> <span class="n">hare</span><span class="p">.</span><span class="n">name</span> <span class="k">LIKE</span> <span class="n">CONCAT</span><span class="p">(</span><span class="nv">"%"</span><span class="p">,</span> <span class="o">?</span><span class="p">)</span>
<span class="k">AND</span> <span class="n">hare</span><span class="p">.</span><span class="n">age</span> <span class="o">>=</span> <span class="mi">5</span><span class="p">;</span>
</code></pre></div></div>
<p>If we add an operation that Speedment can’t optimize to the stream, it will be resolved just like any Java 8 stream. We are never limited to the use of the generated predicate builders, it just makes the stream more efficient.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="kt">long</span> <span class="n">inefficientTotal</span> <span class="o">=</span> <span class="n">hares</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">h</span> <span class="o">-></span> <span class="n">h</span><span class="o">.</span><span class="na">getName</span><span class="o">().</span><span class="na">hashCode</span><span class="o">()</span> <span class="o">==</span> <span class="mi">52</span><span class="o">)</span>
<span class="o">.</span><span class="na">count</span><span class="o">();</span>
</code></pre></div></div>
<p>This would produce the following extremely inefficient statement, but it will still work.</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">id</span><span class="p">,</span><span class="n">name</span><span class="p">,</span><span class="n">color</span><span class="p">,</span><span class="n">age</span> <span class="k">FROM</span> <span class="n">hares</span><span class="p">.</span><span class="n">hare</span><span class="p">;</span>
</code></pre></div></div>
<h3 id="update-entities">Update Entities</h3>
<p>Updating existing entities are done very similar to how we read and persist entities. Changes made to a local copy of an entity will not affect the database until we call the <code class="highlighter-rouge">update()</code>-method in the manager.</p>
<p>In this case we take the hare Harry created earlier and we want to change his color to brown:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">harry</span><span class="o">.</span><span class="na">setColor</span><span class="o">(</span><span class="s">"brown"</span><span class="o">);</span>
<span class="kd">final</span> <span class="n">Hare</span> <span class="n">updatedHarry</span> <span class="o">=</span> <span class="n">hares</span><span class="o">.</span><span class="na">update</span><span class="o">(</span><span class="n">harry</span><span class="o">);</span>
</code></pre></div></div>
<p>The manager returns a new copy of the hare if the update is accepted, so we should continue using that instance after this point. Just like in the “create”-example, the update might fail. Maybe color was defined as a “unique” column and a “brown” hare already existed. In that case, a <code class="highlighter-rouge">SpeedmentException</code> is thrown.</p>
<p>We can also update multiple entities at the same time by combining it with a stream. Say that we want to make all hares named “Harry” brown. In that case, we do this:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">hares</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">Hare</span><span class="o">.</span><span class="na">NAME</span><span class="o">.</span><span class="na">equal</span><span class="o">(</span><span class="s">"Harry"</span><span class="o">))</span>
<span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="n">Hare</span><span class="o">.</span><span class="na">COLOR</span><span class="o">.</span><span class="na">setTo</span><span class="o">(</span><span class="s">"Brown"</span><span class="o">))</span>
<span class="o">.</span><span class="na">forEach</span><span class="o">(</span><span class="n">hares</span><span class="o">.</span><span class="na">updater</span><span class="o">());</span> <span class="c1">// Updates remaining elements in the Stream</span>
</code></pre></div></div>
<p>We should also wrap it in a try-catch to make sure we warn the user if a constraint failed.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">try</span> <span class="o">{</span>
<span class="n">hares</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">Hare</span><span class="o">.</span><span class="na">NAME</span><span class="o">.</span><span class="na">equal</span><span class="o">(</span><span class="s">"Harry"</span><span class="o">))</span>
<span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="n">Hare</span><span class="o">.</span><span class="na">COLOR</span><span class="o">.</span><span class="na">setTo</span><span class="o">(</span><span class="s">"Brown"</span><span class="o">))</span>
<span class="o">.</span><span class="na">forEach</span><span class="o">(</span><span class="n">hares</span><span class="o">.</span><span class="na">updater</span><span class="o">());</span>
<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="kd">final</span> <span class="n">SpeedmentException</span> <span class="n">ex</span><span class="o">)</span> <span class="o">{</span>
<span class="n">System</span><span class="o">.</span><span class="na">err</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">ex</span><span class="o">.</span><span class="na">getMessage</span><span class="o">());</span>
<span class="k">return</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>
<h3 id="removing-entities">Removing Entities</h3>
<p>The last CRUD operation we need to know is how to remove entities from the database. This is almost identical to the “update”. Say that we want to remove all hares older than 10 years. We then do this:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">try</span> <span class="o">{</span>
<span class="n">hares</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">Hare</span><span class="o">.</span><span class="na">AGE</span><span class="o">.</span><span class="na">greaterThan</span><span class="o">(</span><span class="mi">10</span><span class="o">))</span>
<span class="o">.</span><span class="na">forEach</span><span class="o">(</span><span class="n">hares</span><span class="o">.</span><span class="na">remover</span><span class="o">());</span> <span class="c1">// Removes remaining hares</span>
<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="kd">final</span> <span class="n">SpeedmentException</span> <span class="n">ex</span><span class="o">)</span> <span class="o">{</span>
<span class="n">System</span><span class="o">.</span><span class="na">err</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">ex</span><span class="o">.</span><span class="na">getMessage</span><span class="o">());</span>
<span class="k">return</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>
<h3 id="summary">Summary</h3>
<p>In this article you have learned how to set up Speedment in a Maven project and how to create, update, read and delete entities from a database using Java 8 Streams. This is only a small subset of all the things you can do with Speedment, but it serves as a good introduction to start getting your hands dirty. More examples and more advanced use-cases can be <a href="https://github.com/speedment/speedment/wiki">found on the GitHub-page</a>.</p>
<p>Until next time!</p>
<p><a href="http://ageofjava.com/java/Database-CRUD-Operations-in-Java-8-Streams">Database CRUD Operations in Java 8 Streams</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on October 24, 2016.</p>http://ageofjava.com/java/Event-Sourcing-and-CQRS-In-Practise2016-10-11T00:00:00-07:002016-10-11T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>Anyone that has tried to implement a fully ACID compliant system knows that there are a lot of considerations you have to do. You need to make sure database entities can be freely created, modified and deleted without the risk of errors, and in most cases, the solution will be at the cost of performance. One methodology that can be used to get around this is to design the system based on a series of events rather than mutable states. This is generally called Event Sourcing.</p>
<p>In this article I will showcase a demo application that uses the Open Source toolkit <a href="https://github.com/speedment/speedment">Speedment</a> to rapidly get a scalable event-sourced database application up and running. Full source code for the example <a href="https://github.com/Pyknic/speedment-sauna-example">is available here</a>.</p>
<p><img src="https://lh5.googleusercontent.com/Vw_FXOwoRQf8FLi-TxjL5z4VYESLs1EsQ2V5k3fXAZGTXFGgwnYZjxsFvC8VUtQU-XDeuOO9x9hA1Wvaqoqop5iH-rBISIV8OxQG43j9pkA_MJ37c174mYpaSLSzIMhdq2Lj1FmL" alt="Sauna.png" /></p>
<h2 id="what-is-event-sourcing">What is Event Sourcing?</h2>
<p>In a typical relational database system you store the <em>state</em> of an entity as a row in a database. When the state changes, the application modifies the row using an UPDATE or a DELETE-statement. A problem with this method is that it adds a lot of requirements on the database when it comes to making sure that no row is changed in a way that puts the system in an illegal state. You don’t want anyone to withdraw more money than they have in their account or bid on an auction that has already been closed.</p>
<p>In an event-sourced system, we take a different approach to this. Instead of storing the <em>state</em> of an entity in the database, you store the <em>series of changes</em> that led to that state. An event is immutable once it is created, meaning that you only have to implement two operations, CREATE and READ. If an entity is updated or removed, that is realized using the creation of an “update” or “remove” event.</p>
<p>An event sourced system can easily be scaled up to improve performance, as any node can simply download the event log and replay the current state. You also get better performance due to the fact that writing and querying is handled by different machines. This is referred to as CQRS (Command-Query Responsibility Segregation). As you will see in the examples, we can get an eventually consistent materialized view up and running in a very little time using the Speedment toolkit.</p>
<h2 id="the-bookable-sauna">The Bookable Sauna</h2>
<p>To showcase the workflow of building an event sourced system we will create a small application to handle the booking of a shared sauna in a housing complex. We have multiple tenants interested in booking the sauna, but we need to guarantee that the shy tenants never accidentally double-book it. We also want to support multiple saunas in the same system.</p>
<p>To simplify the communication with the database, we are going to use the <a href="https://github.com/speedment/speedment">Speedment toolkit</a>. Speedment is a java tool that allows us to generate a complete domain model from the database and also makes it easy to query the database using optimized Java 8 streams. Speedment is available under the Apache 2-license and there are a lot of great examples for different usages <a href="https://github.com/speedment/speedment/wiki/Speedment-API-Quick-Start">on the Github page</a>.</p>
<h4 id="step-1-define-the-database-schema">Step 1: Define the Database Schema</h4>
<p>The first step is to define our (MySQL) database. We simply have one table called “booking” where we store the events related to booking the sauna. Note that a booking is an event and not an entity. If we want to cancel a booking or make changes to it, we will have to publish additional events with the changes as new rows. We are not allowed to modify or delete a published row.</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">DATABASE</span> <span class="nv">`sauna`</span><span class="p">;</span>
<span class="k">CREATE</span> <span class="k">TABLE</span> <span class="nv">`sauna`</span><span class="p">.</span><span class="nv">`booking`</span> <span class="p">(</span>
<span class="nv">`id`</span> <span class="n">BIGINT</span> <span class="n">UNSIGNED</span> <span class="k">NOT</span> <span class="k">NULL</span> <span class="n">AUTO_INCREMENT</span><span class="p">,</span>
<span class="nv">`booking_id`</span> <span class="n">BIGINT</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
<span class="nv">`event_type`</span> <span class="n">ENUM</span><span class="p">(</span><span class="s1">'CREATE'</span><span class="p">,</span> <span class="s1">'UPDATE'</span><span class="p">,</span> <span class="s1">'DELETE'</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
<span class="nv">`tenant`</span> <span class="n">INT</span> <span class="k">NULL</span><span class="p">,</span>
<span class="nv">`sauna`</span> <span class="n">INT</span> <span class="k">NULL</span><span class="p">,</span>
<span class="nv">`booked_from`</span> <span class="n">DATE</span> <span class="k">NULL</span><span class="p">,</span>
<span class="nv">`booked_to`</span> <span class="n">DATE</span> <span class="k">NULL</span><span class="p">,</span>
<span class="k">PRIMARY</span> <span class="k">KEY</span> <span class="p">(</span><span class="nv">`id`</span><span class="p">)</span>
<span class="p">);</span>
</code></pre></div></div>
<p>The “id” column is an increasing integer that is assigned automatically every time a new event is published to the log. The “booking_id” tells us which booking we are referring to. If two events share the same booking id, they refer to the same entity. We also have an enum called “event_type” that describes which kind of operation we were trying to do. After that comes the information that belongs to the booking. If a column is NULL, we will consider that as unmodified compared to any previous value.</p>
<h4 id="step-2-generating-code-using-speedment">Step 2: Generating Code using Speedment</h4>
<p>The next step is to generate code for the project using Speedment. Simply create a new maven project and add the following code to the <code class="highlighter-rouge">pom.xml</code>-file.</p>
<h6 id="pomxml">pom.xml</h6>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><properties></span>
<span class="nt"><project.build.sourceEncoding></span>UTF-8<span class="nt"></project.build.sourceEncoding></span>
<span class="nt"><maven.compiler.source></span>1.8<span class="nt"></maven.compiler.source></span>
<span class="nt"><maven.compiler.target></span>1.8<span class="nt"></maven.compiler.target></span>
<span class="nt"><speedment.version></span>3.0.0-EA2<span class="nt"></speedment.version></span>
<span class="nt"><mysql.version></span>5.1.39<span class="nt"></mysql.version></span>
<span class="nt"></properties></span>
<span class="nt"><build></span>
<span class="nt"><plugins></span>
<span class="nt"><plugin></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>speedment-maven-plugin<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>mysql<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>mysql-connector-java<span class="nt"></artifactId></span>
<span class="nt"><version></span>${mysql.version}<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
<span class="nt"></plugin></span>
<span class="nt"></plugins></span>
<span class="nt"></build></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>mysql<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>mysql-connector-java<span class="nt"></artifactId></span>
<span class="nt"><version></span>${mysql.version}<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>runtime<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><type></span>pom<span class="nt"></type></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
</code></pre></div></div>
<p>If you build the project, a new maven goal called <strong>speedment:tool</strong> should appear in the IDE. Run it to launch the Speedment user interface. In there, connect to the Sauna database and generate code using the default settings. The project should now be populated with source files.</p>
<p><strong>Tip:</strong> If you make changes to the database, you can download the new configuration using the <strong>speedment:reload</strong>-goal and regenerate sources using <strong>speedment:generate</strong>. No need to relaunch the tool!</p>
<h4 id="step-3-creating-the-materialized-view">Step 3: Creating the Materialized View</h4>
<p>The materialized view is a component that regularly polls the database to see if any new rows have been added, and if so, downloads and merges them into the view in the correct order. Since the polling sometimes can take a lot of time, we want this process to run in a separate thread. We can accomplish that with a java <code class="highlighter-rouge">Timer</code> and <code class="highlighter-rouge">TimerTask</code>.</p>
<p><strong>Polling the database? Really?</strong> Well, an important thing to take into consideration is that it is only the server that will poll the database, not the clients. This gives us very good scalability since we can have a handful of servers polling the database that in turn serve hundreds of thousands of tenants. Compare this with a regular system where every client would request a resource from the server, that in turn contacts the database.</p>
<h6 id="bookingviewjava">BookingView.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">BookingView</span> <span class="o">{</span>
<span class="o">...</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="n">BookingView</span> <span class="nf">create</span><span class="o">(</span><span class="n">BookingManager</span> <span class="n">mgr</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">AtomicBoolean</span> <span class="n">working</span> <span class="o">=</span> <span class="k">new</span> <span class="n">AtomicBoolean</span><span class="o">(</span><span class="kc">false</span><span class="o">);</span>
<span class="kd">final</span> <span class="n">AtomicLong</span> <span class="n">last</span> <span class="o">=</span> <span class="k">new</span> <span class="n">AtomicLong</span><span class="o">();</span>
<span class="kd">final</span> <span class="n">AtomicLong</span> <span class="n">total</span> <span class="o">=</span> <span class="k">new</span> <span class="n">AtomicLong</span><span class="o">();</span>
<span class="kd">final</span> <span class="n">String</span> <span class="n">table</span> <span class="o">=</span> <span class="n">mgr</span><span class="o">.</span><span class="na">getTableIdentifier</span><span class="o">().</span><span class="na">getTableName</span><span class="o">();</span>
<span class="kd">final</span> <span class="n">String</span> <span class="n">field</span> <span class="o">=</span> <span class="n">Booking</span><span class="o">.</span><span class="na">ID</span><span class="o">.</span><span class="na">identifier</span><span class="o">().</span><span class="na">getColumnName</span><span class="o">();</span>
<span class="kd">final</span> <span class="n">Timer</span> <span class="n">timer</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Timer</span><span class="o">();</span>
<span class="kd">final</span> <span class="n">BookingView</span> <span class="n">view</span> <span class="o">=</span> <span class="k">new</span> <span class="n">BookingView</span><span class="o">(</span><span class="n">timer</span><span class="o">);</span>
<span class="kd">final</span> <span class="n">TimerTask</span> <span class="n">task</span> <span class="o">=</span> <span class="o">...;</span>
<span class="n">timer</span><span class="o">.</span><span class="na">scheduleAtFixedRate</span><span class="o">(</span><span class="n">task</span><span class="o">,</span> <span class="mi">0</span><span class="o">,</span> <span class="n">UPDATE_EVERY</span><span class="o">);</span>
<span class="k">return</span> <span class="n">view</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The timer task is defined anonymously and that is where the polling logic will reside.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="n">TimerTask</span> <span class="n">task</span> <span class="o">=</span> <span class="k">new</span> <span class="n">TimerTask</span><span class="o">()</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">run</span><span class="o">()</span> <span class="o">{</span>
<span class="kt">boolean</span> <span class="n">first</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span>
<span class="c1">// Make sure no previous task is already inside this block.</span>
<span class="k">if</span> <span class="o">(</span><span class="n">working</span><span class="o">.</span><span class="na">compareAndSet</span><span class="o">(</span><span class="kc">false</span><span class="o">,</span> <span class="kc">true</span><span class="o">))</span> <span class="o">{</span>
<span class="k">try</span> <span class="o">{</span>
<span class="c1">// Loop until no events was merged </span>
<span class="c1">// (the database is up to date).</span>
<span class="k">while</span> <span class="o">(</span><span class="kc">true</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">// Get a list of up to 25 events that has not yet </span>
<span class="c1">// been merged into the materialized object view.</span>
<span class="kd">final</span> <span class="n">List</span> <span class="n">added</span> <span class="o">=</span> <span class="n">unmodifiableList</span><span class="o">(</span>
<span class="n">mgr</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">Booking</span><span class="o">.</span><span class="na">ID</span><span class="o">.</span><span class="na">greaterThan</span><span class="o">(</span><span class="n">last</span><span class="o">.</span><span class="na">get</span><span class="o">()))</span>
<span class="o">.</span><span class="na">sorted</span><span class="o">(</span><span class="n">Booking</span><span class="o">.</span><span class="na">ID</span><span class="o">.</span><span class="na">comparator</span><span class="o">())</span>
<span class="o">.</span><span class="na">limit</span><span class="o">(</span><span class="n">MAX_BATCH_SIZE</span><span class="o">)</span>
<span class="o">.</span><span class="na">collect</span><span class="o">(</span><span class="n">toList</span><span class="o">())</span>
<span class="o">);</span>
<span class="k">if</span> <span class="o">(</span><span class="n">added</span><span class="o">.</span><span class="na">isEmpty</span><span class="o">())</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(!</span><span class="n">first</span><span class="o">)</span> <span class="o">{</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">format</span><span class="o">(</span>
<span class="s">"%s: View is up to date. A total of "</span> <span class="o">+</span>
<span class="s">"%d rows have been loaded.%n"</span><span class="o">,</span>
<span class="n">System</span><span class="o">.</span><span class="na">identityHashCode</span><span class="o">(</span><span class="n">last</span><span class="o">),</span>
<span class="n">total</span><span class="o">.</span><span class="na">get</span><span class="o">()</span>
<span class="o">);</span>
<span class="o">}</span>
<span class="k">break</span><span class="o">;</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">Booking</span> <span class="n">lastEntity</span> <span class="o">=</span>
<span class="n">added</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">added</span><span class="o">.</span><span class="na">size</span><span class="o">()</span> <span class="o">-</span> <span class="mi">1</span><span class="o">);</span>
<span class="n">last</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="n">lastEntity</span><span class="o">.</span><span class="na">getId</span><span class="o">());</span>
<span class="n">added</span><span class="o">.</span><span class="na">forEach</span><span class="o">(</span><span class="nl">view:</span><span class="o">:</span><span class="n">accept</span><span class="o">);</span>
<span class="n">total</span><span class="o">.</span><span class="na">addAndGet</span><span class="o">(</span><span class="n">added</span><span class="o">.</span><span class="na">size</span><span class="o">());</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">format</span><span class="o">(</span>
<span class="s">"%s: Downloaded %d row(s) from %s. "</span> <span class="o">+</span>
<span class="s">"Latest %s: %d.%n"</span><span class="o">,</span>
<span class="n">System</span><span class="o">.</span><span class="na">identityHashCode</span><span class="o">(</span><span class="n">last</span><span class="o">),</span>
<span class="n">added</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span>
<span class="n">table</span><span class="o">,</span>
<span class="n">field</span><span class="o">,</span>
<span class="n">Long</span><span class="o">.</span><span class="na">parseLong</span><span class="o">(</span><span class="s">""</span> <span class="o">+</span> <span class="n">last</span><span class="o">.</span><span class="na">get</span><span class="o">())</span>
<span class="o">);</span>
<span class="o">}</span>
<span class="n">first</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span>
<span class="c1">// Release this resource once we exit this block.</span>
<span class="o">}</span> <span class="k">finally</span> <span class="o">{</span>
<span class="n">working</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="kc">false</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">};</span>
</code></pre></div></div>
<p>Sometimes the merging task can take more time to complete than the interval of the timer. To avoid this causing a problem, we use an <code class="highlighter-rouge">AtomicBoolean</code> to check and make sure that only one task can execute at the same time. This is similar to a <code class="highlighter-rouge">Semaphore</code>, except that we want tasks that we don’t have time for to be dropped instead of queued since we don’t really need every task to execute, a new one will come in just a second.</p>
<p>The constructor and basic member methods are fairly easy to implement. We store the timer passed to the class as a parameter in the constructor so that we can cancel that timer if we ever need to stop. We also store a map that keeps the current view of all the bookings in memory.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="kd">final</span> <span class="kd">static</span> <span class="kt">int</span> <span class="n">MAX_BATCH_SIZE</span> <span class="o">=</span> <span class="mi">25</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="kd">static</span> <span class="kt">int</span> <span class="n">UPDATE_EVERY</span> <span class="o">=</span> <span class="mi">1_000</span><span class="o">;</span> <span class="c1">// Milliseconds</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">Timer</span> <span class="n">timer</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">Map</span><span class="o"><</span><span class="n">Long</span><span class="o">,</span> <span class="n">Booking</span><span class="o">></span> <span class="n">bookings</span><span class="o">;</span>
<span class="kd">private</span> <span class="nf">BookingView</span><span class="o">(</span><span class="n">Timer</span> <span class="n">timer</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">timer</span> <span class="o">=</span> <span class="n">requireNonNull</span><span class="o">(</span><span class="n">timer</span><span class="o">);</span>
<span class="k">this</span><span class="o">.</span><span class="na">bookings</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ConcurrentHashMap</span><span class="o"><>();</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="n">Stream</span><span class="o"><</span><span class="n">Booking</span><span class="o">></span> <span class="nf">stream</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">bookings</span><span class="o">.</span><span class="na">values</span><span class="o">().</span><span class="na">stream</span><span class="o">();</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">stop</span><span class="o">()</span> <span class="o">{</span>
<span class="n">timer</span><span class="o">.</span><span class="na">cancel</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The last missing piece of the <code class="highlighter-rouge">BookingView</code> class is the <code class="highlighter-rouge">accept()</code>-method used above in the merging procedure. This is where new events are taken into consideration and merged into the view.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="kt">boolean</span> <span class="nf">accept</span><span class="o">(</span><span class="n">Booking</span> <span class="n">ev</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">String</span> <span class="n">type</span> <span class="o">=</span> <span class="n">ev</span><span class="o">.</span><span class="na">getEventType</span><span class="o">();</span>
<span class="c1">// If this was a creation event</span>
<span class="k">switch</span> <span class="o">(</span><span class="n">type</span><span class="o">)</span> <span class="o">{</span>
<span class="k">case</span> <span class="s">"CREATE"</span> <span class="o">:</span>
<span class="c1">// Creation events must contain all information.</span>
<span class="k">if</span> <span class="o">(!</span><span class="n">ev</span><span class="o">.</span><span class="na">getSauna</span><span class="o">().</span><span class="na">isPresent</span><span class="o">()</span>
<span class="o">||</span> <span class="o">!</span><span class="n">ev</span><span class="o">.</span><span class="na">getTenant</span><span class="o">().</span><span class="na">isPresent</span><span class="o">()</span>
<span class="o">||</span> <span class="o">!</span><span class="n">ev</span><span class="o">.</span><span class="na">getBookedFrom</span><span class="o">().</span><span class="na">isPresent</span><span class="o">()</span>
<span class="o">||</span> <span class="o">!</span><span class="n">ev</span><span class="o">.</span><span class="na">getBookedTo</span><span class="o">().</span><span class="na">isPresent</span><span class="o">()</span>
<span class="o">||</span> <span class="o">!</span><span class="n">checkIfAllowed</span><span class="o">(</span><span class="n">ev</span><span class="o">))</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span>
<span class="c1">// If something is already mapped to that key, refuse the </span>
<span class="c1">// event.</span>
<span class="k">return</span> <span class="n">bookings</span><span class="o">.</span><span class="na">putIfAbsent</span><span class="o">(</span><span class="n">ev</span><span class="o">.</span><span class="na">getBookingId</span><span class="o">(),</span> <span class="n">ev</span><span class="o">)</span> <span class="o">==</span> <span class="kc">null</span><span class="o">;</span>
<span class="k">case</span> <span class="s">"UPDATE"</span> <span class="o">:</span>
<span class="c1">// Create a copy of the current state</span>
<span class="kd">final</span> <span class="n">Booking</span> <span class="n">existing</span> <span class="o">=</span> <span class="n">bookings</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">ev</span><span class="o">.</span><span class="na">getBookingId</span><span class="o">());</span>
<span class="c1">// If the specified key did not exist, refuse the event.</span>
<span class="k">if</span> <span class="o">(</span><span class="n">existing</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">Booking</span> <span class="n">proposed</span> <span class="o">=</span> <span class="k">new</span> <span class="n">BookingImpl</span><span class="o">();</span>
<span class="n">proposed</span><span class="o">.</span><span class="na">setId</span><span class="o">(</span><span class="n">existing</span><span class="o">.</span><span class="na">getId</span><span class="o">());</span>
<span class="c1">// Update non-null values</span>
<span class="n">proposed</span><span class="o">.</span><span class="na">setSauna</span><span class="o">(</span><span class="n">ev</span><span class="o">.</span><span class="na">getSauna</span><span class="o">().</span><span class="na">orElse</span><span class="o">(</span>
<span class="n">unwrap</span><span class="o">(</span><span class="n">existing</span><span class="o">.</span><span class="na">getSauna</span><span class="o">())</span>
<span class="o">));</span>
<span class="n">proposed</span><span class="o">.</span><span class="na">setTenant</span><span class="o">(</span><span class="n">ev</span><span class="o">.</span><span class="na">getTenant</span><span class="o">().</span><span class="na">orElse</span><span class="o">(</span>
<span class="n">unwrap</span><span class="o">(</span><span class="n">existing</span><span class="o">.</span><span class="na">getTenant</span><span class="o">())</span>
<span class="o">));</span>
<span class="n">proposed</span><span class="o">.</span><span class="na">setBookedFrom</span><span class="o">(</span><span class="n">ev</span><span class="o">.</span><span class="na">getBookedFrom</span><span class="o">().</span><span class="na">orElse</span><span class="o">(</span>
<span class="n">unwrap</span><span class="o">(</span><span class="n">existing</span><span class="o">.</span><span class="na">getBookedFrom</span><span class="o">())</span>
<span class="o">));</span>
<span class="n">proposed</span><span class="o">.</span><span class="na">setBookedTo</span><span class="o">(</span><span class="n">ev</span><span class="o">.</span><span class="na">getBookedTo</span><span class="o">().</span><span class="na">orElse</span><span class="o">(</span>
<span class="n">unwrap</span><span class="o">(</span><span class="n">existing</span><span class="o">.</span><span class="na">getBookedTo</span><span class="o">())</span>
<span class="o">));</span>
<span class="c1">// Make sure these changes are allowed.</span>
<span class="k">if</span> <span class="o">(</span><span class="n">checkIfAllowed</span><span class="o">(</span><span class="n">proposed</span><span class="o">))</span> <span class="o">{</span>
<span class="n">bookings</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="n">ev</span><span class="o">.</span><span class="na">getBookingId</span><span class="o">(),</span> <span class="n">proposed</span><span class="o">);</span>
<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="k">case</span> <span class="s">"DELETE"</span> <span class="o">:</span>
<span class="c1">// Remove the event if it exists, else refuse the event.</span>
<span class="k">return</span> <span class="n">bookings</span><span class="o">.</span><span class="na">remove</span><span class="o">(</span><span class="n">ev</span><span class="o">.</span><span class="na">getBookingId</span><span class="o">())</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">;</span>
<span class="k">default</span> <span class="o">:</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">format</span><span class="o">(</span>
<span class="s">"Unexpected type '%s' was refused.%n"</span><span class="o">,</span> <span class="n">type</span><span class="o">);</span>
<span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>In an event sourced system, the rules are not enforced when events are received but when they are materialized. Basically anyone can insert new events into the system as long as they do it in the end of the table. It is in this method that we choose to discard events that doesn’t follow the rules setup.</p>
<h4 id="step-4-example-usage">Step 4: Example Usage</h4>
<p>In this example, we will use the standard Speedment API to insert three new bookings into the database, two that are valid and a third that intersects one of the previous ones. We will then wait for the view to update and print out every booking made.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">...</span> <span class="n">params</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">SaunaApplication</span> <span class="n">app</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SaunaApplicationBuilder</span><span class="o">()</span>
<span class="o">.</span><span class="na">withPassword</span><span class="o">(</span><span class="s">"password"</span><span class="o">)</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
<span class="kd">final</span> <span class="n">BookingManager</span> <span class="n">bookings</span> <span class="o">=</span>
<span class="n">app</span><span class="o">.</span><span class="na">getOrThrow</span><span class="o">(</span><span class="n">BookingManager</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="kd">final</span> <span class="n">SecureRandom</span> <span class="n">rand</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SecureRandom</span><span class="o">();</span>
<span class="n">rand</span><span class="o">.</span><span class="na">setSeed</span><span class="o">(</span><span class="n">System</span><span class="o">.</span><span class="na">currentTimeMillis</span><span class="o">());</span>
<span class="c1">// Insert three new bookings into the system.</span>
<span class="n">bookings</span><span class="o">.</span><span class="na">persist</span><span class="o">(</span>
<span class="k">new</span> <span class="nf">BookingImpl</span><span class="o">()</span>
<span class="o">.</span><span class="na">setBookingId</span><span class="o">(</span><span class="n">rand</span><span class="o">.</span><span class="na">nextLong</span><span class="o">())</span>
<span class="o">.</span><span class="na">setEventType</span><span class="o">(</span><span class="s">"CREATE"</span><span class="o">)</span>
<span class="o">.</span><span class="na">setSauna</span><span class="o">(</span><span class="mi">1</span><span class="o">)</span>
<span class="o">.</span><span class="na">setTenant</span><span class="o">(</span><span class="mi">1</span><span class="o">)</span>
<span class="o">.</span><span class="na">setBookedFrom</span><span class="o">(</span><span class="n">Date</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">LocalDate</span><span class="o">.</span><span class="na">now</span><span class="o">().</span><span class="na">plus</span><span class="o">(</span><span class="mi">3</span><span class="o">,</span> <span class="n">DAYS</span><span class="o">)))</span>
<span class="o">.</span><span class="na">setBookedTo</span><span class="o">(</span><span class="n">Date</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">LocalDate</span><span class="o">.</span><span class="na">now</span><span class="o">().</span><span class="na">plus</span><span class="o">(</span><span class="mi">5</span><span class="o">,</span> <span class="n">DAYS</span><span class="o">)))</span>
<span class="o">);</span>
<span class="n">bookings</span><span class="o">.</span><span class="na">persist</span><span class="o">(</span>
<span class="k">new</span> <span class="nf">BookingImpl</span><span class="o">()</span>
<span class="o">.</span><span class="na">setBookingId</span><span class="o">(</span><span class="n">rand</span><span class="o">.</span><span class="na">nextLong</span><span class="o">())</span>
<span class="o">.</span><span class="na">setEventType</span><span class="o">(</span><span class="s">"CREATE"</span><span class="o">)</span>
<span class="o">.</span><span class="na">setSauna</span><span class="o">(</span><span class="mi">1</span><span class="o">)</span>
<span class="o">.</span><span class="na">setTenant</span><span class="o">(</span><span class="mi">2</span><span class="o">)</span>
<span class="o">.</span><span class="na">setBookedFrom</span><span class="o">(</span><span class="n">Date</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">LocalDate</span><span class="o">.</span><span class="na">now</span><span class="o">().</span><span class="na">plus</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="n">DAYS</span><span class="o">)))</span>
<span class="o">.</span><span class="na">setBookedTo</span><span class="o">(</span><span class="n">Date</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">LocalDate</span><span class="o">.</span><span class="na">now</span><span class="o">().</span><span class="na">plus</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="n">DAYS</span><span class="o">)))</span>
<span class="o">);</span>
<span class="n">bookings</span><span class="o">.</span><span class="na">persist</span><span class="o">(</span>
<span class="k">new</span> <span class="nf">BookingImpl</span><span class="o">()</span>
<span class="o">.</span><span class="na">setBookingId</span><span class="o">(</span><span class="n">rand</span><span class="o">.</span><span class="na">nextLong</span><span class="o">())</span>
<span class="o">.</span><span class="na">setEventType</span><span class="o">(</span><span class="s">"CREATE"</span><span class="o">)</span>
<span class="o">.</span><span class="na">setSauna</span><span class="o">(</span><span class="mi">1</span><span class="o">)</span>
<span class="o">.</span><span class="na">setTenant</span><span class="o">(</span><span class="mi">3</span><span class="o">)</span>
<span class="o">.</span><span class="na">setBookedFrom</span><span class="o">(</span><span class="n">Date</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">LocalDate</span><span class="o">.</span><span class="na">now</span><span class="o">().</span><span class="na">plus</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="n">DAYS</span><span class="o">)))</span>
<span class="o">.</span><span class="na">setBookedTo</span><span class="o">(</span><span class="n">Date</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">LocalDate</span><span class="o">.</span><span class="na">now</span><span class="o">().</span><span class="na">plus</span><span class="o">(</span><span class="mi">7</span><span class="o">,</span> <span class="n">DAYS</span><span class="o">)))</span>
<span class="o">);</span>
<span class="kd">final</span> <span class="n">BookingView</span> <span class="n">view</span> <span class="o">=</span> <span class="n">BookingView</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">bookings</span><span class="o">);</span>
<span class="c1">// Wait until the view is up-to-date.</span>
<span class="k">try</span> <span class="o">{</span> <span class="n">Thread</span><span class="o">.</span><span class="na">sleep</span><span class="o">(</span><span class="mi">5_000</span><span class="o">);</span> <span class="o">}</span>
<span class="k">catch</span> <span class="o">(</span><span class="kd">final</span> <span class="n">InterruptedException</span> <span class="n">ex</span><span class="o">)</span> <span class="o">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">RuntimeException</span><span class="o">(</span><span class="n">ex</span><span class="o">);</span>
<span class="o">}</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Current Bookings for Sauna 1:"</span><span class="o">);</span>
<span class="kd">final</span> <span class="n">SimpleDateFormat</span> <span class="n">dt</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SimpleDateFormat</span><span class="o">(</span><span class="s">"yyyy-MM-dd"</span><span class="o">);</span>
<span class="kd">final</span> <span class="n">Date</span> <span class="n">now</span> <span class="o">=</span> <span class="n">Date</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">LocalDate</span><span class="o">.</span><span class="na">now</span><span class="o">());</span>
<span class="n">view</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">Booking</span><span class="o">.</span><span class="na">SAUNA</span><span class="o">.</span><span class="na">equal</span><span class="o">(</span><span class="mi">1</span><span class="o">))</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">Booking</span><span class="o">.</span><span class="na">BOOKED_TO</span><span class="o">.</span><span class="na">greaterOrEqual</span><span class="o">(</span><span class="n">now</span><span class="o">))</span>
<span class="o">.</span><span class="na">sorted</span><span class="o">(</span><span class="n">Booking</span><span class="o">.</span><span class="na">BOOKED_FROM</span><span class="o">.</span><span class="na">comparator</span><span class="o">())</span>
<span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="n">b</span> <span class="o">-></span> <span class="n">String</span><span class="o">.</span><span class="na">format</span><span class="o">(</span>
<span class="s">"Booked from %s to %s by Tenant %d."</span><span class="o">,</span>
<span class="n">dt</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="n">b</span><span class="o">.</span><span class="na">getBookedFrom</span><span class="o">().</span><span class="na">get</span><span class="o">()),</span>
<span class="n">dt</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="n">b</span><span class="o">.</span><span class="na">getBookedTo</span><span class="o">().</span><span class="na">get</span><span class="o">()),</span>
<span class="n">b</span><span class="o">.</span><span class="na">getTenant</span><span class="o">().</span><span class="na">getAsInt</span><span class="o">()</span>
<span class="o">))</span>
<span class="o">.</span><span class="na">forEachOrdered</span><span class="o">(</span><span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">::</span><span class="n">println</span><span class="o">);</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"No more bookings!"</span><span class="o">);</span>
<span class="n">view</span><span class="o">.</span><span class="na">stop</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>
<p>If we run it, we get the following output:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>677772350: Downloaded 3 row(s) from booking. Latest id: 3.
677772350: View is up to date. A total of 3 rows have been loaded.
Current Bookings for Sauna 1:
Booked from 2016-10-11 to 2016-10-12 by Tenant 2.
Booked from 2016-10-13 to 2016-10-15 by Tenant 1.
No more bookings!
</code></pre></div></div>
<p>Full source code for this demo application is available <a href="https://github.com/Pyknic/speedment-sauna-example">on my GitHub page</a>. There you can also find many other examples on how to use Speedment in various scenarios to rapidly develop database applications.</p>
<h2 id="summary">Summary</h2>
<p>In this article we have developed a materialized view over a database table that evaluates events on materialization and not upon insertion. This makes it possible to spin up multiple instances of the application without having to worry about synchronizing them since they will be eventually consistent. We then finished by showing how the materialized view can be queried using the Speedment API to produce a list of current bookings.</p>
<p>Thank you for reading and please checkout <a href="https://github.com/speedment/speedment">more Speedment examples</a> at the Github page!</p>
<p><a href="http://ageofjava.com/java/Event-Sourcing-and-CQRS-In-Practise">Event-Sourcing and CQRS in Practise</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on October 11, 2016.</p>http://ageofjava.com/java/Insert-and-Read-From-Database-Using-JSON2016-08-10T00:00:00-07:002016-08-10T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>In this article we will create a plugin for <a href="https://github.com/speedment/speedment">Speedment</a> that generates serialization and deserialization logic using <a href="https://github.com/google/gson">Gson</a> to make it super easy to map between database entities and JSON strings. This will help to showcase the extendability of the Speedment code generation while at the same time explore some of the cool features of the Gson library.</p>
<p>Speedment is a code generation tool for java that connects to a database and use it as a reference for generating entity and manager files for your project. The tool is very modular, allowing you to write your own plugins that modify the way the resulting code will look. One thing several people have mentioned on the Gitter chat is that Speedment entities are declared abstract which prevents them from being automatically deserialized. In this article we will look at how you can deserialize Speedment entities using Gson by automatically generating a custom TypeAdapter for each table in the database. This will not only give us better performance when working with JSON representations of database content, but might also serve as a general example on how you can extend the code generator to solve your problems.</p>
<p><img src="https://lh5.googleusercontent.com/L62CgdVcpG0O0aC6u1BiY-HXy_9y08-oZ337B5ZjaWh4t2RJQwz6cEARAxlhN9ZC8hFwepJngXNg9EvNs3t6MHt8hR34LQy3B1EsbK4HfvuLnrdCON82Pm5H1De9t8U8DUUzj8SN" alt="Spire and Duke downloading stuff from a database" /></p>
<h3 id="step-1-creating-the-plugin-project">Step 1: Creating the Plugin Project</h3>
<p><a href="/website/java/Generate-Customized-Code-With-Plugins">In a previous article</a> I went into detail on how to create a new plugin for Speedment, so here is the short version. Create a new maven project and set Speedment and Gson as dependencies.</p>
<h6 id="pomxml">pom.xml</h6>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><name></span>Speedment Gson Plugin<span class="nt"></name></span>
<span class="nt"><description></span>
A plugin for Speedment that generates Gson Type Adapters for every
table in the database.
<span class="nt"></description></span>
<span class="nt"><properties></span>
<span class="nt"><project.build.sourceEncoding></span>UTF-8<span class="nt"></project.build.sourceEncoding></span>
<span class="nt"><maven.compiler.source></span>1.8<span class="nt"></maven.compiler.source></span>
<span class="nt"><maven.compiler.target></span>1.8<span class="nt"></maven.compiler.target></span>
<span class="nt"><speedment.version></span>2.3.7<span class="nt"></speedment.version></span>
<span class="nt"></properties></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>speedment<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"><dependency></span>
<span class="nt"><artifactId></span>gson<span class="nt"></artifactId></span>
<span class="nt"><groupId></span>com.google.code.gson<span class="nt"></groupId></span>
<span class="nt"><version></span>2.6.2<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
</code></pre></div></div>
<h3 id="step-2-create-a-translator-class-for-the-type-adapter">Step 2: Create a Translator Class for the Type Adapter</h3>
<p>Next we need to create the translator that will generate the new type adapter for us. A translator is a class that describes what name, path and content a generated file will have. To that it has a lot of convenience methods to make it easier to generate the code. The basic structure of the translator is shown below.</p>
<h6 id="generatedtypeadaptertranslatorjava">GeneratedTypeAdapterTranslator.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">...</span>
<span class="kd">public</span> <span class="nf">GeneratedTypeAdapterTranslator</span><span class="o">(</span>
<span class="n">Speedment</span> <span class="n">speedment</span><span class="o">,</span> <span class="n">Generator</span> <span class="n">gen</span><span class="o">,</span> <span class="n">Table</span> <span class="n">table</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">(</span><span class="n">speedment</span><span class="o">,</span> <span class="n">gen</span><span class="o">,</span> <span class="n">table</span><span class="o">,</span> <span class="nl">Class:</span><span class="o">:</span><span class="n">of</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="n">Class</span> <span class="nf">makeCodeGenModel</span><span class="o">(</span><span class="n">File</span> <span class="n">file</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="nf">newBuilder</span><span class="o">(</span><span class="n">file</span><span class="o">,</span> <span class="n">getClassOrInterfaceName</span><span class="o">())</span>
<span class="o">.</span><span class="na">forEveryTable</span><span class="o">((</span><span class="n">clazz</span><span class="o">,</span> <span class="n">table</span><span class="o">)</span> <span class="o">-></span> <span class="o">{</span>
<span class="c1">// Code generation goes here</span>
<span class="o">}).</span><span class="na">build</span><span class="o">();</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="n">String</span> <span class="nf">getClassOrInterfaceName</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="s">"Generated"</span> <span class="o">+</span> <span class="n">getSupport</span><span class="o">().</span><span class="na">typeName</span><span class="o">()</span> <span class="o">+</span> <span class="s">"TypeAdapter"</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="n">String</span> <span class="nf">getJavadocRepresentText</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="s">"A Gson Type Adapter"</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">isInGeneratedPackage</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">...</span>
</code></pre></div></div>
<p>Every translator is built up using a builder pattern that can be invoked using the <code class="highlighter-rouge">newBuilder()</code>-method. This becomes important later on when we want to modify an existing translator. The actual code is generated inside the builder’s <code class="highlighter-rouge">forEveryTable()</code>-method. It is a callback that will be executed for every table that is encountered in the scope of interest. In this case, the translator will only execute on one table at a time so the callback will only be executed once.</p>
<p>For complete sources for the <code class="highlighter-rouge">GeneratedTypeAdapterTranslator</code>-class, please go to <a href="https://github.com/Pyknic/speedment-gson-plugin/blob/master/src/main/java/com/speedment/plugins/gson/GeneratedTypeAdapterTranslator.java">this github page</a>.</p>
<h3 id="step-3-create-decorator-for-modifying-the-manager-interface">Step 3: Create Decorator for Modifying the Manager Interface</h3>
<p>Generating a bunch of <code class="highlighter-rouge">TypeAdapters</code> is not enough though. We want to integrate the new code into the already existing managers. To do this, we need to define a decorator that will be applied to every generated manager after the default logic has been executed.</p>
<h6 id="generatedmanagerdecoratorjava">GeneratedManagerDecorator.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">GeneratedManagerDecorator</span>
<span class="kd">implements</span> <span class="n">TranslatorDecorator</span><span class="o"><</span><span class="n">Table</span><span class="o">,</span> <span class="n">Interface</span><span class="o">></span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">apply</span><span class="o">(</span><span class="n">JavaClassTranslator</span><span class="o"><</span><span class="n">Table</span><span class="o">,</span> <span class="n">Interface</span><span class="o">></span> <span class="n">translator</span><span class="o">)</span> <span class="o">{</span>
<span class="n">translator</span><span class="o">.</span><span class="na">onMake</span><span class="o">((</span><span class="n">file</span><span class="o">,</span> <span class="n">builder</span><span class="o">)</span> <span class="o">-></span> <span class="o">{</span>
<span class="n">builder</span><span class="o">.</span><span class="na">forEveryTable</span><span class="o">(</span><span class="n">Translator</span><span class="o">.</span><span class="na">Phase</span><span class="o">.</span><span class="na">POST_MAKE</span><span class="o">,</span>
<span class="o">(</span><span class="n">clazz</span><span class="o">,</span> <span class="n">table</span><span class="o">)</span> <span class="o">-></span> <span class="o">{</span>
<span class="n">clazz</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">Method</span><span class="o">.</span><span class="na">of</span><span class="o">(</span>
<span class="s">"fromJson"</span><span class="o">,</span>
<span class="n">translator</span><span class="o">.</span><span class="na">getSupport</span><span class="o">().</span><span class="na">entityType</span><span class="o">()</span>
<span class="o">).</span><span class="na">add</span><span class="o">(</span><span class="n">Field</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"json"</span><span class="o">,</span> <span class="n">STRING</span><span class="o">)));</span>
<span class="o">});</span>
<span class="o">});</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>A decorator is similar to a translator, except it only defines the changes that should be done to an existing file. Every decorator executes in a specific phase. In our case we want to execute after the default code has been generated, so we select <code class="highlighter-rouge">POST_MAKE</code>. The logic we want to add is simple. In the interface, we want an additional method <code class="highlighter-rouge">fromJson(String)</code> to be required. We don’t need to define a <code class="highlighter-rouge">toJson</code> since every Speedment manager already has that from an inherited interface.</p>
<h3 id="step-4-create-decorator-for-modifying-the-manager-implementation">Step 4: Create Decorator for Modifying the Manager Implementation</h3>
<p>The manager implementation is a bit trickier to modify. We need to append it with a Gson instance as a member variable, a implementation for the new interface method we just added, an override for the <code class="highlighter-rouge">toJson</code>-method that uses Gson instead of the built-in serializer and we need to modify the manager constructor to instantiate Gson using our new <code class="highlighter-rouge">TypeAdapter</code>.</p>
<h6 id="generatedmanagerimpldecoratorjava">GeneratedManagerImplDecorator.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">GeneratedManagerImplDecorator</span>
<span class="kd">implements</span> <span class="n">TranslatorDecorator</span><span class="o"><</span><span class="n">Table</span><span class="o">,</span> <span class="n">Class</span><span class="o">></span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">apply</span><span class="o">(</span><span class="n">JavaClassTranslator</span><span class="o"><</span><span class="n">Table</span><span class="o">,</span> <span class="n">Class</span><span class="o">></span> <span class="n">translator</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">String</span> <span class="n">entityName</span> <span class="o">=</span> <span class="n">translator</span><span class="o">.</span><span class="na">getSupport</span><span class="o">().</span><span class="na">entityName</span><span class="o">();</span>
<span class="kd">final</span> <span class="n">String</span> <span class="n">typeAdapterName</span> <span class="o">=</span> <span class="s">"Generated"</span> <span class="o">+</span> <span class="n">entityName</span> <span class="o">+</span>
<span class="s">"TypeAdapter"</span><span class="o">;</span>
<span class="kd">final</span> <span class="n">String</span> <span class="n">absoluteTypeAdapterName</span> <span class="o">=</span>
<span class="n">translator</span><span class="o">.</span><span class="na">getSupport</span><span class="o">().</span><span class="na">basePackageName</span><span class="o">()</span> <span class="o">+</span> <span class="s">".generated."</span> <span class="o">+</span>
<span class="n">typeAdapterName</span><span class="o">;</span>
<span class="n">Final</span> <span class="n">Type</span> <span class="n">entityType</span> <span class="o">=</span> <span class="n">translator</span><span class="o">.</span><span class="na">getSupport</span><span class="o">().</span><span class="na">entityType</span><span class="o">();</span>
<span class="n">translator</span><span class="o">.</span><span class="na">onMake</span><span class="o">((</span><span class="n">file</span><span class="o">,</span> <span class="n">builder</span><span class="o">)</span> <span class="o">-></span> <span class="o">{</span>
<span class="n">builder</span><span class="o">.</span><span class="na">forEveryTable</span><span class="o">(</span><span class="n">Translator</span><span class="o">.</span><span class="na">Phase</span><span class="o">.</span><span class="na">POST_MAKE</span><span class="o">,</span>
<span class="o">(</span><span class="n">clazz</span><span class="o">,</span> <span class="n">table</span><span class="o">)</span> <span class="o">-></span> <span class="o">{</span>
<span class="c1">// Make sure GsonBuilder and the generated type adapter </span>
<span class="c1">// are imported.</span>
<span class="n">file</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">Import</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="n">Type</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="n">GsonBuilder</span><span class="o">.</span><span class="na">class</span><span class="o">)));</span>
<span class="n">file</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">Import</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="n">Type</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="n">absoluteTypeAdapterName</span><span class="o">)));</span>
<span class="c1">// Add a Gson instance as a private member</span>
<span class="n">clazz</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">Field</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"gson"</span><span class="o">,</span> <span class="n">Type</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="n">Gson</span><span class="o">.</span><span class="na">class</span><span class="o">))</span>
<span class="o">.</span><span class="na">private_</span><span class="o">().</span><span class="na">final_</span><span class="o">()</span>
<span class="o">);</span>
<span class="c1">// Find the constructor and define gson in it</span>
<span class="n">clazz</span><span class="o">.</span><span class="na">getConstructors</span><span class="o">().</span><span class="na">forEach</span><span class="o">(</span><span class="n">constr</span> <span class="o">-></span> <span class="o">{</span>
<span class="n">constr</span><span class="o">.</span><span class="na">add</span><span class="o">(</span>
<span class="s">"this.gson = new GsonBuilder()"</span><span class="o">,</span>
<span class="n">indent</span><span class="o">(</span><span class="s">".setDateFormat(\""</span> <span class="o">+</span> <span class="n">DATE_FORMAT</span> <span class="o">+</span> <span class="s">"\")"</span><span class="o">),</span>
<span class="n">indent</span><span class="o">(</span><span class="s">".registerTypeAdapter("</span> <span class="o">+</span> <span class="n">entityName</span> <span class="o">+</span>
<span class="s">".class, new "</span> <span class="o">+</span> <span class="n">typeAdapterName</span> <span class="o">+</span> <span class="s">"(this))"</span><span class="o">),</span>
<span class="n">indent</span><span class="o">(</span><span class="s">".create();"</span><span class="o">)</span>
<span class="o">);</span>
<span class="o">});</span>
<span class="c1">// Override the toJson()-method</span>
<span class="n">clazz</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">Method</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"toJson"</span><span class="o">,</span> <span class="n">STRING</span><span class="o">)</span>
<span class="o">.</span><span class="na">public_</span><span class="o">().</span><span class="na">add</span><span class="o">(</span><span class="n">OVERRIDE</span><span class="o">)</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">Field</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"entity"</span><span class="o">,</span> <span class="n">entityType</span><span class="o">))</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"return gson.toJson(entity, "</span> <span class="o">+</span> <span class="n">entityName</span> <span class="o">+</span>
<span class="s">".class);"</span>
<span class="o">)</span>
<span class="o">);</span>
<span class="c1">// Override the fromJson()-method</span>
<span class="n">clazz</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">Method</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"fromJson"</span><span class="o">,</span> <span class="n">entityType</span><span class="o">)</span>
<span class="o">.</span><span class="na">public_</span><span class="o">().</span><span class="na">add</span><span class="o">(</span><span class="n">OVERRIDE</span><span class="o">)</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">Field</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"json"</span><span class="o">,</span> <span class="n">STRING</span><span class="o">))</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"return gson.fromJson(json, "</span> <span class="o">+</span> <span class="n">entityName</span> <span class="o">+</span>
<span class="s">".class);"</span>
<span class="o">)</span>
<span class="o">);</span>
<span class="o">});</span>
<span class="o">});</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h3 id="step-5-install-all-the-new-classes-into-the-platform">Step 5: Install All the New Classes into the Platform</h3>
<p>Once we have created all the new classes, we need to create a component and a component installer that can be referenced from any project where we want to use the plugin.</p>
<h6 id="gsoncomponentjava">GsonComponent.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">GsonComponent</span> <span class="kd">extends</span> <span class="n">AbstractComponent</span> <span class="o">{</span>
<span class="kd">public</span> <span class="nf">GsonComponent</span><span class="o">(</span><span class="n">Speedment</span> <span class="n">speedment</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">(</span><span class="n">speedment</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">onResolve</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">CodeGenerationComponent</span> <span class="n">code</span> <span class="o">=</span>
<span class="n">getSpeedment</span><span class="o">().</span><span class="na">getCodeGenerationComponent</span><span class="o">();</span>
<span class="n">code</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="n">Table</span><span class="o">.</span><span class="na">class</span><span class="o">,</span>
<span class="n">GeneratedTypeAdapterTranslator</span><span class="o">.</span><span class="na">KEY</span><span class="o">,</span>
<span class="nl">GeneratedTypeAdapterTranslator:</span><span class="o">:</span><span class="k">new</span>
<span class="o">);</span>
<span class="n">code</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">Table</span><span class="o">.</span><span class="na">class</span><span class="o">,</span>
<span class="n">StandardTranslatorKey</span><span class="o">.</span><span class="na">GENERATED_MANAGER</span><span class="o">,</span>
<span class="k">new</span> <span class="nf">GeneratedManagerDecorator</span><span class="o">()</span>
<span class="o">);</span>
<span class="n">code</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">Table</span><span class="o">.</span><span class="na">class</span><span class="o">,</span>
<span class="n">StandardTranslatorKey</span><span class="o">.</span><span class="na">GENERATED_MANAGER_IMPL</span><span class="o">,</span>
<span class="k">new</span> <span class="nf">GeneratedManagerImplDecorator</span><span class="o">()</span>
<span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Class</span><span class="o"><</span><span class="n">GsonComponent</span><span class="o">></span> <span class="nf">getComponentClass</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">GsonComponent</span><span class="o">.</span><span class="na">class</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Software</span> <span class="nf">asSoftware</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">AbstractSoftware</span><span class="o">.</span><span class="na">with</span><span class="o">(</span><span class="s">"Gson Plugin"</span><span class="o">,</span> <span class="s">"1.0"</span><span class="o">,</span> <span class="n">APACHE_2</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Component</span> <span class="nf">defaultCopy</span><span class="o">(</span><span class="n">Speedment</span> <span class="n">speedment</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">GsonComponent</span><span class="o">(</span><span class="n">speedment</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h6 id="gsoncomponentinstallerjava">GsonComponentInstaller.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">GsonComponentInstaller</span>
<span class="kd">implements</span> <span class="n">ComponentConstructor</span><span class="o"><</span><span class="n">GsonComponent</span><span class="o">></span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">GsonComponent</span> <span class="nf">create</span><span class="o">(</span><span class="n">Speedment</span> <span class="n">speedment</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">GsonComponent</span><span class="o">(</span><span class="n">speedment</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h3 id="usage">Usage</h3>
<p>When we want to use our new plugin in a project, we simply add it as a dependency both in the dependency section in the pom and as a dependency under the speedment maven plugin. We then add a configuration tag to the plugin like below:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><plugin></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>speedment-maven-plugin<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.speedment.plugins<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>gson<span class="nt"></artifactId></span>
<span class="nt"><version></span>1.0.0<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>mysql<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>mysql-connector-java<span class="nt"></artifactId></span>
<span class="nt"><version></span>5.1.39<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
<span class="nt"><configuration></span>
<span class="nt"><components></span>
<span class="nt"><component</span> <span class="na">implementation=</span><span class="s">"com.speedment.plugins.gson.GsonComponentInstaller"</span> <span class="nt">/></span>
<span class="nt"></components></span>
<span class="nt"></configuration></span>
<span class="nt"></plugin></span>
</code></pre></div></div>
<p>We can then regenerate our code and we should then have access to the new serialization and deserialization logic.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="n">String</span> <span class="n">pippi</span> <span class="o">=</span> <span class="s">"{"</span> <span class="o">+</span>
<span class="s">"\"id\":1,"</span> <span class="o">+</span>
<span class="s">"\"bookId\":-8043771945249889258,"</span> <span class="o">+</span>
<span class="s">"\"borrowedStatus\":\"AVAILABLE\","</span> <span class="o">+</span>
<span class="s">"\"title\":\"Pippi Långström\","</span> <span class="o">+</span>
<span class="s">"\"authors\":\"Astrid Lindgren\","</span> <span class="o">+</span>
<span class="s">"\"published\":\"1945-11-26\","</span> <span class="o">+</span>
<span class="s">"\"summary\":\"A story about the world's strongest little girl.\""</span> <span class="o">+</span>
<span class="s">"}"</span><span class="o">;</span>
<span class="n">books</span><span class="o">.</span><span class="na">fromJson</span><span class="o">(</span><span class="n">pippi</span><span class="o">).</span><span class="na">persist</span><span class="o">();</span>
</code></pre></div></div>
<h3 id="summary">Summary</h3>
<p>In this article we have created a new Speedment plugin that generated Gson <code class="highlighter-rouge">TypeAdapters</code> for every table in a database and integrates those adapters with the existing manager generation. If you want more examples on how you can use the Speedment code generator to increase your productivity, <a href="https://github.com/speedment/speedment">check out the GitHub page</a>!</p>
<p>Until next time!</p>
<p><a href="http://ageofjava.com/java/Insert-and-Read-From-Database-Using-JSON">How To - Insert and Read From a Database using Json</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on August 10, 2016.</p>http://ageofjava.com/java/Generate-Customized-Code-With-Plugins2016-04-12T00:00:00-07:002016-04-12T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>One thing most programmers hate is to write boilerplate code. Endless hours are spent setting up entity classes and configuring database connections. To avoid this you can let a program like <a href="https://github.com/speedment/speedment">Speedment Open Source</a> generate all this code for you. This makes it easy to get a database project up and running with minimal manual labour, but how do you maintain control of the written code when large parts of it is handed over to a machine?</p>
<p>Say that you have a database with a table “user” which has a column “gender”, and you want that implemented as an <code class="highlighter-rouge">enum</code> in java. If you run Speedment and use it to generate code, the “gender” field will be represented as a <code class="highlighter-rouge">String</code>. The reason for this is that there isn’t any built-in mappers for converting between database <code class="highlighter-rouge">ENUM</code>s and custom java classes. This is one of those cases when you might feel that the generator is taking away control for you. Well, fear not, for since the <a href="https://github.com/speedment/speedment/releases/tag/2.3.0">2.3 Hamilton release</a>, you can get this same control by creating your own plugin for Speedment!</p>
<h3 id="the-goal-of-this-article">The Goal of this Article</h3>
<p><img src="https://3.bp.blogspot.com/-RW17_QWuHJ4/Vww7_A44imI/AAAAAAAAEwA/p-wUFmNjNeYv2XmxpMD03DHtP22eEullQCLcB/s640/PLUGIN2.png" alt="Spire and Duke are plugging Components into Speedment" /></p>
<p>In this example we have a database schema with a table called “Person”. A person has an id, a name and a gender. The gender is declared as an <code class="highlighter-rouge">ENUM</code> with three possible values: “Male”, “Female” and “Other”. If we use the default settings in Speedment to generate this class, Speedment will consider the <code class="highlighter-rouge">ENUM</code> a <code class="highlighter-rouge">String</code>. There are some issues with this however. For an example, if you want to persist a new person into the database, there is nothing that prevents you from spelling a gender wrong and getting an exception when you do the insert. Instead, we want to define a java <code class="highlighter-rouge">enum</code> with the specified alternatives as constants. What would make the generated code more secure and easier to use.</p>
<p>We can achieve this using a plugin for Speedment!</p>
<h3 id="creating-the-plugin-project">Creating the Plugin Project</h3>
<p>To do any custom modifications to the Speedment platform we will need to define a plugin. A plugin is a piece of software that can be plugged into the Speedment runtime from the <code class="highlighter-rouge">pom.xml</code>-file. The plugin resides in its own maven project and can be shared between projects.</p>
<p>Begin by creating a new Maven Project and declare Speedment as a dependency. You will not need the <code class="highlighter-rouge">speedment-maven-plugin</code> in this project.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>speedment<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"></dependency></span>
</code></pre></div></div>
<p>The plugin system revolves around two interfaces; <code class="highlighter-rouge">Component</code> and <code class="highlighter-rouge">ComponentConstructor</code>. A <code class="highlighter-rouge">Component</code> is a pluggable piece of software that can be executed as part of the Speedment lifecycle. Every component has a number of stages in which it is allowed to execute. These are “initialize”, “load”, “resolve” and “start”.</p>
<p>The <code class="highlighter-rouge">ComponentConstructor</code> is a lightweight type that has a default constructor and a method for initializing new instances of the custom component. This is used by the maven plugin to setup the new code.</p>
<p>Here is how our two implementations will look:</p>
<h6 id="custommappingcomponentjava">CustomMappingComponent.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">CustomMappingComponent</span>
<span class="kd">extends</span> <span class="n">AbstractComponent</span> <span class="o">{</span>
<span class="n">CustomMappingComponent</span><span class="o">(</span><span class="n">Speedment</span> <span class="n">speedment</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">(</span><span class="n">speedment</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">onResolve</span><span class="o">()</span> <span class="o">{</span>
<span class="c1">// Resolve logic here...</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Class</span><span class="o"><</span><span class="n">CustomMappingComponent</span><span class="o">></span> <span class="nf">getComponentClass</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">CustomMappingComponent</span><span class="o">.</span><span class="na">class</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Software</span> <span class="nf">asSoftware</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">AbstractSoftware</span><span class="o">.</span><span class="na">with</span><span class="o">(</span>
<span class="s">"Custom Mapping Component"</span><span class="o">,</span>
<span class="s">"1.0"</span><span class="o">,</span>
<span class="n">APACHE_2</span>
<span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Component</span> <span class="nf">defaultCopy</span><span class="o">(</span><span class="n">Speedment</span> <span class="n">speedment</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">CustomMappingComponent</span><span class="o">(</span><span class="n">speedment</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h6 id="custommappingcomponentinstallerjava">CustomMappingComponentInstaller.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">CustomMappingComponentInstaller</span>
<span class="kd">implements</span> <span class="n">ComponentConstructor</span><span class="o"><</span><span class="n">CustomMappingComponent</span><span class="o">></span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Component</span> <span class="nf">create</span><span class="o">(</span><span class="n">Speedment</span> <span class="n">speedment</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">CustomMappingComponent</span><span class="o">(</span><span class="n">speedment</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>We now have a bare-bone plugin that can be added to a Speedment project. The next step is to define the logic that maps between strings and genders. To this this, first we need the <code class="highlighter-rouge">Gender</code> enum.</p>
<h6 id="genderjava">Gender.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">enum</span> <span class="n">Gender</span> <span class="o">{</span>
<span class="n">MALE</span> <span class="o">(</span><span class="s">"Male"</span><span class="o">),</span>
<span class="n">FEMALE</span> <span class="o">(</span><span class="s">"Female"</span><span class="o">),</span>
<span class="n">OTHER</span> <span class="o">(</span><span class="s">"Other"</span><span class="o">);</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">databaseName</span><span class="o">;</span>
<span class="n">Gender</span><span class="o">(</span><span class="n">String</span> <span class="n">databaseName</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">databaseName</span> <span class="o">=</span> <span class="n">databaseName</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="n">String</span> <span class="nf">getDatabaseName</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">databaseName</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>If you store the enum values in upper-case in the database, this class could be much shorter since you could simply use the <code class="highlighter-rouge">Enum.name()</code>-method to get the database name, but this approach is better if you want flexibility in naming the constants.</p>
<p>Now for the final piece. We need to declare a type that implements the <code class="highlighter-rouge">TypeMapper</code>-interface in Speedment. A type mapper is really simple. It contains two methods for mapping to and from the database type as well as methods for retrieving the java class of both types.</p>
<h6 id="stringtogendermapperjava">StringToGenderMapper.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">StringToGenderMapper</span> <span class="kd">implements</span> <span class="n">TypeMapper</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">Gender</span><span class="o">></span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Class</span><span class="o"><</span><span class="n">Gender</span><span class="o">></span> <span class="nf">getJavaType</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">Gender</span><span class="o">.</span><span class="na">class</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Class</span><span class="o"><</span><span class="n">String</span><span class="o">></span> <span class="nf">getDatabaseType</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">String</span><span class="o">.</span><span class="na">class</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Gender</span> <span class="nf">toJavaType</span><span class="o">(</span><span class="n">String</span> <span class="n">value</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">value</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">Stream</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="n">Gender</span><span class="o">.</span><span class="na">values</span><span class="o">())</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">g</span> <span class="o">-></span> <span class="n">g</span><span class="o">.</span><span class="na">getDatabaseName</span><span class="o">().</span><span class="na">equals</span><span class="o">(</span><span class="n">value</span><span class="o">))</span>
<span class="o">.</span><span class="na">findAny</span><span class="o">()</span>
<span class="o">.</span><span class="na">orElseThrow</span><span class="o">(()</span> <span class="o">-></span>
<span class="k">new</span> <span class="nf">UnsupportedOperationException</span><span class="o">(</span>
<span class="s">"Unknown gender '"</span> <span class="o">+</span> <span class="n">value</span> <span class="o">+</span> <span class="s">"'."</span>
<span class="o">)</span>
<span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">String</span> <span class="nf">toDatabaseType</span><span class="o">(</span><span class="n">Gender</span> <span class="n">value</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">value</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
<span class="k">else</span> <span class="k">return</span> <span class="n">value</span><span class="o">.</span><span class="na">getDatabaseName</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">isIdentityMapper</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>This new mapper also need to be installed in the Speedment platform. We can do that from the component we created earlier by modifying the <code class="highlighter-rouge">onResolve()</code>-method:</p>
<h6 id="custommappingcomponentjava-1">CustomMappingComponent.java</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">onResolve</span><span class="o">()</span> <span class="o">{</span>
<span class="c1">// Resolve logic here...</span>
<span class="n">getSpeedment</span><span class="o">().</span><span class="na">getTypeMapperComponent</span><span class="o">()</span>
<span class="o">.</span><span class="na">install</span><span class="o">(</span><span class="nl">StringToGenderMapper:</span><span class="o">:</span><span class="k">new</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Our new plugin is now done! Build the project and you are set to go!</p>
<h3 id="using-the-plugin">Using the Plugin</h3>
<p>To use a plugin in a project, you only need to modify the <code class="highlighter-rouge">pom.xml</code>-file of that project. Open up an existing Speedment project and locate the <code class="highlighter-rouge">pom.xml</code>-file. In it, you should be able to find the <code class="highlighter-rouge">speedment-maven-plugin</code>. To make your own plugin accessible for the maven plugin, you need to add it as a dependency inside the <code class="highlighter-rouge"><plugin></code>-tag and add the <code class="highlighter-rouge">ComponentInstaller</code> to the configuration. Here is an example of how it can look:</p>
<h6 id="pomxml">pom.xml</h6>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><plugin></span>
<span class="nt"><groupId></span>com.speedment<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>speedment-maven-plugin<span class="nt"></artifactId></span>
<span class="nt"><version></span>${speedment.version}<span class="nt"></version></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>mysql<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>mysql-connector-java<span class="nt"></artifactId></span>
<span class="nt"><version></span>${mysql.version}<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="c"><!-- Our plugin project --></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.github.pyknic<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>custom-mapping-component<span class="nt"></artifactId></span>
<span class="nt"><version></span>1.0.0-SNAPSHOT<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
<span class="nt"><configuration></span>
<span class="nt"><components></span>
<span class="c"><!-- Path to the component installer --></span>
<span class="nt"><component</span> <span class="na">implementation=</span><span class="s">"
com.github.pyknic.salesinfo.plugin.CustomMappingComponentInstaller
"</span> <span class="nt">/></span>
<span class="nt"></components></span>
<span class="nt"></configuration></span>
<span class="nt"></plugin></span>
</code></pre></div></div>
<p>You also need to add the project as a runtime dependency since the new <code class="highlighter-rouge">Gender</code>-enum must be accessible from the generated code.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><dependencies></span>
...
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.github.pyknic<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>custom-mapping-component<span class="nt"></artifactId></span>
<span class="nt"><version></span>1.0.0-SNAPSHOT<span class="nt"></version></span>
<span class="nt"></dependency></span>
...
<span class="nt"></dependencies></span>
</code></pre></div></div>
<h3 id="trying-it-out">Trying it out</h3>
<p>That’s it! The plugin is installed! If you want to a particular column to be mapped to a <code class="highlighter-rouge">Gender</code> instead of a <code class="highlighter-rouge">String</code>, you can go into the User Interface, navigate to the particular column in the “Project Tree” and select your new Type Mapper in the dropdown list.</p>
<p><img src="https://lh6.googleusercontent.com/V3X1vuUHpUsLMuGvmhqkQ8QA6ya5lj5x2PTTvZldRw_Hk6p2YdfWK9fVcgVgz_MNC1ls4VtOXou38QLivNdIHqVeiLBHP9-VpLuuZQT_TVQHVB5uYvZAa-u1qY2uQBF4GmP_05Q7" alt="screenshot of the Speedment user interface" title="Speedment User Interface - Main Window" /></p>
<p>If you want to see a list of all the components and/or type mappers loaded into the platform, you can also go to “About” → “Components…” in the UI. There you should see the new component.</p>
<p><img src="https://lh4.googleusercontent.com/p_QK6vO4AdBLAp2Gvhde_YZP8fBqEzXr5xM5DMQ19g9hUo5YOHNMUIruvlXS5ZI4_ZlGE6GsV6tYRee0dvQDoP07Ix_6OhEAqg_6dwaBEAWwRWWgzb6LE42vFiXSRIexaPgYrvzm" alt="screenshot of the components dialog in the Speedment user interface" title="Speedment User Interface - Components Dialog" /></p>
<h3 id="summary">Summary</h3>
<p>In this article you have learned how to create a custom plugin for <a href="https://github.com/speedment/speedment/">Speedment</a> that integrates a new Type Mapper from a String to a Gender enum. You have also learned how you can see which components are loaded into the platform and select which type mapper you want to use for each column.</p>
<p><strong>PS:</strong> If you create some cool new mappers for your Speedment project, consider sharing them with the community in <a href="https://gitter.im/speedment/speedment">our Gitter chat</a>!</p>
<p><a href="http://ageofjava.com/java/Generate-Customized-Code-With-Plugins">How to Generate Customized Java 8 Code with Plugins</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on April 12, 2016.</p>http://ageofjava.com/java/Bye-SQL-Hello-Speedment2016-04-08T00:00:00-07:002016-04-08T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>Most applications written in Java require some form of data storage. In small applications this is often realized using a primitive JDBC-connection that is queried using ordinary SQL. Larger systems on the other hand often use an Object Relational Mapping (ORM) frameworks to handle the database communication. There are pro’s and con’s with both of these approaches, but both tend to involve writing a lot of boilerplate code that looks more or less the same across every codebase. In this article I will showcase another approach to easy database communication using an open source project called <a href="https://github.com/speedment/speedment">Speedment</a>.</p>
<h3 id="what-is-speedment">What is Speedment?</h3>
<p><img src="https://1.bp.blogspot.com/-mE0IVu3Z7Dk/Vwg4lFJx4PI/AAAAAAAAEvw/x_aDWWzgknM6WA7AcPezNzi3lAYnenGpQ/s320/Hello-Speedment.png" alt="" /></p>
<p>Speedment is a developer tool that generates java classes from your SQL metadata. The generated code handles everything from setting up a connection to data retrieval and persistence. The system is designed to integrate perfectly with the Java 8 Stream API so that you can query your database using lambdas without a single line of SQL. The created streams are <a href="https://dzone.com/articles/parsing-java-8-streams-into-sql">optimized in the background</a> to reduce the network load.</p>
<h3 id="setting-up-a-project">Setting Up a Project</h3>
<p>In this article I will write a small application that asks for the user’s name and age and persist it in a MySQL database. First of, we will define the database schema. Open up your MySQL console and enter the following:</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">DATABASE</span> <span class="n">hellospeedment</span><span class="p">;</span>
<span class="n">USE</span> <span class="n">hellospeedment</span><span class="p">;</span>
<span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">IF</span> <span class="k">NOT</span> <span class="k">EXISTS</span> <span class="nv">`user`</span> <span class="p">(</span>
<span class="nv">`id`</span> <span class="n">bigint</span><span class="p">(</span><span class="mi">20</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span> <span class="n">AUTO_INCREMENT</span><span class="p">,</span>
<span class="nv">`name`</span> <span class="n">varchar</span><span class="p">(</span><span class="mi">32</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
<span class="nv">`age`</span> <span class="n">int</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
<span class="k">PRIMARY</span> <span class="k">KEY</span> <span class="p">(</span><span class="nv">`id`</span><span class="p">),</span>
<span class="k">UNIQUE</span> <span class="k">KEY</span> <span class="nv">`name`</span> <span class="p">(</span><span class="nv">`name`</span><span class="p">)</span>
<span class="p">)</span> <span class="n">ENGINE</span><span class="o">=</span><span class="n">InnoDB</span> <span class="k">DEFAULT</span> <span class="n">CHARSET</span><span class="o">=</span><span class="n">utf8</span> <span class="n">AUTO_INCREMENT</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</code></pre></div></div>
<p>Next we will create our java project. Fire up your favorite IDE and create a new Maven Project from Archetype. Archetypes are template projects that can be used to quickly define new maven projects. Exactly how they are used differ between different IDEs. The following information will have to be entered:</p>
<table>
<tbody>
<tr>
<td>Repository</td>
<td>https://repo1.maven.org/maven2</td>
</tr>
<tr>
<td>GroupId</td>
<td>com.speedment</td>
</tr>
<tr>
<td>ArtifactId</td>
<td>speedment-archetype-mysql</td>
</tr>
<tr>
<td>Version</td>
<td>2.3.0</td>
</tr>
</tbody>
</table>
<p>Similar archetypes are available for <a href="https://search.maven.org/#search%7Cga%7C1%7Ca%3A%22speedment-archetype-postgresql%22">PostgreSQL</a> and <a href="https://search.maven.org/#search%7Cga%7C1%7Ca%3A%22speedment-archetype-mariadb%22">MariaDB</a> as well.</p>
<p>On NetBeans, the archetype is usually found among the default ones indexed from the Maven Central Repository. When the project is created you should have something like this:</p>
<p><img src="https://lh4.googleusercontent.com/pWHS2Fmd-BC7Wp_YN0Y0ReC8gpmTeXMEoULGgTa-21B05jt0GLO5NSHREw6LBvilRn-YzFQQmA9xKgx6R4gzmFOLsFxsIBzA301wKNSF1Shl7rXAYp4pQ6rlyZMM5Reer-l8Z7B5" alt="" /></p>
<h3 id="launching-the-speedment-ui">Launching the Speedment UI</h3>
<p>Now then the project has been created it is time to start up the Speedment User Interface. This is done by executing the <code class="highlighter-rouge">speedment:gui</code>-maven goal. In NetBeans and IntelliJ IDEA, a list of available maven goals can be found from within the IDE. In <strong>Netbeans</strong> this is found in the Navigator window (often located in the bottom-left of the screen). The project root node must be selected for the goals to appear. In <strong>IntelliJ</strong>, the goals can be found under the “Maven Projects”-tab in the far right of the screen. You might need to maximize the “Project Name”, “Plugins” and “speedment-maven-plugin”-nodes to find it. In <strong>Eclipse</strong>, you don’t have a list of goals as far as I know. Instead you will have to define the goal manually. There is a tutorial for doing this <a href="https://github.com/speedment/speedment/wiki/Tutorial:-Creating-a-Speedment-Project-in-Eclipse">on the Speedment GitHub wiki</a>.</p>
<p>When the user interface starts the first time it will ask for your email address. After that you can connect to your database.</p>
<p><img src="https://lh3.googleusercontent.com/_VNpvOblX1KdSZW1vE3MFxi_eF3ZtNmwAl5UJincVjG1Mi2-ATTqllTmHIExNueRERlo9pI34757KoUGcP3rVxjgksx_XivianXaL5HUEdvype58sBwKZizh8asM6JNixdaC9EQS" alt="" /></p>
<p>The connection dialog will only allow you to choose between databases that you can connect to using the loaded JDBC-drivers. If you for example want to use a PostgreSQL-database, you should add the PostgreSQL-driver to the <code class="highlighter-rouge"><dependencies></code>-tag of the <code class="highlighter-rouge">speedment-maven-plugin</code> section in the <code class="highlighter-rouge">pom.xml</code>-file and the re-run the UI.</p>
<p>Once you have connected to the database, the main window opens. On the left side you can see a tree-view of the database. In the middle is the workspace where things like database connection, code generation and entity naming can be configured. You can select what part of the project to configure by selecting other nodes in the tree.</p>
<p><img src="https://lh6.googleusercontent.com/gHrVqbQlEEPbz0pY1RJ-uJCTr1JBUGlBNTJKw5CqDTlZLHdsWGV0GGWxkBn5YyJTp0_VczbizPQXlJdMdeSlIwrLnttg31duqNMixJ8zV2ccdSd55V7wCGGPob-U6W13CTTCMAUu" alt="" /></p>
<p>In this case, we will simply press the “Generate”-button in the toolbar to generate a project using the default settings. We can now close the UI and return to our IDE.</p>
<h3 id="write-the-application">Write the Application</h3>
<p>Now when Speedment has generated all the boilerplate code required to communicate with the <code class="highlighter-rouge">HelloSpeedment</code> database we can focus on writing the actual application. Let’s open the <code class="highlighter-rouge">Main.java</code>-file created by the maven archetype and modify the <code class="highlighter-rouge">main()</code> method.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Main</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">...</span> <span class="n">params</span><span class="o">)</span> <span class="o">{</span>
<span class="n">Speedment</span> <span class="n">speedment</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HellospeedmentApplication</span><span class="o">()</span>
<span class="o">.</span><span class="na">withPassword</span><span class="o">(</span><span class="s">"secret"</span><span class="o">).</span><span class="na">build</span><span class="o">();</span>
<span class="n">Manager</span><span class="o"><</span><span class="n">User</span><span class="o">></span> <span class="n">users</span> <span class="o">=</span> <span class="n">speedment</span><span class="o">.</span><span class="na">managerOf</span><span class="o">(</span><span class="n">User</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>In Speedment, an application is defined using a builder pattern. Runtime configuration can be done using different <code class="highlighter-rouge">withXXX()</code>-methods and the platform is finialized when the <code class="highlighter-rouge">build()</code>-method is called. In this case, we use this to set the MySQL password. Speedment will never store sensitive information like your database passwords in the configuration files so you will either have to have a unprotected database or set the password at runtime.</p>
<p>The next thing we want to do is to listen for user input. When a user starts the program, we should greet them and then ask for their name and age. We should then persist the user information in the database.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="n">Scanner</span> <span class="n">scn</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Scanner</span><span class="o">(</span><span class="n">System</span><span class="o">.</span><span class="na">in</span><span class="o">);</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">print</span><span class="o">(</span><span class="s">"What is your name? "</span><span class="o">);</span>
<span class="kd">final</span> <span class="n">String</span> <span class="n">name</span> <span class="o">=</span> <span class="n">scn</span><span class="o">.</span><span class="na">nextLine</span><span class="o">();</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">print</span><span class="o">(</span><span class="s">"What is your age? "</span><span class="o">);</span>
<span class="kd">final</span> <span class="kt">int</span> <span class="n">age</span> <span class="o">=</span> <span class="n">scn</span><span class="o">.</span><span class="na">nextInt</span><span class="o">();</span>
<span class="k">try</span> <span class="o">{</span>
<span class="n">users</span><span class="o">.</span><span class="na">newEmptyEntity</span><span class="o">()</span>
<span class="o">.</span><span class="na">setName</span><span class="o">(</span><span class="n">name</span><span class="o">)</span>
<span class="o">.</span><span class="na">setAge</span><span class="o">(</span><span class="n">age</span><span class="o">)</span>
<span class="o">.</span><span class="na">persist</span><span class="o">();</span>
<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">SpeedmentException</span> <span class="n">ex</span><span class="o">)</span> <span class="o">{</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"That name was already taken."</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>If the persistence failed, a <code class="highlighter-rouge">SpeedmentException</code> is thrown. This could for example happen if a user with that name already exists since the <code class="highlighter-rouge">name</code> column in the schema is set to <code class="highlighter-rouge">UNIQUE</code>.</p>
<h3 id="reading-the-persisted-data">Reading the Persisted Data</h3>
<p>Remember I started out by telling you how Speedment fits in nicely with the Stream API in Java 8? Let’s try it out! If we run the application above a few times we can populate the database with some users. We can then query the database using the same <code class="highlighter-rouge">users</code> manager.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span>
<span class="n">users</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">User</span><span class="o">.</span><span class="na">ID</span><span class="o">.</span><span class="na">lessThan</span><span class="o">(</span><span class="mi">100</span><span class="o">))</span>
<span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="nl">User:</span><span class="o">:</span><span class="n">toJson</span><span class="o">)</span>
<span class="o">.</span><span class="na">collect</span><span class="o">(</span><span class="n">joining</span><span class="o">(</span><span class="s">",\n "</span><span class="o">,</span> <span class="s">"[\n "</span><span class="o">,</span> <span class="s">"\n]"</span><span class="o">))</span>
<span class="o">);</span>
</code></pre></div></div>
<p>This will produce a result something like this:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>
<span class="o">{</span><span class="s">"id"</span><span class="o">:</span><span class="mi">1</span><span class="o">,</span><span class="s">"name"</span><span class="o">:</span><span class="s">"Adam"</span><span class="o">,</span><span class="s">"age"</span><span class="o">:</span><span class="mi">24</span><span class="o">},</span>
<span class="o">{</span><span class="s">"id"</span><span class="o">:</span><span class="mi">2</span><span class="o">,</span><span class="s">"name"</span><span class="o">:</span><span class="s">"Bert"</span><span class="o">,</span><span class="s">"age"</span><span class="o">:</span><span class="mi">20</span><span class="o">},</span>
<span class="o">{</span><span class="s">"id"</span><span class="o">:</span><span class="mi">3</span><span class="o">,</span><span class="s">"name"</span><span class="o">:</span><span class="s">"Carl"</span><span class="o">,</span><span class="s">"age"</span><span class="o">:</span><span class="mi">35</span><span class="o">},</span>
<span class="o">{</span><span class="s">"id"</span><span class="o">:</span><span class="mi">4</span><span class="o">,</span><span class="s">"name"</span><span class="o">:</span><span class="s">"Dave"</span><span class="o">,</span><span class="s">"age"</span><span class="o">:</span><span class="mi">41</span><span class="o">},</span>
<span class="o">{</span><span class="s">"id"</span><span class="o">:</span><span class="mi">5</span><span class="o">,</span><span class="s">"name"</span><span class="o">:</span><span class="s">"Eric"</span><span class="o">,</span><span class="s">"age"</span><span class="o">:</span><span class="mi">18</span><span class="o">}</span>
<span class="o">]</span>
</code></pre></div></div>
<h3 id="summary">Summary</h3>
<p>This article has showcased how easy it is to write database applications using <a href="https://github.com/speedment/speedment">Speedment</a>. We have created a project using a maven archetype, launched the Speedment UI as a maven goal, established a connection with a local database and generated application code. We have then managed to do both data persistence and querying without a single row of SQL!</p>
<p>That was all for this time.</p>
<p><strong>PS:</strong> <a href="https://github.com/speedment/speedment/releases/tag/2.3.0">Speedment 2.3 Hamilton</a> was just released the other day and it contains a ton of really cool features for how you can manipulate the code generator to fit your every need. Check it out!</p>
<p><a href="http://ageofjava.com/java/Bye-SQL-Hello-Speedment">Bye Manual SQL, Hello Speedment!</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on April 08, 2016.</p>http://ageofjava.com/java/Equality-vs-Identity2016-02-16T00:00:00-08:002016-02-16T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>When storing objects in a <code class="highlighter-rouge">Set</code>, it is important that the same object can never be added twice. That is the core definition of a <code class="highlighter-rouge">Set</code>. In java, two methods are used to determine whether two referenced objects are the same or if they can both exist in the same <code class="highlighter-rouge">Set</code>; <code class="highlighter-rouge">equals()</code> and <code class="highlighter-rouge">hashCode()</code>. In this article I will explain the difference between equality and identity and also take up some of the advantages they have over each other.</p>
<p>Java offers a standard implementation of both these methods. The standard <code class="highlighter-rouge">equals()</code>-method is defined as an “identity” comparing method. It means that it compares the two memory references to determine if they are the same. Two identical objects that are stored in different locations in the memory will therefore be deemed unequal. This comparison is done using the <code class="highlighter-rouge">==</code>-operator, as can be seen if you look at the source code of the <code class="highlighter-rouge">Object</code>-class.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="n">Object</span> <span class="n">obj</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="o">(</span><span class="k">this</span> <span class="o">==</span> <span class="n">obj</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The <code class="highlighter-rouge">hashCode()</code>-method is implemented by the virtual machine as a native operation so it is not visible in the code, but it is often realized as simply returning the memory reference (on 32-bit architectures) or a modulo 32 representation of the memory reference (on a 64-bit architecture).
One thing many programmers choose to do when designing classes is to override this method with a different equality definition where instead of comparing the memory reference, you look at the values of the two instances to see if they can be considered equal. Here is an example of that:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">java.util.Objects</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">static</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">Objects</span><span class="o">.</span><span class="na">requireNonNull</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">Person</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">firstname</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">lastname</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">Person</span><span class="o">(</span><span class="n">String</span> <span class="n">firstname</span><span class="o">,</span> <span class="n">String</span> <span class="n">lastname</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">firstname</span> <span class="o">=</span> <span class="n">requireNonNull</span><span class="o">(</span><span class="n">firstname</span><span class="o">);</span>
<span class="k">this</span><span class="o">.</span><span class="na">lastname</span> <span class="o">=</span> <span class="n">requireNonNull</span><span class="o">(</span><span class="n">lastname</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="kt">int</span> <span class="n">hash</span> <span class="o">=</span> <span class="mi">7</span><span class="o">;</span>
<span class="n">hash</span> <span class="o">=</span> <span class="mi">83</span> <span class="o">*</span> <span class="n">hash</span> <span class="o">+</span> <span class="n">Objects</span><span class="o">.</span><span class="na">hashCode</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">firstname</span><span class="o">);</span>
<span class="n">hash</span> <span class="o">=</span> <span class="mi">83</span> <span class="o">*</span> <span class="n">hash</span> <span class="o">+</span> <span class="n">Objects</span><span class="o">.</span><span class="na">hashCode</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">lastname</span><span class="o">);</span>
<span class="k">return</span> <span class="n">hash</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="n">Object</span> <span class="n">obj</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">obj</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">obj</span> <span class="o">==</span> <span class="kc">null</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="n">getClass</span><span class="o">()</span> <span class="o">!=</span> <span class="n">obj</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="kd">final</span> <span class="n">Person</span> <span class="n">other</span> <span class="o">=</span> <span class="o">(</span><span class="n">Person</span><span class="o">)</span> <span class="n">obj</span><span class="o">;</span>
<span class="k">if</span> <span class="o">(!</span><span class="n">Objects</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">firstname</span><span class="o">,</span> <span class="n">other</span><span class="o">.</span><span class="na">firstname</span><span class="o">))</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span> <span class="k">else</span> <span class="k">return</span> <span class="n">Objects</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">lastname</span><span class="o">,</span> <span class="n">other</span><span class="o">.</span><span class="na">lastname</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>This comparison is called “equality” (compared to the previous “identity”). As long as two persons have the same first- and lastname, they will be considered equal. This can for an example be used to sort out duplicates from a stream of input. Remember that if you override the <code class="highlighter-rouge">equals()</code>-method, you should always override the <code class="highlighter-rouge">hashCode()</code>-method as well!</p>
<h3 id="equality">Equality</h3>
<p>Now, if you choose equality over identity, there are some things you will need to think about. The first thing you must ask yourself is: are two instances of this class with the same properties necessarily the same? In the case of Person above, I would say no. It is very likely that you will someday have two people in your system with the same first- and lastname. Even if you continue to add more personal information like birthday or favorite color, you will sooner or later have a collision. On the other hand, if your system are handling cars and each car contains a reference to a “model”, it can be safely assumed that if two cars both are black Tesla model S, they are probably the same model even if the objects are stored in different places in the memory. That is an example of a case when equality can be good.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">java.util.Objects</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">static</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">Objects</span><span class="o">.</span><span class="na">requireNonNull</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">Car</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">Model</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">name</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">version</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">Model</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">,</span> <span class="n">String</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">name</span> <span class="o">=</span> <span class="n">requireNonNull</span><span class="o">(</span><span class="n">name</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">requireNonNull</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">int</span> <span class="nf">hashCode</span><span class="o">()</span> <span class="o">{</span>
<span class="kt">int</span> <span class="n">hash</span> <span class="o">=</span> <span class="mi">5</span><span class="o">;</span>
<span class="n">hash</span> <span class="o">=</span> <span class="mi">23</span> <span class="o">*</span> <span class="n">hash</span> <span class="o">+</span> <span class="n">Objects</span><span class="o">.</span><span class="na">hashCode</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">hash</span> <span class="o">=</span> <span class="mi">23</span> <span class="o">*</span> <span class="n">hash</span> <span class="o">+</span> <span class="n">Objects</span><span class="o">.</span><span class="na">hashCode</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="k">return</span> <span class="n">hash</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="n">Object</span> <span class="n">obj</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">obj</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">obj</span> <span class="o">==</span> <span class="kc">null</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="n">getClass</span><span class="o">()</span> <span class="o">!=</span> <span class="n">obj</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="kd">final</span> <span class="n">Model</span> <span class="n">other</span> <span class="o">=</span> <span class="o">(</span><span class="n">Model</span><span class="o">)</span> <span class="n">obj</span><span class="o">;</span>
<span class="k">if</span> <span class="o">(!</span><span class="n">Objects</span><span class="o">.</span><span class="na">equals</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">other</span><span class="o">.</span><span class="na">name</span><span class="o">))</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span> <span class="k">else</span> <span class="k">return</span> <span class="n">Objects</span><span class="o">.</span><span class="na">equals</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">other</span><span class="o">.</span><span class="na">version</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">color</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">Model</span> <span class="n">model</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">Car</span><span class="o">(</span><span class="n">String</span> <span class="n">color</span><span class="o">,</span> <span class="n">Model</span> <span class="n">model</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">color</span> <span class="o">=</span> <span class="n">requireNonNull</span><span class="o">(</span><span class="n">color</span><span class="o">);</span>
<span class="k">this</span><span class="o">.</span><span class="na">model</span> <span class="o">=</span> <span class="n">requireNonNull</span><span class="o">(</span><span class="n">model</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="n">Model</span> <span class="nf">getModel</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">model</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Two cars are only considered the same if they have the same memory address. Their models on the other hand is considered the same as long as they have the same name and version. Here is an example of this:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="n">Car</span> <span class="n">a</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Car</span><span class="o">(</span><span class="s">"black"</span><span class="o">,</span> <span class="k">new</span> <span class="n">Car</span><span class="o">.</span><span class="na">Model</span><span class="o">(</span><span class="s">"Tesla"</span><span class="o">,</span> <span class="s">"Model S"</span><span class="o">));</span>
<span class="kd">final</span> <span class="n">Car</span> <span class="n">b</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Car</span><span class="o">(</span><span class="s">"black"</span><span class="o">,</span> <span class="k">new</span> <span class="n">Car</span><span class="o">.</span><span class="na">Model</span><span class="o">(</span><span class="s">"Tesla"</span><span class="o">,</span> <span class="s">"Model S"</span><span class="o">));</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Is a and b the same car? "</span> <span class="o">+</span> <span class="n">a</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">b</span><span class="o">));</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Is a and b the same model? "</span> <span class="o">+</span> <span class="n">a</span><span class="o">.</span><span class="na">getModel</span><span class="o">().</span><span class="na">equals</span><span class="o">(</span><span class="n">b</span><span class="o">.</span><span class="na">getModel</span><span class="o">()));</span>
<span class="c1">// Prints the following:</span>
<span class="c1">// Is a and b the same car? false</span>
<span class="c1">// Is a and b the same model? true</span>
</code></pre></div></div>
<h3 id="identity">Identity</h3>
<p>One risk of choosing equality over identity is that it can be an invitation to allocating more objects than necessarily on the heap. Just look at the car example above. For every car we create we also allocate space in memory for a model. Even if java generally optimizes string allocation to prevent duplicates, it is still a certain waste for objects that will always be the same. A short trick to turn the inner object into something that can be compared using identity comparing method and at the same time avoid unnecessary object allocation is to replace it with an enum:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">Car</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">enum</span> <span class="n">Model</span> <span class="o">{</span>
<span class="n">TESLA_MODEL_S</span> <span class="o">(</span><span class="s">"Tesla"</span><span class="o">,</span> <span class="s">"Model S"</span><span class="o">),</span>
<span class="n">VOLVO_V70</span> <span class="o">(</span><span class="s">"Volvo"</span><span class="o">,</span> <span class="s">"V70"</span><span class="o">);</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">name</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">version</span><span class="o">;</span>
<span class="n">Model</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">,</span> <span class="n">String</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">name</span> <span class="o">=</span> <span class="n">name</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="o">}</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">color</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">Model</span> <span class="n">model</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">Car</span><span class="o">(</span><span class="n">String</span> <span class="n">color</span><span class="o">,</span> <span class="n">Model</span> <span class="n">model</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">color</span> <span class="o">=</span> <span class="n">requireNonNull</span><span class="o">(</span><span class="n">color</span><span class="o">);</span>
<span class="k">this</span><span class="o">.</span><span class="na">model</span> <span class="o">=</span> <span class="n">requireNonNull</span><span class="o">(</span><span class="n">model</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="n">Model</span> <span class="nf">getModel</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">model</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Now we can be sure that each model will only ever exist at one place in memory and can therefore safely be compared using identity comparison. An issue with this however is that is really limits our extendability. Before with could define new models on the fly without modifying the source code in the <code class="highlighter-rouge">Car.java</code>-file, but now we have locked ourselves into an enum that should generally be kept unmodified. If those properties are desired, an equals comparison is probably better for you.</p>
<p>A finishing note, if you have overridden the <code class="highlighter-rouge">equals()</code> and <code class="highlighter-rouge">hashCode()</code>-methods of a class and later want to store it in a Map based on identity, you can always use the <a href="https://docs.oracle.com/javase/8/docs/api/java/util/IdentityHashMap.html">IdentityHashMap</a> structure. It will use the memory address to reference its keys, even if the <code class="highlighter-rouge">equals()</code>- and <code class="highlighter-rouge">hashCode()</code>-methods have been overridden.</p>
<p><a href="http://ageofjava.com/java/Equality-vs-Identity">Equality vs Identity</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on February 16, 2016.</p>http://ageofjava.com/java/Get-Rid-of-equals-compareTo-and-toString2016-02-10T00:00:00-08:002016-02-10T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>Have you ever looked at the javadoc of <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html">the Object-class</a> in Java?</p>
<p>Probably. You tend to end up there every now and then when digging your way down the inheritance tree. One thing you might have noticed is that it has quite a few methods that every class must inherit. The favorite methods to implement yourself rather than stick with the original ones are probably <code class="highlighter-rouge">.toString()</code>, <code class="highlighter-rouge">.equals()</code> and <code class="highlighter-rouge">.hashCode()</code> (why you should always implement both of the latter is described well <a href="https://minborgsjavapot.blogspot.com/2014/10/new-java-8-object-support-mixin-pattern.html">by Per-Åke Minborg in this post</a>).</p>
<p>But these methods are apparently not enough. Many people mix in additional interfaces from the standard libraries like <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html">Comparable</a> and <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html">Serializable</a>. But is that really wise? Why do everyone want to implement these methods on their own so badly? Well, implementing your own <code class="highlighter-rouge">.equals()</code> and <code class="highlighter-rouge">.hashCode()</code> methods will probably make sense if you are planning on storing them in something like a <code class="highlighter-rouge">HashMap</code> and want to control hash collisions, but what about <code class="highlighter-rouge">compareTo()</code> and <code class="highlighter-rouge">toString()</code>?</p>
<p>In this article I will present an approach to software design that we use on <a href="https://github.com/speedment/speedment">the Speedment open source project</a> where methods that operate on objects are implemented as functional references stored in variables rather than overriding Javas built in methods. There are several advantages to this. Your POJOs will be shorter and more concise, common operations can be reused without inheritance and you can switch between different configurations in a flexible matter.</p>
<p><img src="/website/images/2016-02-10/cleaner.png" alt="Spire and Duke cleaning the house" /></p>
<h3 id="original-code">Original Code</h3>
<p>Let us begin by looking at the following example. We have a typical Java class named <code class="highlighter-rouge">Person</code>. In our application we want to print out every person from a <code class="highlighter-rouge">Set</code> in the order of their firstname followed by lastname (in case two persons share the same firstname).</p>
<h5 id="personjava">Person.java</h5>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Person</span> <span class="kd">implements</span> <span class="n">Comparable</span><span class="o"><</span><span class="n">Person</span><span class="o">></span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">firstname</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">lastname</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">Person</span><span class="o">(</span><span class="n">String</span> <span class="n">firstname</span><span class="o">,</span> <span class="n">String</span> <span class="n">lastname</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">firstname</span> <span class="o">=</span> <span class="n">firstname</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">lastname</span> <span class="o">=</span> <span class="n">lastname</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="n">String</span> <span class="nf">getFirstname</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">firstname</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="n">String</span> <span class="nf">getLastname</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">lastname</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="kt">int</span> <span class="n">hash</span> <span class="o">=</span> <span class="mi">7</span><span class="o">;</span>
<span class="n">hash</span> <span class="o">=</span> <span class="mi">83</span> <span class="o">*</span> <span class="n">hash</span> <span class="o">+</span> <span class="n">Objects</span><span class="o">.</span><span class="na">hashCode</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">firstname</span><span class="o">);</span>
<span class="n">hash</span> <span class="o">=</span> <span class="mi">83</span> <span class="o">*</span> <span class="n">hash</span> <span class="o">+</span> <span class="n">Objects</span><span class="o">.</span><span class="na">hashCode</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">lastname</span><span class="o">);</span>
<span class="k">return</span> <span class="n">hash</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="n">Object</span> <span class="n">obj</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">obj</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">obj</span> <span class="o">==</span> <span class="kc">null</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="n">getClass</span><span class="o">()</span> <span class="o">!=</span> <span class="n">obj</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="kd">final</span> <span class="n">Person</span> <span class="n">other</span> <span class="o">=</span> <span class="o">(</span><span class="n">Person</span><span class="o">)</span> <span class="n">obj</span><span class="o">;</span>
<span class="k">if</span> <span class="o">(!</span><span class="n">Objects</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">firstname</span><span class="o">,</span> <span class="n">other</span><span class="o">.</span><span class="na">firstname</span><span class="o">))</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span>
<span class="k">return</span> <span class="n">Objects</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">lastname</span><span class="o">,</span> <span class="n">other</span><span class="o">.</span><span class="na">lastname</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">compareTo</span><span class="o">(</span><span class="n">Person</span> <span class="n">that</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">that</span><span class="o">)</span> <span class="k">return</span> <span class="mi">0</span><span class="o">;</span>
<span class="k">else</span> <span class="nf">if</span> <span class="o">(</span><span class="n">that</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="k">return</span> <span class="mi">1</span><span class="o">;</span>
<span class="kt">int</span> <span class="n">comparison</span> <span class="o">=</span> <span class="k">this</span><span class="o">.</span><span class="na">firstname</span><span class="o">.</span><span class="na">compareTo</span><span class="o">(</span><span class="n">that</span><span class="o">.</span><span class="na">firstname</span><span class="o">);</span>
<span class="k">if</span> <span class="o">(</span><span class="n">comparison</span> <span class="o">!=</span> <span class="mi">0</span><span class="o">)</span> <span class="k">return</span> <span class="n">comparison</span><span class="o">;</span>
<span class="n">comparison</span> <span class="o">=</span> <span class="k">this</span><span class="o">.</span><span class="na">lastname</span><span class="o">.</span><span class="na">compareTo</span><span class="o">(</span><span class="n">that</span><span class="o">.</span><span class="na">lastname</span><span class="o">);</span>
<span class="k">return</span> <span class="n">comparison</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">String</span> <span class="nf">toString</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">firstname</span> <span class="o">+</span> <span class="s">" "</span> <span class="o">+</span> <span class="n">lastname</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h5 id="mainjava">Main.java</h5>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Main</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">...</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">Set</span> <span class="n">people</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HashSet</span><span class="o"><>();</span>
<span class="n">people</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">Person</span><span class="o">(</span><span class="s">"Adam"</span><span class="o">,</span> <span class="s">"Johnsson"</span><span class="o">));</span>
<span class="n">people</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">Person</span><span class="o">(</span><span class="s">"Adam"</span><span class="o">,</span> <span class="s">"Samuelsson"</span><span class="o">));</span>
<span class="n">people</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">Person</span><span class="o">(</span><span class="s">"Ben"</span><span class="o">,</span> <span class="s">"Carlsson"</span><span class="o">));</span>
<span class="n">people</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">Person</span><span class="o">(</span><span class="s">"Ben"</span><span class="o">,</span> <span class="s">"Carlsson"</span><span class="o">));</span>
<span class="n">people</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">Person</span><span class="o">(</span><span class="s">"Cecilia"</span><span class="o">,</span> <span class="s">"Adams"</span><span class="o">));</span>
<span class="n">people</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">sorted</span><span class="o">()</span>
<span class="o">.</span><span class="na">forEachOrdered</span><span class="o">(</span><span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">::</span><span class="n">println</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h5 id="output">Output</h5>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>run:
Adam Johnsson
Adam Samuelsson
Ben Carlsson
Cecilia Adams
BUILD SUCCESSFUL (total time: 0 seconds)
</code></pre></div></div>
<p>Person implements several methods here to control the output of the stream. The <code class="highlighter-rouge">hashCode()</code> and <code class="highlighter-rouge">equals()</code> method make sure that duplicate persons can’t be added to the set. The <code class="highlighter-rouge">compareTo()</code> method is used by the sorted action to produce the desired order. The overridden <code class="highlighter-rouge">toString()</code>-method is finally controlling how each <code class="highlighter-rouge">Person</code> should be printed when <code class="highlighter-rouge">System.out.println()</code> is called. Do you recognize this structure? You can find it in almost every java project out there.</p>
<h3 id="alternative-code">Alternative Code</h3>
<p>Instead of putting all functionality into the <code class="highlighter-rouge">Person</code> class, we can try and keep it as clean as possible and use functional references to handle these decorations. We remove all the boilerplate with <code class="highlighter-rouge">equals</code>, <code class="highlighter-rouge">hashCode</code>, <code class="highlighter-rouge">compareTo</code> and <code class="highlighter-rouge">toString</code> and instead we introduce two static variables, <code class="highlighter-rouge">COMPARATOR</code> and <code class="highlighter-rouge">TO_STRING</code>.</p>
<h5 id="personjava-1">Person.java</h5>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Person</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">firstname</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">lastname</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">Person</span><span class="o">(</span><span class="n">String</span> <span class="n">firstname</span><span class="o">,</span> <span class="n">String</span> <span class="n">lastname</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">firstname</span> <span class="o">=</span> <span class="n">firstname</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">lastname</span> <span class="o">=</span> <span class="n">lastname</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="n">String</span> <span class="nf">getFirstname</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">firstname</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="n">String</span> <span class="nf">getLastname</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">lastname</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kd">static</span> <span class="n">Comparator</span><span class="o"><</span><span class="n">Person</span><span class="o">></span> <span class="n">COMPARATOR</span> <span class="o">=</span>
<span class="n">Comparator</span><span class="o">.</span><span class="na">comparing</span><span class="o">(</span><span class="nl">Person:</span><span class="o">:</span><span class="n">getFirstname</span><span class="o">)</span>
<span class="o">.</span><span class="na">thenComparing</span><span class="o">(</span><span class="nl">Person:</span><span class="o">:</span><span class="n">getLastname</span><span class="o">);</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kd">static</span> <span class="n">Function</span><span class="o"><</span><span class="n">Person</span><span class="o">,</span> <span class="n">String</span><span class="o">></span> <span class="n">TO_STRING</span> <span class="o">=</span>
<span class="n">p</span> <span class="o">-></span> <span class="n">p</span><span class="o">.</span><span class="na">getFirstname</span><span class="o">()</span> <span class="o">+</span> <span class="s">" "</span> <span class="o">+</span> <span class="n">p</span><span class="o">.</span><span class="na">getLastname</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>
<h5 id="mainjava-1">Main.java</h5>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Main</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">...</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">Set</span> <span class="n">people</span> <span class="o">=</span> <span class="k">new</span> <span class="n">TreeSet</span><span class="o"><>(</span><span class="n">Person</span><span class="o">.</span><span class="na">COMPARATOR</span><span class="o">);</span>
<span class="n">people</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">Person</span><span class="o">(</span><span class="s">"Adam"</span><span class="o">,</span> <span class="s">"Johnsson"</span><span class="o">));</span>
<span class="n">people</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">Person</span><span class="o">(</span><span class="s">"Adam"</span><span class="o">,</span> <span class="s">"Samuelsson"</span><span class="o">));</span>
<span class="n">people</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">Person</span><span class="o">(</span><span class="s">"Ben"</span><span class="o">,</span> <span class="s">"Carlsson"</span><span class="o">));</span>
<span class="n">people</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">Person</span><span class="o">(</span><span class="s">"Ben"</span><span class="o">,</span> <span class="s">"Carlsson"</span><span class="o">));</span>
<span class="n">people</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">Person</span><span class="o">(</span><span class="s">"Cecilia"</span><span class="o">,</span> <span class="s">"Adams"</span><span class="o">));</span>
<span class="n">people</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="n">Person</span><span class="o">.</span><span class="na">TO_STRING</span><span class="o">)</span>
<span class="o">.</span><span class="na">forEachOrdered</span><span class="o">(</span><span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">::</span><span class="n">println</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h5 id="output-1">Output</h5>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>run:
Adam Johnsson
Adam Samuelsson
Ben Carlsson
Cecilia Adams
BUILD SUCCESSFUL (total time: 0 seconds)
</code></pre></div></div>
<p>The nice thing with this approach is that we can now replace the order and the formatting of the print without changing our <code class="highlighter-rouge">Person</code> class. This will make the code more maintainable and easier to reuse, not to say faster to write.</p>
<p><a href="http://ageofjava.com/java/Get-Rid-of-equals-compareTo-and-toString">Get rid of equals, compare_To and to_String</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on February 10, 2016.</p>http://ageofjava.com/java/Definition-of-the-Trait-Pattern-in-Java2016-02-03T00:00:00-08:002016-02-03T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>In this article I will present <a href="/website/java/Using-Traits-in-Java-8">the concept of traits</a> and give you a concrete example of how they can be used in Java to achieve less redundancy in your object design.</p>
<p><img src="/website/images/2016-02-03/traitlike.png" alt="Spire and Duke trying on each others traits" /></p>
<p>I will begin by presenting a fictional case where traits could be used to reduce repetition and then finish with an example implementation of the trait pattern using Java 8.</p>
<p>Suppose you are developing a message board software and you have identified the following as your data models: “topics”, “comments” and “attachments”. A topic has a title, a content and an author. A comment has a content and an author. An attachment has a title and a blob. A topic can have multiple comments and attachments. A comment can also have multiple comments, but no attachments.</p>
<p><img src="/website/images/2016-02-03/system.png" alt="UML diagram of a simple comment system in Java" /></p>
<p>Soon you realise that no matter how you implement the three models, there will be code repetition in the program. If you for an example want to write a method that adds a new comment to a post, you will need to write one method for commenting topics and one for commenting comments. Writing a method that summarizes a discussion by printing out the discussion tree will have to take into consideration that a node can be either a topic, a comment or an attachment.</p>
<p>Since the inception of Java over 20 years ago, object-oriented programming has been the flesh and soul of the language, but during this time, other languages has experimented with other tools for organizing the structure of a program. One such tool that we use in <a href="https://github.com/speedment/speedment">Speedment Open Source</a> is something called “Traits”. A trait is kind of a “micro interface” that describes some characteristic of a class design that can be found in many different components throughout the system. By referring to the traits instead of the implementing class itself you can keep the system decoupled and modular.</p>
<p>Let’s look at how this would change our example with the message board.</p>
<p><img src="/website/images/2016-02-03/complex-with-traits.png" alt="UML diagram of a comment system with Java 8 Traits" /></p>
<p>Now the different <em>traits</em> of each entity has been separated into different interfaces. This is good. Since Java allows us to have multiple interfaces per class, we can reference the interfaces directly when writing our business logic. In fact, the classes will not have to be exposed at all!</p>
<p>Traits have existed for many years in other programming languages such as Scala, PHP, Groovy, and many more. To my knowledge there is no consensus regarding what is considered a trait between different languages. On <a href="https://en.wikipedia.org/wiki/Trait_(computer_programming)#Characteristics">the Wikipedia page</a> regarding traits it says that:</p>
<blockquote>
<p>“Traits both provide a set of methods that implement behaviour to a class and require that the class implement a set of methods that parameterize the provided behaviour”</p>
</blockquote>
<p>The following properties are named as distinctive for traits:</p>
<ul>
<li>traits can be combined (symmetric sum)</li>
<li>traits can be overriden (asymmetric sum)</li>
<li>traits can be expanded (alias)</li>
<li>traits can be excluded (exclusion)</li>
</ul>
<p>Since Java 8 you can actually fulfill most of these criteria using interfaces. You can for an example cast an implementing class of an unknown type to a union of traits using the and (<code class="highlighter-rouge">&</code>) operator, which satisfies the symmetric sum criteria. A good example of this <a href="/website/java/Using-Traits-in-Java-8">is described here</a>. By creating a new interface and <a href="https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html">using default implementations</a> you can override some methods to fulfill the asymmetric sum criteria. Aliases can be created in a similar way. The only problem is exclusion. Currently java has no way of removing a method from inheritance so there is no way to prevent a child class from accessing a method defined in a trait.</p>
<p>If we return to the message board example, we could for an example require the implementing class to have a method <code class="highlighter-rouge">getComments()</code>, but all additional logic regarding adding, removing and streaming over comments could be put in the interface.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">HasComments</span><span class="o"><</span><span class="n">R</span> <span class="kd">extends</span> <span class="n">HasComments</span><span class="o"><</span><span class="n">R</span><span class="o">>></span> <span class="o">{</span>
<span class="c1">// one method that parameterize the provided behaviour</span>
<span class="n">List</span><span class="o"><</span><span class="n">Comment</span><span class="o">></span> <span class="nf">getComments</span><span class="o">();</span>
<span class="c1">// two methods that implement the behaviour</span>
<span class="k">default</span> <span class="n">R</span> <span class="nf">add</span><span class="o">(</span><span class="n">Comment</span> <span class="n">comment</span><span class="o">)</span> <span class="o">{</span>
<span class="n">getComments</span><span class="o">().</span><span class="na">add</span><span class="o">(</span><span class="n">comment</span><span class="o">);</span>
<span class="k">return</span> <span class="o">(</span><span class="n">R</span><span class="o">)</span> <span class="k">this</span><span class="o">;</span>
<span class="o">}</span>
<span class="k">default</span> <span class="n">R</span> <span class="nf">remove</span><span class="o">(</span><span class="n">Comment</span> <span class="n">comment</span><span class="o">)</span> <span class="o">{</span>
<span class="n">getComments</span><span class="o">().</span><span class="na">remove</span><span class="o">(</span><span class="n">comment</span><span class="o">);</span>
<span class="k">return</span> <span class="o">(</span><span class="n">R</span><span class="o">)</span> <span class="k">this</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>If we have an object and we want to cast it to a symmetric sum of <code class="highlighter-rouge">HasComments</code> and <code class="highlighter-rouge">HasContent</code>, we could do it using the and (<code class="highlighter-rouge">&</code>) operator:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="n">Object</span> <span class="n">obj</span> <span class="o">=</span> <span class="o">...;</span>
<span class="n">Optional</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="n">obj</span><span class="o">)</span>
<span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="n">o</span> <span class="o">-></span> <span class="o">(</span><span class="n">HasComments</span><span class="o"><?></span> <span class="o">&</span> <span class="n">HasContent</span><span class="o"><?>)</span> <span class="n">o</span><span class="o">)</span>
<span class="o">.</span><span class="na">ifPresent</span><span class="o">(</span><span class="n">sum</span> <span class="o">-></span> <span class="o">{</span><span class="cm">/* do something */</span><span class="o">});</span>
</code></pre></div></div>
<p>That was all for this time!</p>
<p><strong>PS:</strong> If you want to read more about traits as a concept, I really suggest you to read the <cite><a href="http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf">Traits: Composable Units of Behaviour</a></cite> paper from 2003 by N. Schärli et al.</p>
<p><a href="http://ageofjava.com/java/Definition-of-the-Trait-Pattern-in-Java">Definition of the Trait Pattern in Java</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on February 03, 2016.</p>http://ageofjava.com/java/Using-Traits-in-Java-82016-01-27T00:00:00-08:002016-01-27T00:00:00-00:00Emil Forslundhttp://ageofjava.comme@ageofjava.com
<p>In <a href="/java/Type-Safe-Views-using-Abstract-Document-Pattern">one of my earlier articles</a> I mentioned a programming component called “traits”. These constructs have existed <a href="https://en.wikipedia.org/wiki/Trait_(computer_programming)">for many years</a> in other programming languages like <a href="http://docs.scala-lang.org/tutorials/tour/traits.html">Scala</a> and <a href="https://secure.php.net/manual/en/language.oop5.traits.php">PHP</a>, but have only recently been available through default methods in Java. I will not go into the possibilities with using traits in this article, but I will show you a neat trick <a href="https://github.com/speedment/speedment">we use a lot at Speedment</a> that you can use if you ever need to stream over a collection of different objects and separate those that fulfill a number of traits.</p>
<p><img src="/images/2016-01-27/traits.png" alt="Spire and Duke wearing masks" /></p>
<p>Say that you have two noun classes Person and Elephant. There is no reason really why persons and elephants should belong to the same super class; elephants are intelligent four-legged creatures and most humans are not. You might still find the two of them in the same computer system and sometimes you even need to store them in the same collection. One way of operating on this collection of various living beings without making them share a common ancestor, (which would totally be just a theory), you can give them similar <em>traits</em>.</p>
<p>Take a look at this interface:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">interface</span> <span class="nc">HasName</span> <span class="kd">extends</span> <span class="n">Document</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">String</span> <span class="n">NAME</span> <span class="o">=</span> <span class="s">"name"</span><span class="o">;</span>
<span class="k">default</span> <span class="n">String</span> <span class="nf">getName</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="nf">get</span><span class="o">(</span><span class="n">NAME</span><span class="o">);</span>
<span class="o">}</span>
<span class="k">default</span> <span class="kt">void</span> <span class="nf">setName</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
<span class="n">put</span><span class="o">(</span><span class="n">NAME</span><span class="o">,</span> <span class="n">name</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Using the <a href="/java/Type-Safe-Views-using-Abstract-Document-Pattern">Abstract Document Pattern</a> presented earlier, the trait can set and get the attribute “name” from a map. If we now want to iterate over our collection of many living things that might or might not implement our specified traits, we can easily do it like this:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="n">Set</span><span class="o"><</span><span class="n">Object</span><span class="o">></span> <span class="n">livingBeings</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HashSet</span><span class="o"><>();</span>
<span class="n">livingBeings</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">Person</span><span class="o">(...));</span>
<span class="n">livingBeings</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">Person</span><span class="o">(...));</span>
<span class="n">livingBeings</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">Elephant</span><span class="o">(...));</span>
<span class="n">livingBeings</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">HasName</span><span class="o">.</span><span class="na">class</span><span class="o">::</span><span class="n">isInstance</span><span class="o">)</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">HasAge</span><span class="o">.</span><span class="na">class</span><span class="o">::</span><span class="n">isInstance</span><span class="o">)</span>
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">HasWeight</span><span class="o">.</span><span class="na">class</span><span class="o">::</span><span class="n">isInstance</span><span class="o">)</span>
<span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="n">p</span> <span class="o">-></span> <span class="o">(</span><span class="n">HasName</span> <span class="o">&</span> <span class="n">HasAge</span> <span class="o">&</span> <span class="n">HasWeight</span><span class="o">)</span> <span class="n">p</span><span class="o">)</span>
<span class="o">.</span><span class="na">forEach</span><span class="o">(</span><span class="n">p</span> <span class="o">-></span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span>
<span class="n">p</span><span class="o">.</span><span class="na">getName</span><span class="o">()</span> <span class="o">+</span> <span class="s">" is "</span> <span class="o">+</span>
<span class="n">p</span><span class="o">.</span><span class="na">getAge</span><span class="o">()</span> <span class="o">+</span> <span class="s">" years old and weighs "</span> <span class="o">+</span>
<span class="n">p</span><span class="o">.</span><span class="na">getWeight</span><span class="o">()</span> <span class="o">+</span> <span class="s">" pounds."</span>
<span class="o">)</span>
<span class="o">);</span>
</code></pre></div></div>
<p>Using the and-character (<code class="highlighter-rouge">&</code>) we can cast instances that implement all the required traits into a dynamic type, without them sharing an ancestor.</p>
<p>Was this interesting? In <a href="/java/Using-Traits-in-Java-8">the following article</a> I present a more formal definition of the Trait Pattern in java.</p>
<p><a href="http://ageofjava.com/java/Using-Traits-in-Java-8">Using Traits in Java 8</a> was originally published by Emil Forslund at <a href="http://ageofjava.com">Thoughts and Ideas Related to Java Programming</a> on January 27, 2016.</p>