Spring Boot, MongoDB and raw JSON

Sometimes you want to store and retrieve raw JSON in MongoDB. With Spring Boot storing the JSON isn’t very hard, but retrieving can be a bit more challenging.

Setting up

To start using MongoDB from Spring Boot, you add the dependency to spring-boot-starter-data-mongodb

	<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>


And then you inject MongoTemplate into your class

@Autowired
private MongoTemplate mongoTemplate;


Inserting into MongoDB

Inserting JSON is just a matter of converting the JSON into a Document, and inserting that document into the right collection

String json = getJson();
Document doc = Document.parse(json);
mongoTemplate.insert(doc, "CollectionName");


Retrieving JSON

Retrieving JSON is a bit more complicated. First you need to get a cursor for the collection. This allows you to iterate over all the documents within that collection. Then you’ll retrieve each document from the collection, and cast it to a BasicDBObject. Once you have that, you can retrieve the raw JSON.

DBCursor cursor = mongoTemplate.getCollection("CollectionName").find();
Iterator iterator = cursor.iterator();
while (iterator.hasNext()){
BasicDBObject next = (BasicDBObject) iterator.next();
String json = next.toJson();
// do stuff with json
}


Transforming raw JSON to Object

With Jackson you can transform the retrieved JSON to an object. However, your object might miss a few fields, since MongoDB adds some to keep track of the stored documents. To get around this problem, you need to configure the ObjectMapper to ignore those extra fields.

ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)


Lessons learned

Pressure makes diamonds, as the saying goes. I worked on a high-pressure project for a couple of weeks (as in, it needed to be done before we even started), and these are some of the lessons we learned as a team. The lessons are mostly tips and tricks, as we learned a lot on the job.

General lessons learned

Way of working

Bring (at least) two developers to the project. One will focus on the algorithm, the other will focus on the code quality and support as much as possible. Notice the choice of words: “focus”. This means that all developers do all the things, but their main task is different.
Don’t underestimate the impact of code quality. Code should be as clear as possible, so that it doesn’t get in the way of solving the business problem. When you’re constantly thinking about what the code does, you’re not thinking about how to solve the business problem. On that note, the first versions were set up as procedural. Refactor to object oriented. OO has advantages over procedural, and it would be a waste to not have access to those advantages. This refactoring was well worth the effort, as we had our codebase audited. No major flaws were encountered during the audit.

Version control

Get a version control tool in place, and choose the one that is easiest to use. You can share code by emailing .zip files, but that’s too cumbersome. Besides, errors get made. Use git, ask around how to do that, and ignore project managers who tell you not to do this. Even a paid github repository is better than nothing.

maven

Manually include dependencies

It is possible to add dependencies to the build, without the need for those dependencies to be available in a repository. You’ll include them from a /lib folder or something like that:

        <dependency>
<groupId>group.id</groupId>
<artifactId>artifact</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/test/resources/to-include.jar</systemPath> </dependency>  Create complete jar To build the resulting jar with dependencies, use the following command: mvn assembly:assembly -DdescriptorId=jar-with-dependencies Version tracking Resource filtering, to update variables in your resources with maven properties. But only variables in certain files, all other files should not be filtered because that might corrupt them:  <build> <resources> <resource> <directory>src/main/resources</directory> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>project-version.properties</include> </includes> </resource> </resources> </build>  Contents of project-version.properties: version =${build.version}


where ${build.version} is a property in the pom file, along with the format for this timestamp: <properties> <maven.build.timestamp.format>yyyyMMdd-HHmm</maven.build.timestamp.format> <build.version>${maven.build.timestamp}</build.version>
</properties>


 mvn dependency:sources

This will allow you to inspect the actual source code when you’re in a debugging session.

Skip tests

There are two ways of skipping unit tests:

mvn -DskipTests <task>

Only skips _executing_ the tests. The unit tests will still be compiled

mvn -Dmaven.test.skip=true

Does not compile the tests, and therefore the tests are not executed.

One piece of software

For testing purposes, we made our program so it ran locally. The same program could run, without modifications, on the server. We used hard-coded paths and keys for the server version, with fallbacks for the local standalone version. This allowed us to focus on the algorithms, and find/fix environments issues quite fast.

Patching jars

We had to patch the Mendelson jars a few times, before we decided to create a maven build script for the source code.

javac -classpath <jar to be patched>;<jars containing non-local classes used by the class to be compiled> path\to\modified\file.java

Then open the jar with a zip-tool (7zip, for example), and replace the old class with the newly compiled version.

Logging

Add as much logging as useful. This is probably more than you think. In our case, logging wasn’t showing up. So we wrote a LoggingFacade which wrote its output to the default logging framework, AND to System.out or System.err if needed.

Debugging

Debugging will provide more information than logging, but is not always possible.
Make one version that run standalone, so you can attach a debugger while developing.
Make sure you can remotely debug the server. Start the server with debug enabled, with the following command-line parameter:

-agentlib:jdwp=transport=dt_socket,address=localhost:4000,server=y,suspend=y

This starts the program in debug mode, listening to debuggers on TCP port 4000. You can choose any port that is convenient for you.

You might need to open an SSH tunnel to your server, listening locally to port 4000, and forwarding it to localhost:4000. Notice that localhost is the localhost of the server, not the localhost from which you make the connection to the server.

Then configure your IDE to connect to a remote application.

Spring-Boot

One of the avenues we’ve explored was to build a standalone program to intercept and process the messages in a more controllable way. Spring-Boot was introduced for this, but not continued. It is worth exploring these kinds of avenues when you’re stuck, because they might give some insight in how to continue.
Spring-Boot offers quite a lot of extras that we can use for our project, such as a standalone server (run with mvn spring-boot:run). Any application can still be run from within the IDE, because the applications still have a main() function.

Switching from application: https://stackoverflow.com/questions/23217002/how-do-i-tell-spring-boot-which-main-class-to-use-for-the-executable-jar

To test the producing service, use Postman (https://www.getpostman.com/apps)
The service can be reached with a POST request on http://localhost:8080
Body type: raw
Body contents can be found on the producing link, file is called “request.xml”

Project specific

Decrypting XML

The XML might have been encrypted with a cipher that isn’t available to you. Find the correct cipher in the following section:

	<xenc:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#rsa-oaep">
<ds:DigestMethod xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<xenc11:MGF xmlns:xenc11="http://www.w3.org/2009/xmlenc11#" Algorithm="http://www.w3.org/2009/xmlenc11#mgf1sha256"/>
</xenc:EncryptionMethod>


Take special note of the Digest Method and the Mask Generation Function, as these might not be available to you. You need to use a third party library that implements the exact cipher that is used. In our case that is Apache Santuario.

Initializing Santuario

Santuario must be initialized before it’s used. However, before initializing the main cryptography engine, the Internationalization framework needs to be initialized. Normally this is initialized with the locale en-US, but only the en (without the _US_ part) properties file is available. This should not be a problem, since this properties file is part of a fallback mechanism. However, in our case, this fallback mechanism doesn’t work.
First initialize Santuario with an empty resource bundle, then initialize the cryptography engine.

Binary data

In one instance of our project, the binary file had a repeating sequence EF BF BD. This is caused by creating a String from the binary data, and requesting the bytes from that String. Strings and binary aren’t the best of friends, keep them separated!

JVMCon

On 30 January 2018, the first edition of JVMCon was organised. It was a small conference, only a couple of hundred attendees, but it was sold-out anyway. I attended five sessions, and I will list them in order of least to most awesome.

The first session I attended was by Alexander Yadayadayada (his joke, not mine) about gamification to increase code quality. Most of the ideas came down to “make it a contest!”. And most of the ideas that he tried so far weren’t very succesful. When you make a set of rules for engineers, they will always find ways to game the system and get ahead without any effort. For example, one point per unittest: create empty unittests. Give someone a taco on slack for doing something awesome: “Hey, I don’t have any tacos, could anyone throw me some?” But the biggest problem seems to be that people usually decide to stop playing, because the game isn’t balanced properly.

Hadi Hariri’s session was named Kotlin 102. It didn’t cover the basics of Kotlin, but a bit more advanced stuff. Hadi had a live-demo presentation, which is always impressive. However, he was talking to a tough crowd. Perhaps the reason was because his session was after lunch. Or maybe Kotlin isn’t known well enough yet to get into the more advanced stuff.

The third session in this list is that of Angelo van der Sijpt: What you didn’t know you wanted to know about the JVM. This one started to tickle my nerdy-senses. He spoke of Java, bytecode, C and even assembler, right down to the individual instructions that will be executed by the CPU. Then there were bits about how the memory is really used. There was a quizz: is this word a CPU instruction or not? Hint, IDCLIP is not. It was an interesting talk, but a bit too advanced for me.

Then there is Venkat Subramaniam’s talk about Java 9 Modularization. Modules are here, and they are here to stay. However, I don’t think the world is ready for it just yet. And with the new Java release cycle (And totally messed-up versioning system. WTF Oracle, really?), I don’t think there will be many production systems that will run Java 9. Anyway, Venkat started his talk with the remark “If there are any questions, please interrupt”. Then he started to spew information faster than the audience could process it. So, when you wanted to ask a question, he was already three topics ahead. He also had a live demo, which didn’t always go as planned. But then again, he disguised a typo with a joke: “If you do this, things go so wrong that you don’t even get an error. You get an ERRRO!” If you want to go to an information rollercoaster, see Venkat live.

Take the sum of the awesomeness of all the previous talks, and then multiply it with the sum of their nerdyness, and you’re still not even close to the last talk. This one was in a league of it’s own: Don’t hack the platform? by Jan Ouwens. If you need inspiration for messing with your colleagues, this is the one for you. From Unicode-hacks to overwriting JVM constants to changing complete method implementations. …On a running system. …remotely. This guy had some evil, evil hacks.

Class size

Imagine that you need to maintain two applications. Both are about 20.000 lines of code. Now imagine that one has about 10 classes, and the other has 200 classes. Which one would you rather work with?

I’ve had discussions about whether you should favor many classes over fewer. When you only take into account the amount of functionality delivered through those classes, it doesn’t matter. The same functionality will be in the codebase, whether there are few classes or many. Since creating a new class takes effort (not much, but still), it’s easier to have a few big ones. One could say that having a few big classes would contain related functionality in the same files.

The amount of functionality in the system isn’t the only metric. The ease of adding functionality and solving defects, and unit-testing are examples of other metrics that should be taken into account.

Big classes usually have lots of private methods. So, how are you going to write unit-tests for them? Are you going to use reflection to make those methods accessible? Are you going to write extensive setup code to reach those methods? Or are you going to extract classes containing those methods, and make them publicly accessible?

How are you going to change the functionality? How are you going to fix defects? Big classes are big, and usually it’s hard to keep track of what’s going on. Because of this, you’re spending more time figuring out what the code is doing, and what it actually should do. The clearer the intention of your code, the less time you need to spend on getting to know what it’s doing.

Personally, I prefer lots of small classes. But how do we get there? When you’re presented with a legacy project, it requires a lot of refactoring. But beware, don’t just go out and refactor. If there are no issues, and the required functionality doesn’t change, that part of the codebase is just fine. On the other hand, when you start a new project, it’s a bit easier.

One of the first thing I’d recommend is to read up on the SOLID principles. SOLID stands for Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation and Dependency Inversion. Knowing and applying these principles will help you create a well-factored system. You probably won’t be able to apply these principles all of the time, but it definitely helps to know about them.

Put some tests in place, and make sure these tests are of the highest quality. The more and better tests you have, the more secure your refactorings will be. As an added bonus, you gain knowledge of and insight in the system you’re working on. As you progress with fixing defects and implementing new functionality, the amount of code under test will increase, and the faster you can develop and refactor.

Practice Test Driven Development. Write a test, make it pass, and refactor to optimise readability. Make sure you do the last step, TDD won’t work otherwise. TDD will help you create a clear system with very high test-coverage. And that coverage will be high quality.

Use as few if-statements and switch/cases as possible.Using as few conditionals as possible makes the codebase more usable, because it forces you to use more object oriented design. You could use an inheritance structure, or a table-/map-based approach. There may be other patterns, if you’re creative enough to discover them.

In our current project there is a guideline that all of the public API must have Javadoc. I disagree with this guideline. Our project does not have a public API, since we’re the only team that works on this project and no other team is allowed to use the codebase. Public classes and methods are not the only criterium for a public API.

So I asked, how many times is the Javadoc actually read, versus looking at the actual code to see what the method does? Personally, I never look at the Javadoc, and I suspect I’m not alone in this practice.

So why don’t I read Javadoc in our project? I don’t trust it. We’re using IntelliJ Ultimate, and this IDE also finds errors in Javadoc. And there are lots and lots of errors. So I don’t trust it.

When you’re working on the code, you’re not updating the accompanying Javadoc. The reason for this is the same as why you don’t write unittests – unless you’re using TDD: you’re solving a problem, and you need your attention there.

Javadoc is useful when you’re writing a library, and actually want third parties to use it. They need this form of documentation.

As for our project, there are other ways of documenting the code. You can (and must, in my opinion) factor the code to be as clear as possible. Good naming practices are a good step towards self-documenting code.

Another way of documenting, is writing clear unittests. You don’t need to write them first, though that is often the easiest way to write them. As long as you run them, you have a form of documentation that fails if incorrect.

For the same reason, you can use the assert keyword. To enable this, you need a runtime JVM argument, by default it is disabled. This means assert statements are not executed in production, but neither is Javadoc. However, during development, asserts can provide a treasure of information and verify the correctness of your program. The assert keyword IS documentation.

No documentation is bad, wrong documentation is worse. Javadoc tends to turn wrong when the codebase changes, and should therefore be avoided if possible.

Internet of Things

On 19 April 2017 about 1300 tech enthusiasts gathered in Utrecht for the IoT tech day. During this day I noticed two themes: on the one hand there were project demos, on the other hand there were talks about why you should use certain products and services to connect your projects. This showed me the state of IoT at this moment: it’s still early on the technology curve. This means that the tools and frameworks need to be developed further, and, more importantly, that standards still need to emerge. This in turn will lead to new ways of thinking about computing.

Part of the problem is that the term Internet of Things (IoT) is not very well defined yet. Is virtual/augmented/mixed reality part of IoT? How about cloud computing? Artificial Intelligence or Machine Learning? Mobile apps?

In my view, IoT consists of three parts: data collection using sensors, data processing using a cloud infrastructure, and presentation. In this regard, IoT is not different from any computer program. The difference is in the way the data is collected and processed, the infrastructure of IoT. In traditional computing, the data is sourced from a few sources, processed, and presented to the user. In IoT data is generated from thousands, perhaps millions of sensors. Due to the volume of data that is potentially generated, processing speed and storage becomes a challenge.

This is where the infrastructure comes in. Instead of one monolithic program, running on a giant machine, we build and connect any number of (micro-) services, running on multiple servers, located all around the world. These services aren’t written in a single language: we can choose whatever seems best for that particular step.

This is a game-changer. The role of a software engineer is not just to translate functional requirements to source-code. Maintaining changeability is also a key objective. We do this by abstracting complexity away, and organizing the code so its intention is as clear as possible. Methods should do only one thing, and they should do it well. Classes should have one responsibility, one reason to change. Now we can add services to this list, although I’m not sure what role these services will play in the abstraction and organization of code.

For now, the Internet of Things is the domain of tech-enthusiasts and big companies cashing in on infrastructure. However, this is the next revolution in computing. The personal computer, the Internet, and mobile each supplied their own challenges and solutions. Each revolution built on the previous one. IoT is the next revolution moving computing forward.

Technical Debt

Technical debt is acquired when you take shortcuts while developing your software. It helps you get the changes in place faster, but it results in code that is harder to understand.

Ward Cunningham coined this term while he was working in a financial institution to explain why they were refactoring. His boss at the time was a financial guy, and this was financial software, so a financial metaphor was the best way to explain this principle.

When you want to buy a car, and you don’t have the money, there are basically two things you can do. You can wait and save until you do have the money to buy the car, or you can borrow it. Translating this to writing code, you can implement the feature correctly, with clean and clear design. This way, when it needs to change, it is easy to understand and changing it will be faster. Or, you can do it the quick and dirty way. This is faster, for now. But when the time comes to change the code, it will take more time.

The two components of financial debt also apply to technical debt. There is interest, and there is principle. We pay interest when we need to change dirty code, and we pay down the principle when we clean that code up.

Martin Fowler divides the term Technical Debt into four categories. Reckless vs. Prudent, and Deliberate vs. Inadvertent:
Deliberate, Reckless: “Design is boring and time consuming. This works, so who cares?”
Deliberate, Prudent: “We really should do this, but the deadline is approaching fast. We’ll note our shortcuts and refactor after the deadline.”
Inadvertent, Reckless: “What’s wrong with an entitymanager in the weblayer?”
Inadvertent, Prudent: “This seemed like a good idea at the time. Now we know how we should have done it.”

Here are a few things to help get technical debt under control.

Naming

Choose good names for your functions and variables, and rename to better names when your understanding of the code changes.
You are not just telling the computer what to do. You are also writing a document for future developers. You are creating a language in which to communicate your thoughts about the problem at hand. This language is a mixture of reserved words of the programming language (for, if), terms that are used in the domain (account, customer), and terms that are common in our industry, such as design patterns (action, command, listener). The easy part is  getting the computer to do what we want it to do. The hard part is telling our future selves what we are thinking.

Shorter methods

“Rule 1 of methods: they should be short. Rule 2 of methods: they should be shorter than that!”
“Functions should do one thing. They should do it well. They should do it only.”
Longer methods tend to do more than they should. Splitting methods into smaller methods makes them more readable, manageable, and reusable. Another advantage of smaller methods is that you get lots of them, and that makes it easier to group them in the correct classes.

Unittests

While the production sourcecode is the primary document we deliver, there is another document: unittests. When written correctly, unittests are quite helpful in further explaining the code. They will tell how objects are created and used. This is one of the reasons Test Driven Development is useful. They are also quite useful for spotting design flaws. For example, when you find an uncovered private method, and it’s just too hard to reach it through the public interface of the class, chances are that the class has too many responsibilities and should be split into multiple classes.

Remove duplications

With shorter methods comes a more fragmented codebase: functionality is split into more fragments. This usually means that duplications become more visible. The duplications are already in the code, but sometimes they are hidden. Duplications are generally considered bad, because it usually means that you need to apply the same change to multiple pieces of code. And that’s easy to forget. According to Kent Beck, eliminating duplications is a powerful way of getting a good design.

Single Responsibility Principle

What does the class do? What reasons does it have to change? How many responsibilities does it have? A class should have only one role, only one responsibility. For example, it should only validate input, or format some text. Some ways of finding the responsibilities of a class include grouping of method names and drawing the relations of the class members.
Responsibilities can live on the interface level, and on the implementation level. Classes can either delegate the responsibility to other classes, or they can implement the responsibility themselves. When a class implements too many responsibilities, it’s easier to move just the implementations those responsibilities to other classes, and keep the original methods. These methods then act as a gateway to the new classes. Over time, we can modify the system so it only uses the new classes, and then we can remove the gateway methods.

Test driven development

TDD is the ultimate agile practice. You can’t get faster feedback cycles than with TDD: often a cycle lasts well under a minute. Because of this, you always know that you’re moving to the target.

However, I’ve met very few people who know about TDD, and even fewer who actually practice it. I was at a technical meeting a couple of months ago, where the presenter asked the question who knew about Test driven development. Out of about 50 developers who were present, only about 10 raised their hands. The question who had experience with it managed to raise only three or four hands.

But it’s even worse than that. I’ve worked on quite a few projects, and most of them had a limited set of unittests. The project that I’m working on now only has about 42% coverage, and a good deal of code is covered by useless or unreadable tests. Useless, because the tests don’t actually check the behavior. Unreadable, because of duplications, long setups and multiple asserts per test.

As an industry we know that unittests are important to catch bugs early on. But unittests are often written after the production code, and that’s boring and complicated. So, often it is skipped altogether. Writing unittests before writing production code, or actually, alternating between writing tests and production code, would help.

The main sequence of TDD is as follows:

• Red: Write a test to specify the behavior. This test will fail because the behavior doesn’t exist yet, resulting in a red bar.
• Green: Write the behavior specified by the test. Get it working as soon as possible, it is OK to make a mess.
• Refactor: Eliminate duplications. Both from the production code and from the tests. This last point is important, because the tests need to be readable to be useful.

When you follow this sequence over and over again, you’ll start to notice that the code you produce is quite nice to read, and well factored. The code will tell you how it wants to be designed: design emerges, instead of being imposed on the code.

Fixing bugs is also faster with TDD. Once you’ve located the problem, write a test to verify that problem. Then adjust the test so it will verify the correct behavior. At that point you don’t need to go through the compile/deploy/test cycle again. You just run the unittest to see if you’re making progress. Then, when you fixed the behavior according to the test, you can always test it manually.

The biggest downside of TDD is that it is hard to learn. Perhaps this is the reason why it is not practiced as much as it should. It is a mindset, a habit that needs to be formed. It will take months to get good enough. Therefore, it is recommended to practice on a side-project, or at least practice on small, clearly defined pieces of behavior. But once you do use TDD, you will be a better developer.

Maven, Hibernate, PrimeFaces and Jetty

In this post, we will make a (very) simple CRUD application using Maven, Hibernate, PrimeFaces and Jetty. It won’t be the best application out there, but enough to get started. Run ‘mvn jetty:run’ to start the application.

In this case, we’ll be making a simple addressbook, with each contact having a first and last name, and an address. The address will have a city, street, housenumber and postalcode. They will each have an id, because they need to be stored somewhere. This is what they look like:

package nl.ghyze.contacts;

public class Contact {

private Long id;
private String firstname;
private String lastname;

public void setId(Long id){
this.id = id;
}

public Long getId(){
return id;
}

public void setFirstname(String firstname){
this.firstname = firstname;
}

public void setLastname(String lastname){
this.lastname = lastname;
}

public String getFirstname() {
return firstname;
}

public String getLastname() {
return lastname;
}

}

}
}

package nl.ghyze.contacts;

private Long id;
private String city;
private String street;
private String housenumber;
private String postalcode;

public void setId(Long id) {
this.id = id;
}

public Long getId() {
return id;
}

public void setCity(String city) {
this.city = city;
}

public String getCity() {
return city;
}

public void setStreet(String street) {
this.street = street;
}

public String getStreet() {
return street;
}

public void setHousenumber(String housenumber) {
this.housenumber = housenumber;
}

public String getHousenumber() {
return housenumber;
}

public void setPostalcode(String postalcode) {
this.postalcode = postalcode;
}

public String getPostalcode() {
return postalcode;
}
}


Of course there needs to be a database schema to store the records in. We will use a MySQL database for this. For simplicity, all keys are bigints, and all other fields will be varchars.

create schema if not exists contacts;
use contacts;

create table if not exists address
(id bigint primary key,
city varchar(100),
postalcode varchar(10),
housenumber varchar(10),
street varchar(100)
);

create table if not exists contact
(id bigint primary key,
firstname varchar(255),
lastname varchar(255),


Now we will need to tell Hibernate how to map the database tables to objects. These days you’ll probably use annotations for that, but to keep database-related code out of our entities, we’re going for XML configuration.
The mapping for contact will look like this:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="nl.ghyze.contacts">
<class name="Contact" table="contact">
<id name="id" column="id">
<generator class="increment" />
</id>
<property name="firstname" column="firstname" />
<property name="lastname" column="lastname" />
</class>
</hibernate-mapping>


<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="nl.ghyze.contacts">
<id name="id" column="id">
<generator class="increment" />
</id>
<property name="city" column="city" />
<property name="postalcode" column="postalcode" />
<property name="housenumber" column="housenumber" />
<property name="street" column="street" />
</class>
</hibernate-mapping>


Now we need to configure hibernate, telling it how to connect to our database and which mapping files to use.

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/contacts?useUnicode=true&amp;useJDBCCompliantTimezoneShift=true&amp;useLegacyDatetimeCode=false&amp;serverTimezone=UTC</property>

<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>

<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

<!-- Do not show executed SQL -->
<property name="show_sql">false</property>

<!-- Validate the database schema on startup -->
<property name="hbm2ddl.auto">validate</property>

<!-- Use these mapping files -->
<mapping resource="nl/ghyze/contacts/Contact.hbm.xml"/>
</session-factory>
</hibernate-configuration>


Next step, setting up the connection from our application. Since we want only one place to manage the database connectivity in the application, this will be set up as a Singleton.

package nl.ghyze.contacts.repository;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

public class DatabaseSessionProvider {

private static final DatabaseSessionProvider instance = new DatabaseSessionProvider();

private SessionFactory sessionFactory;

private DatabaseSessionProvider(){
setUp();
}

public static DatabaseSessionProvider getInstance(){
return instance;
}

public Session getSession(){
Session session = sessionFactory.openSession();
session.beginTransaction();
return session;
}

public void end(Session session){
if (session.getTransaction().getRollbackOnly()){
rollback(session);
} else {
commit(session);
}
}

private void commit(Session session){
session.getTransaction().commit();
session.close();
}

private void rollback(Session session){
session.getTransaction().rollback();
session.close();
}

public void shutDown(){
sessionFactory.close();
}

private void setUp() {
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure()
.build();
try {
}
catch (Exception e) {
e.printStackTrace();
StandardServiceRegistryBuilder.destroy( registry );
}
}
}


At this point we’re ready to read, write and delete contacts from and to the database. We’re going to use HQL for this purpose.

package nl.ghyze.contacts.repository;

import nl.ghyze.contacts.Contact;
import org.hibernate.Session;
import org.hibernate.query.Query;

import java.util.List;

public class ContactRepository {

private final DatabaseSessionProvider provider;
private Session session;

public ContactRepository(){
this.provider = DatabaseSessionProvider.getInstance();
}

public Contact saveContact(Contact contact){
session = provider.getSession();
session.saveOrUpdate(contact);
provider.end(session);
return contact;
}

public List<Contact> getAllContacts(){
String queryString = "from Contact";
Query<Contact> query = createQuery(queryString);
List<Contact> result = query.getResultList();
provider.end(session);
return result;
}

public void deleteContact(Contact contact){
session = provider.getSession();
session.delete(contact);
provider.end(session);
}

public Contact getContactWithId(Long id){
if (id == null){
return null;
}
String queryString = "from Contact where id = :id";
Query<Contact> query = createQuery(queryString);
query.setParameter("id", id);
Contact contact = query.getSingleResult();
provider.end(session);
return contact;
}

private Query<Contact> createQuery(String queryString) {
session = provider.getSession();
return session.createQuery(queryString, Contact.class);
}
}


With the database stuff out of the way, let’s create a simple service for communicating with the repository. At this point we’re getting into PrimeFaces. We’re making this a ManagedBean, so it can be injected into the Action classes that we’ll discuss next.

package nl.ghyze.contacts.service;

import nl.ghyze.contacts.Contact;
import nl.ghyze.contacts.repository.ContactRepository;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import java.util.List;

@ManagedBean(name="contactService")
@SessionScoped
public class ContactService {

private ContactRepository contactRepository = new ContactRepository();

public List<Contact> getContactList(){
return contactRepository.getAllContacts();
}

public Contact saveContact(Contact contact){
return contactRepository.saveContact(contact);
}

public Contact getOrCreateContact(Long id){
Contact contact =  contactRepository.getContactWithId(id);
if (contact == null){
contact = new Contact();
}
}
return contact;
}

public void deleteContact(Contact contact) {
contactRepository.deleteContact(contact);
}
}


Before we continue, let’s take a moment to think about the front-end of the application. We’re going to make two pages: the first one listing all the contacts that we have, and the second one listing the details of one single contact. Each page will have its own backing class, handling the server side actions of the requests.
The list action will be simple: it only needs to provide a list of Contacts that is currently in our database.

package nl.ghyze.contacts.web;

import nl.ghyze.contacts.Contact;
import nl.ghyze.contacts.service.ContactService;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import java.util.List;

@ManagedBean(name="contactListAction")
@SessionScoped
public class ContactListAction {

@ManagedProperty(value="#{contactService}")
private ContactService contactService;

public List<Contact> getContactList(){
return contactService.getContactList();
}

public void setContactService(ContactService contactService){
this.contactService = contactService;
}

public ContactService getContactService(){
return contactService;
}
}


The details action will be a bit more complicated. It will need to be able to:
– get the correct contact
– save the edited contact
– delete a contact
– Since everything is SessionScoped, when the user wants to go back to the list, it needs to clear its values
The methods that receive an ActionEvent as parameter are called from PrimeFaces. Pay attention to the method signature, as this is something that lots of developers struggle with.

package nl.ghyze.contacts.web;

import nl.ghyze.contacts.Contact;
import nl.ghyze.contacts.service.ContactService;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import java.io.IOException;

@ManagedBean
@SessionScoped
public class ContactDetailAction {

@ManagedProperty(value="#{contactService}")
private ContactService contactService;

private Contact contact;

private Long contactId;

public Contact getContact(){
if (contact == null){
contact = contactService.getOrCreateContact(contactId);
}
return contact;
}

public void save(ActionEvent actionEvent){
contact = contactService.saveContact(contact);
redirectToList();
}

public void delete(ActionEvent actionEvent){
contactService.deleteContact(contact);
redirectToList();
}

public void back(ActionEvent actionEvent){
redirectToList();
}

private void redirectToList() {
reset();
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
try {
context.redirect(context.getRequestContextPath() + "/contactList.xhtml");
} catch (IOException e) {
e.printStackTrace();
}
}

private void reset() {
contact = null;
contactId = null;
}

public void setContactService(ContactService contactService){
this.contactService = contactService;
}

public ContactService getContactService(){
return contactService;
}

public void setContactId(Long id){
this.contactId = id;
}

public Long getContactId(){
return contactId;
}
}


Now we’re ready to create the .xhtml pages. For the list, we’re going to create a table for listing all contacts. The last column will have buttons, so we can edit the contact in that row. Clicking this button will navigate to the details page, supplying the ID of the contact. Below the table there will be a button for adding new contacts.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui">

<h:body>
<h:form>
<p:dataTable var="contact" value="#{contactListAction.contactList}">
<h:outputText value="#{contact.firstname}"/>
</p:column>
<h:outputText value="#{contact.lastname}"/>
</p:column>
</p:column>
</p:column>
</p:column>
</p:column>
<p:column style="width:32px;text-align: center">
<p:button icon="ui-icon-edit" title="Edit" outcome="contactDetail">
<f:param name="contactId" value="#{contact.id}" />
</p:button>
</p:column>
</p:dataTable>
<p:button outcome="contactDetail" value="new Contact"/>
</p:panel>
</h:form>
</h:body>
</html>


The details page is, again, a bit more complicated. This page receives the contactId, and sets it in the action. This part is a bit confusing, and it takes a while to understand. The f:metadata tag is responsible for this.
The p:commandButton tags are used to call methods in ContactDetailsAction. This is how those methods that take the ActionEvent parameters are called.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui" xmlns:c="http://java.sun.com/jstl/core" xmlns:f="http://java.sun.com/jsf/core">

<title>Edit Contact</title>

<h:body>
<f:viewParam name="contactId" value="#{contactDetailAction.contactId}" />
<h:form>
<c:set var="contact" value="#{contactDetailAction.contact}"/>
<h:outputText value="First name"/>
<h:inputText value="#{contact.firstname}"/>

<h:outputText value="Last name"/>
<h:inputText value="#{contact.lastname}"/>

<h:outputText value="Street" />

<h:outputText value="Housenumber" />

<h:outputText value="Postal code" />

<h:outputText value="City" />
</h:panelGrid>
<p:commandButton value="Save" actionListener="#{contactDetailAction.save}" ajax="false" />
<p:commandButton value="Delete" actionListener="#{contactDetailAction.delete}" ajax="false" />
<p:commandButton value="Back to list" actionListener="#{contactDetailAction.back}" ajax="false" />
</p:panel>
</h:form>
</h:body>
</html>


The Deployment Descriptor (web.xml) tells the application server how to handle incomming requests.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">

<!-- File(s) appended to a request for a URL that is not mapped to a web component -->
<welcome-file-list>
<welcome-file>contactList.xhtml</welcome-file>
</welcome-file-list>

<!-- Define the JSF servlet (manages the request processing life cycle for JavaServer Faces) -->
<servlet>
<servlet-name>faces-servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>

<!-- Map following files to the JSF servlet -->
<servlet-mapping>
<servlet-name>faces-servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>


The maven project configuration (pom.xml) tells maven how to build this project. It contains all the dependencies. Pay attention to the last part of the configuration, the maven-jetty-plugin. This is how we start, and test, the application.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>nl.ghyze</groupId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>

<servlet.version>3.1.0</servlet.version>
<jsf.version>2.2.13</jsf.version>
<primefaces.version>6.0</primefaces.version>

<maven-compiler-plugin.version>3.5.1</maven-compiler-plugin.version>
<jetty-maven-plugin.version>9.4.0.M0</jetty-maven-plugin.version>

<hibernate.version>5.2.1.Final</hibernate.version>
<mysql.version>6.0.3</mysql.version>
</properties>

<dependencies>
<!-- PrimeFaces -->
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>${primefaces.version}</version> </dependency> <!-- Servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<!-- JSF -->
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>${jsf.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.sun.faces</groupId> <artifactId>jsf-impl</artifactId> <version>${jsf.version}</version>
<scope>compile</scope>
</dependency>

<!-- Database-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>\${jetty-maven-plugin.version}</version>
<configuration>
<httpConnector>
<port>9090</port>
</httpConnector>
<webApp>
</webApp>
</configuration>
</plugin>
</plugins>
</build>
</project>


Split condition

Intuitively it makes sense to group several statements in an if/else clause. In that case you only need to execute the check once. However, this is not always the cleanest solution, and it makes methods longer than they should be.

For example, take the following piece of code.

    public void updateDocument(Attachment attachment){
Document document = new Document();
if (AttachmentModel.TYPE_SPECIAL.equals(attachment.getAttachmentType())) {
DocumentType documentType = repository.findByCode(DocumentType.class, DocumentType.CODE_SPECIAL);
document.setType(documentType);
document.setName(documentType.getName() + " " + getDateAsString());
} else {
document.setType(repository.findByCode(DocumentType.class, DocumentType.CODE_OTHER));
document.setName("Attachment " + getDateAsString());
}
}


So, what’s wrong with this? It does what it’s supposed to do, and it doesn’t look too complicated.

But it does too many things:

1. It checks the type of the attachment
2. Based on this type, it finds the DocumentType from the database
3. It sets the DocumentType of the Document
4. It generates a name
5. It sets the name of the document

To cite Uncle Bob (Clean Code, page 35):

Functions should do one thing. They should do it well. They should do it only.

So, let’s refactor.

First, copy the condition, and move the statements around so that each condition handles only one property of the document.

    public void updateDocument(Attachment attachment){
Document document = new Document();
if (AttachmentModel.TYPE_SPECIAL.equals(attachment.getAttachmentType())) {
DocumentType documentType = repository.findByCode(DocumentType.class, DocumentType.CODE_SPECIAL);
document.setType(documentType);
} else {
document.setType(repository.findByCode(DocumentType.class, DocumentType.CODE_OTHER));
}

if (AttachmentModel.TYPE_SPECIAL.equals(attachment.getAttachmentType())){
document.setName(documentType.getName() + " " + getDateAsString());
} else {
document.setName("Attachment " + getDateAsString());
}
}


This doesn’t compile, because documentType isn’t available in the second block. So, let’s move the declaration of DocumentType outside of the first block.

    public void updateDocument(Attachment attachment){
Document document = new Document();

DocumentType documentType = null;
if (AttachmentModel.TYPE_SPECIAL.equals(attachment.getAttachmentType())) {
documentType = repository.findByCode(DocumentType.class, DocumentType.CODE_SPECIAL);
document.setType(documentType);
} else {
document.setType(repository.findByCode(DocumentType.class, DocumentType.CODE_OTHER));
}

if (AttachmentModel.TYPE_SPECIAL.equals(attachment.getAttachmentType())) {
document.setName(documentType.getName() + " " + getDateAsString());
} else {
document.setName("Attachment " + getDateAsString());
}
}


Ah, that’s better. But there’s duplication: document.setType is called on two lines. Let’s move that outside of the if block. And, while we’re at it, let’s do the same for setName.

    public void updateDocument(Attachment attachment){
Document document = new Document();

DocumentType documentType = null;
if (AttachmentModel.TYPE_SPECIAL.equals(attachment.getAttachmentType())) {
documentType = repository.findByCode(DocumentType.class, DocumentType.CODE_SPECIAL);
} else {
documentType = repository.findByCode(DocumentType.class, DocumentType.CODE_OTHER)
}
document.setType(documentType);

String name = null;
if (AttachmentModel.TYPE_SPECIAL.equals(attachment.getAttachmentType())) {
name = documentType.getName() + " " + getDateAsString();
} else {
name = "Attachment " + getDateAsString();
}
document.setName(name);
}


This is getting in better shape. Now we have separate logic for getting the DocumentType, setting the DocumentType, getting the name, and setting the name. Let’s extract some methods and see what happens.

    public void updateDocument(Attachment attachment){
Document document = new Document();
DocumentType documentType = getDocumentType(attachment);
document.setType(documentType);

String name = getName(attachment, documentType);
document.setName(name);
}

private DocumentType getDocumentType(Attachment attachment) {
DocumentType documentType = null;
if (AttachmentModel.TYPE_SPECIAL.equals(attachment.getAttachmentType())) {
documentType = repository.findByCode(DocumentType.class, DocumentType.CODE_SPECIAL);
} else {
documentType = repository.findByCode(DocumentType.class, DocumentType.CODE_OTHER)
}
return documentType;
}

private String getName(Attachment attachment, DocumentType documentType) {
String name = null;
if (AttachmentModel.TYPE_SPECIAL.equals(attachment.getAttachmentType())) {
name = documentType.getName() + " " + getDateAsString();
} else {
name = "Attachment " + getDateAsString();
}
return name;
}


Our original method looks a lot simpler now. But the methods we’ve extraced contain duplication! The condition itself, the calls to repository.findByCode, and the calls to getDateAsString(). So, let’s fix that.

    public void updateDocument(Attachment attachment){
Document document = new Document();

DocumentType documentType = getDocumentType(attachment);
document.setType(documentType);

String name = getName(attachment, documentType);
document.setName(name);
}

private DocumentType getDocumentType(Attachment attachment) {
String documentTypeCode = null;
if (isAttachmentTypeSpecial(attachment)) {
documentTypeCode = DocumentType.CODE_SPECIAL;
} else {
documentTypeCode = DocumentType.CODE_OTHER;
}
return repository.findByCode(DocumentType.class, documentTypeCode);
}

private String getName(Attachment attachment, DocumentType documentType) {
String name = null;
if (isAttachmentTypeSpecial(attachment)) {
name = documentType.getName();
} else {
name = "Attachment";
}
return name + " " + getDateAsString();
}

private boolean isAttachmentTypeSpecial(Attachment attachment) {
return AttachmentModel.TYPE_SPECIAL.equals(attachment.getAttachmentType());
}


This code still looks a bit odd. getDocumentType() determines the document type code, and then uses that to find the documentType. And getName() has a similar issue: it determines the prefix for the name, and then appends the date as String.

    public void updateDocument(Attachment attachment){
Document document = new Document();

DocumentType documentType = getDocumentType(attachment);
document.setType(documentType);

String name = getName(attachment, documentType);
document.setName(name);
}

private DocumentType getDocumentType(Attachment attachment) {
String documentTypeCode = getDocumentTypeCode(attachment);
return repository.findByCode(DocumentType.class, documentTypeCode);
}

private String getDocumentTypeCode(Attachment attachment) {
if (isAttachmentTypeSpecial(attachment)) {
return DocumentType.CODE_SPECIAL;
}
return DocumentType.CODE_OTHER;
}

private String getName(Attachment attachment, DocumentType documentType) {
String name = getNamePrefix(attachment, documentType);
return name + " " + getDateAsString();
}

private String getNamePrefix(Attachment attachment, DocumentType documentType) {
if (isAttachmentTypeSpecial(attachment)) {
return documentType.getName();
}
return "Attachment";
}

private boolean isAttachmentTypeSpecial(Attachment attachment) {
return AttachmentModel.TYPE_SPECIAL.equals(attachment.getAttachmentType());
}


At this point we have some variables and perhaps some methods that are not adding anything in terms of clarity. We should inline them and compact our code a little.

    public void updateDocument(Attachment attachment){
Document document = new Document();

DocumentType documentType = getDocumentType(attachment);
document.setType(documentType);

document.setName(getName(attachment, documentType));
}

private DocumentType getDocumentType(Attachment attachment) {
return repository.findByCode(DocumentType.class, getDocumentTypeCode(attachment));
}

private String getDocumentTypeCode(Attachment attachment) {
if (isAttachmentTypeSpecial(attachment)) {
return DocumentType.CODE_SPECIAL;
}
return DocumentType.CODE_OTHER;
}

private String getName(Attachment attachment, DocumentType documentType) {
return getNamePrefix(attachment, documentType) + " " + getDateAsString();
}

private String getNamePrefix(Attachment attachment, DocumentType documentType) {
if (isAttachmentTypeSpecial(attachment)) {
return documentType.getName();
}
return "Attachment";
}

private boolean isAttachmentTypeSpecial(Attachment attachment) {
return AttachmentModel.TYPE_SPECIAL.equals(attachment.getAttachmentType());
}


This refactoring introduced a couple of new methods. Each method call takes a little extra time, and reduces performance a bit. But there’s a catch: with modern processors, cache-misses are the biggest performance killers. Keeping the data as local as possible will reduce cache-misses and increase performance.
In practice, however, I doubt that you’ll even notice the performance difference.

As for clarity, the original code expanded from 11 lines to 34 lines, a 3-fold increase. However, the original method decreased a bit. And because we’ve added a couple of layers of abstraction, the method now communicates only what it does. The details of how are delegated to other methods.