Coming from a software development background mainly rooted in Java I have spent roughly two years away from the Java world, exploring the wonderful aspects of embedded system design in the automotive industry. Taking on new challenges yet again related to Java is a cognitive homecoming of sorts for me while the spatial aspects of the new job initially entail transatlantic commuting. My first California visit on the new job at Speedment Inc luckily coincided with the JavaOne 2016 conference in San Francisco.
The story that you are about to read is about one particular encounter at this for me very inspiring event. You will learn about Hares and Reindeer, Nordic cooperation at its finest and a perfect match of frameworks creating an inspiringly elegant hello world web application rendering data from a relational database in a browser.
TL;DR: Jump directly to the take home message or the code in case you do not want to indulge in the full narrative.
JavaOne 2016 Keeping the Promises of Conferences Past
Having watched the progress from a certain distance since the automotive industry has a way of absorbing one's attention, it was a delight to be back in 2016 to what seemed quite similar to the bright future pictured a few years ago. The future progress promised in 2013 had not only materialized but also been widely embraced. The functional paradigm of Java 8 lambdas and streams had not been received as just a facelift but as the fundamental gamechanger it actually is.
Attending a big conference when just having started a new job is a great way of getting a feel for the general direction of the industry and the way the product of the company is received. An inspiring and greatly informative quick start, participating at such a major congregation immediately tells what parts of our product actually peak others interest and what kind of questions arise during follow-up discussions.
I learned from several enthusiastic exchanges that Speedment bringing Java 8 style functional programming in an innovative and uniquely consistent way to the realm of relational databases was the key factor that caught others attention.
An Inspiring Meeting - Vaadin and Speedment
Capturing the spirit of the meeting the graphic illustration of this blog post is inspired by painter John Bauer and pictures a reindeer and a hare working together. With its roots in Finland, Vaadin has a Reindeer mascot. Speedment has Swedish heritage and mascot Hare.
Nordic people may not be known for overly expressive outbursts of enthusiasm, but I believe that I displayed my excitement with an average of more than one positive word per sentence and an occasional smirk that may have resembled a smile. Thus expressing profound enthusiasm (bordering the socially acceptable in my home country) about the promising outlook, we decided to try it out. What about trying to get Vaadin and Speedment work together there and then at the exhibition hall of the conference?
It has happened to me many times that what at first seems like a great idea in theory somehow does not handle the meeting with reality very well. General discussions in the abstract world of concepts quite often reveal overlapping or matching ideas that implicate great synergies, only to let one down when further explored. This is quite natural for at least two reasons;
- We are able to reason about fundamentally complex systems much due to our ability to perform agile transitions between different levels of abstraction. Roaming the realm of higher abstractions, we allow ourselves the luxury of turning a blind eye to details, enabling us to find patterns on a larger scale. When descending the stairs of abstraction to lower levels we often find ourselves knee deep in a swap of complicating details.
- Additionally, when talking about newly found synergies, one only has deep knowledge about a limited part of the problem since otherwise the topic at hand would not be new in the first place. Compared to thinking within one’s knowledge comfort zone, reasoning about something one does not really know typically gives rise to much creativity and rejoicing but increases the risk of creating things that simply do not work.
Well knowing this, setting out to create running code right there on the exhibition floor seemed like a fun exercise yet doomed to run into some obstacle, no matter how clean and perfect the match does initially seem. It would turn out that the expected obstacles never materialized.
Creating a Hello World Relational Data Web Application
After some ten minutes of coding no more than standard instructions of the respective framework, the browser of my laptop rendered data from a table of an SQL database. The data was delivered by Speedment, manipulated in straightforward Java 8 code with minimal boilerplate and then sent to Vaadin for rendering.
One reason that this application worked more or less out of the box is that Vaadin and Speedment agree on using standard Java constructs in their interfaces. Had there been any special constructs used for any of the frameworks, the code would be bloated with adapting boilerplate.
For the toy example we started out with one of our example databases. The table of interest in this example is a table of hares that have name, color and age.
CREATE TABLE `hare` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`color` varchar(45) NOT NULL,
`age` int(11) NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO hare (name, color, age) VALUES ("Hansel", "Gray", 3);
INSERT INTO hare (name, color, age) VALUES ("Henrietta", "White", 2);
INSERT INTO hare (name, color, age) VALUES ("Henry", "Black", 9);
INSERT INTO hare (name, color, age) VALUES ("Harry", "Gray", 400);
The business logic of our toy example is minimal, the following declarative code describes filtering out hares that have age above 3 and collecting them in a list. The Speedment framework has an API founded in Java 8 streams, a fact that was the major cause of excitement when describing Speedment to people I met at JavaOne. For further reading on that topic, please see for example this previous blog post.
final List haresList = hares.stream()
.filter(Hare.AGE.greaterThan(3))
.collect(Collectors.toList());
The first line starts out the description of an operation pipeline operating on a stream of hares from the database and the second line adds a filter to the pipeline telling Speedment to find hares of the desired age. The last line terminates the pipeline, defining the result as a list of the filtered hares.
Having a list of beans, a table of the Vaadin framework can be populated by the following piece of code.
MTable<hareimpl> table = new MTable<>(Hare.class)
.withCaption("Hares older than 3 years")
.withProperties("name", "color", "age");
table.setRows(haresList);
setContent(table);
A First Test Run
mysql> SELECT * FROM hare;
+-----+-----------+-------+-----+
| id | name | color | age |
+-----+-----------+-------+-----+
| 1 | Hansel | Gray | 3 |
| 2 | Henrietta | White | 2 |
| 3 | Henry | Black | 9 |
| 700 | Harry | Gray | 400 |
+-----+-----------+-------+-----+
4 rows in set (0,00 sec)
Our business logic described above filters out the hares with age strictly greater than 3, yielding two lines of the table presented in the browser.
Further Improvements
The upcoming Vaadin 8 API promises to take Java 8 support to a higher level. See for example this blog post. I look forward to exploring how this may enable even more elegant Speedment Vaadin interaction.
Final Remarks: The Take Home Message
I thoroughly enjoyed being there to see this application appear on my screen. It gave me some insight into the Vaadin framework and I took with me new knowledge of how to give a quick visual presentation of the power of the Speedment framework. For a back end tool provider, demonstrating end user value is often an indirect exercise. To show a relevant example of how to use our tool, we need to add some front end presentation and Vaadin is a great match for doing so in the future.
The two frameworks seamlessly interacting to create a solution to a toy representation of a real use case, in this case a web application using a relational database, is a sign of relevancy and maturity of both frameworks.
What you have seen here is a starting point of more to come, a proof of concept if you will. Since the two frameworks complement each other so well to create a self contained complete example, we will build on this to create more elaborate Speedment web applications using Vaadin . For a developer new to the field, it is very easy to see that the frameworks solve and abstract away the domain specifics and allows the developer of the business logic to create her application using modern standard Java code with minimal concern for boilerplate or framework specific constructs.
As described in more detail in for example this blog post, Speedment allows a developer to access the relational database in a declarative way without explicitly creating SQL queries, which allows for very elegant code with low maintenance cost. The proof of concept described here shows how nicely Vaadin provides a web front end that works with Speedment out of the box.
Appendix: How to Run the Application
- Create the database table.
CREATE TABLE `hare` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(45) NOT NULL, `color` varchar(45) NOT NULL, `age` int(11) NOT NULL, PRIMARY KEY (`id`) );
- Populate the database with some data to make the application result interesting.
INSERT INTO hare (name, color, age) VALUES ("Hansel", "Gray", 3); INSERT INTO hare (name, color, age) VALUES ("Henrietta", "White", 2); INSERT INTO hare (name, color, age) VALUES ("Henry", "Black", 9); INSERT INTO hare (name, color, age) VALUES ("Harry", "Gray", 400);
- Clone the github skeleton containing a
pom.xml
file and the java code from this blog post.git clone https://github.com/lawesson/speedment-vaadin-demo.git
- Change directory to the newly created git repo.
cd speedment-vaadin-demo
- Run the Speedment code generation tool.
mvn speedment:tool
- Enter database credentials in the UI, fill in the schema hares and press the Generate button without changing any defaults to create Speedment code.
- Run the application. Substitute pwd and user with proper database credentials.
mvn -Djdbc.password=pwd -Djdbc.username=user compile exec:java
- With the application running, point a browser to the Vaadin rendered UI located at http://localhost:8080.
- Optionally, add some more hares in the table and reload the browser page to see the data filtered by your application.
Edit: Since this post was originally published, Matti Tahvonen of Vaadin has provided valuable feedback and a pull request to the git repo bringing the example code up to speed with the latest advances of Vaadin technology.