Database centric applications with Spring Boot and jOOQ

Abstract

As the german conference DOAG K+A is approaching very fast, I have to finalize my talk. As I prepared my demo already several months ago (on the one hand good, it’s done, on the other hand bad, I have to rehearse it), I might as well write about it.

This is gonna be a serious of posts that will provide one solution on how to do advanced reporting using jOOQ and basically mapping queries on HTTP endpoints with Spring Boot. We also gonna add a nice frontend to the mix based on Oracle JET.

I used NetBeans throughout the demo. It’s a highly versatile IDE that not only helped me a lot creating the buildfile for maven, but also supports me in managing my Oracle Datebase inside a Docker container.

There will be two “bonus” topics: Creating an Oracle Database inside a Docker container and using the Oracle Maven repositories for an “original” copy of the Oracle JDBC driver.

Be aware that some things maybe feels very simple to you if you are an experienced Spring Boot developer, but remember that this demo is developed for an audience that probably has little knowledge of Spring Boot or even Java.

As I’m gonna add posts to this series, I’ll push the commits to this repository: michael-simons/DOAG2016, planing to have it fully populated by the end of November.

Content

  1. Part 1: Database centric applications with Spring Boot and jOOQ (this post)
  2. Part 2: Create a Oracle Database Docker container for your Spring Boot + jOOQ application
  3. Part 3: Take control of your development databases evolution
  4. Part 4: An HTTP api for analytic queries
  5. Part 5: Oracle JET: JavaScript components for mere mortals?

Read the complete article »

| Comments (7) »

28-Oct-16


NetBeans Dream Team and more

The last month was quite a ride. Sometimes I think my life has never been better. So many nice and great people in my life, its hard to believe and I am really grateful.

First of all, thanks to my company, ENERKO Informatik for giving me the opportunities to do this stuff. I really need a place on that site to write more stuff some time soon.

NetBeans Dream Team

dream team Geertjan approached me some weeks ago in the name of the NetBeans Dream Team if I want to be a part of it. What a question! Its an honor to be part of such a great open source movement.

This was the announcement last Friday: Seven New NetBeans Dream Team Members. Look at the other 6 people: Attila Kelemen who created the Gradle support and Bruno Flávio, engaged in Groovy as well as in Grails (which is by the way, also Spring Based… I should really have a look at v3 some time).

JPA modeler by Gaurav Gupta surely isn’t only useful for Java EE but also if you use JPA / Hibernate stand alone.

We also have Emmanuel Hugonnet and Leonardo Zanivan on board who actively engage in community, organize NetBean events and more.

You even can get a NetBeans certification, just follow Ryan Cupraks guide.

Hibernate community blog

Vlad Mihalcea, author of High-Performance Java Persistence started a series of interviews on In relation to, the Hibernate community blog.

The first interview was with Petar Tahchiev who I met at Spring I/O earlier this year. Petar is a data geek and founder of the Nemesis platform.

Yesterday, Vlad published my interview, have a look: Meet Michael Simons.

Publications

I published my article about “basics” in German and English on JAXEnter, have a look:

JUG Alert: Über JUG Treffen für Anfänger und die JUG Kaiserslautern im Porträt

JUGs – Beginner or rock-star meetup?

Having an open environment for people to meet and discuss is in my opinion as much as important as having a free and open source IDE. Thanks Dominik for the opportunity to publish this!

Foto for the article: “Dream Team” by Thomas Hawk.

| Comments (1) »

22-Oct-16



Spring Boot: Referencing @MockBeans by name

This post has been featured on This Week in Spring – October 18, 2016.

We do a lot of server side rendering at my company and we ran into a strange “problem” today testing our views. Thanks to Pivotals own Andy Wilkinson we could resolve our issue easily.

A technical problem

The testing slices in Spring Boot 1.4+ are really neat. Imagine a simple controller like this:

package ac.simons.thymeleafmockbean;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
 
@Controller
public class WebController {
 
    @GetMapping(value = "/greeting")
    public String greeting() {
        return "greeting";
    }
}

that returns the name of a Thymeleaf view that looks like this:

<!DOCTYPE html>
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    </head>
    <body>
        <div th:text="${@helloService.sayHello()}">placeholder</div>
    </body>
</html>

Notice the usage of a service called “helloService” inside the div!

The service is super simple, too:

package ac.simons.thymeleafmockbean;
 
import org.springframework.stereotype.Service;
 
@Service
public class HelloService {
 
    public String sayHello() {
        return "Hallo, Welt";
    }
}

The service is little surprising annotated with @Service, making it a specialized component who’s bean instance can either referred to by type or by name. The name is – in the case of using the annotation – “helloService”, for reference see AnnotationBeanNameGenerator. I really didn’t spent much time thinking about naming any more the last years, it just used to work and I can use the service in my view .

Using Spring Boots test slices @WebMvcTest and @MockBean it can be tested like this:

package ac.simons.thymeleafmockbean;
 
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
 
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.hasXPath;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
 
@RunWith(SpringRunner.class)
@WebMvcTest
public class WebControllerTest {
 
    @Autowired
    private MockMvc mvc;
 
    @MockBean(name = "helloService")
    private HelloService helloService;
 
    @Before
    public void prepareMock() {
        when(helloService.sayHello()).thenReturn("Hello from Mock!");
    }
 
    @Test
    public void greetingShouldWork() throws Exception {
        this.mvc
                .perform(get("/greeting"))
                .andExpect(status().isOk())
                .andExpect(view().name("greeting"))                
                .andExpect(content().node(hasXPath("/html/body/div", equalTo("Hello from Mock!"))));
    }
}

Important thing is the usage of @MockBean(name = "helloService") with a name! @MockBean mocks beans, here the “HelloService”. There is no instance of that service as the service is not part of the web slice. The annotation name generator doesn’t kick in and the mocking bean mechanism generates its own name which is “ac.simons.thymeleafmockbean.HelloService#0”. If you plan to use mocked beans by name and you don’t replace existing beans make sure you specify the name of the bean as you are expecting it in your application code!

In our use case, we ended up with a stack trace that read like this:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "@helloService.sayHello()" (greeting:9)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:677)

We actually use a service within Thymeleafs Spring Security integration inside a sec:auth attribute. If you google that stack trace you’ll end up with some solutions leading you into the wrong direction, mainly settings regarding your security configuration. For me that was a really nice example on teaching how important it is to strip away pretty much everything to come to the core of the problem which in this case was, that one bean was there but reachable by an expected name.

An architectural problem

Update: The reader may have noticed that post covers two problems. A technical problem, which is the fact that mocked beans often have a different name opposed to normal instantiated beans. This problem can be solved as the post describes, by naming them correctly.

The other problem has been mentioned by Oliver Gierke and is of architectural kind and specific to our problem we had this morning. We obviously reaching back from the view layer into a service layer. We have reasons for doing so in our use case, but as often, technical debt comes back looking for you and if it is only for finding problems like these. Oliver was so kind suggestion a solution that doesn’t involve interceptors for controllers or adding the information we need to every model in every request mapped. He suggested a view model, wrapping the service call. I adapted his gist to the example above which then looks like this:

package ac.simons.thymeleafmockbean;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
 
@Controller
public class WebController {
 
    public static class ViewModel {
 
        private final HelloService service;
 
        public ViewModel(HelloService service) {
            this.service = service;
        }
 
        public String getGreeting() {
            return service.sayHello();
        }
    }
 
    private final HelloService helloService;
 
    public WebController(HelloService helloService) {
        this.helloService = helloService;
    }
 
    // Available in all views rendered by that controller
    @ModelAttribute
    public ViewModel viewModel() {
        return new ViewModel(this.helloService);
    }
 
    @GetMapping(value = "/greeting")
    public String usingHelloService() {
        return "greeting";
    }
}

You see that now the controller depends on the service, as it should. It uses the @ModelAttribute annotation to provide an instance of the custom view model class, which wraps the service call. By declaring it as a model attribute, it’s available to every view rendered by every method of the controller declaring this.

Nice added bonus: No obvious method call in the view anymore, spot the difference:

<!DOCTYPE html>
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    </head>
    <body>
        <div th:text="${viewModel.greeting}">placeholder</div>
    </body>
</html>

And regarding the test: I can now safely remove the name of the mocked been again, as the dependency in the controller is resolved by type.

| Comments (1) »

13-Oct-16