Thoughts about architecture

Most people slice their cakes like this:


14962767_53ec6ef41e_o

Image by Elaine Ashton

and in most cases not horizontally but still many developers, like i did in the past, slice their packages that way.

Really, just slapping classes into packages named “Model”, “View” and “Controller” doesn’t implement that pattern. @jensschauder has written much more eloquent than i about this here (Jens does also a pretty good talk about that topic and has some really nice drawings in it as well, if you should have the opportunity, check it out) and @olivergierke has taken it further here. Take your time, read both posts. Its worth it. Rethinking my own organization of code the last years helped me writing better code. Looking at a recent project that isn’t divided into libraries yet, i could easily rip those modules apart and deploy them separately.

So, why am i writing this, when so much has already been written by smarter people than i?

The last weeks i’ve been working on a new frontend for an old but really not outdated project that handles a lot of time series, prices and tenders, all in a multi tenant fashion. The database model is really complex but not complicated and is there to stay. The current codebase does many things right in the database (stored PL/SQL procedures) and that won’t change much.

In the course of the last 5 to 8 years I’ve learned so much about Hibernate and got to love the stuff that the Spring Data team is doing on Spring Data JPA and i can say that i really come far, using HQL or now JPQL and also the criteria query api (together with the static meta model) that nobody else seem to like. For example, using semi-joins to determine if stuff is active or not:

public static Specification<Projekt> isAktiv() {
	return (root, query, b) -> {	    
	    final Subquery<String> outerSubquery = query.subquery(String.class);
	    final Root<Projektversion> outerSubqueryRoot = outerSubquery.from(Projektversion.class);
	    final Join<Projektversion, LieferangebotEntity> joinLieferangebot = outerSubqueryRoot.join(lieferangebot);
 
	    final Subquery<String> innerSubquery = query.subquery(String.class);
	    final Root<Projektversion> innerSubqueryRoot = innerSubquery.from(Projektversion.class);
 
	    return b.exists(
		outerSubquery
		    .select(b.literal(""))
		    .where(b.and(
			    b.equal(outerSubqueryRoot.get(projekt), root),
			    b.isNotNull(joinLieferangebot.get(vertragsabschlussdatum))),
			    b.not(b.exists(
				    innerSubquery
					.select(b.literal(""))
					.where(b.and(
						b.equal(innerSubqueryRoot.get(projekt), outerSubqueryRoot.get(projekt)),
						b.greaterThan(innerSubqueryRoot.get(versionsdatum), outerSubqueryRoot.get(versionsdatum))
					))
			    ))
		    )			  		    
	    );	    
	};
    }

Using this with Spring Data Repositories and specification makes JPA actually fun. But with jOOQ i can write it down like i would in SQL:

private static final Condition IS_ACTIVE_CONDITION = 
	exists(
	    select(val(""))
	    .from(outer)
		.join(LIEFERANGEBOTE)
		    .on(LIEFERANGEBOTE.LIEFERANGEBOTS_ID.eq(outer.LIEFERANGEBOTS_ID))
	    .where(
		    outer.PROJEKT_ID.eq(p.ID)
		.and(LIEFERANGEBOTE.ABSCHLUSSDATUM.isNotNull())
		.and(not(exists(
		    select(val(""))
		    .from(inner)
		    .where(
			    inner.PROJEKT_ID.eq(outer.PROJEKT_ID)
			.and(inner.VERSIONSDATUM.gt(outer.VERSIONSDATUM))
		    )
		)))
	    )
	);

Lukas promotes jOOQ for that kind of usage very well. But i say, it’s the simple things. I cannot only write elaborate queries, I can also write down what i want to select. jOOQ doesn’t try to be a mapping from a relational world into the slices of my application, it just maps tables and their columns 1:1. It’s up to me what i select. I could achieve this with native or JPQL queries as shown here, but than what’s the point of mapping all those entities anyway (to be honest, i’ve already done this on several occasions)? Another solution would be the new entity graphs but than i end up with either half-empty entities or getting nice surprises from lazy loaded associations.

What every JPA solution has in common, at least to me, is the fact that one ends up with one big package containing pretty much every entity there is. To create complete mappings from the relational into the object oriented world those entities depend on each other and i cannot slice it the way the application works.

You might say that this persistence package is analogue to the generated jOOQ tables and records, but i think they are quite different. The generated tables and records are mere means of accessing the same thing in the database, not more but also not less. Building a full fledged mapping is a lot more and implicates a lot more.

Not being forced to put effort into defining a logical and accurate class hierarchy to work with JPA but instead modeling and filling DTOs and business objects right from the database in a way that fits architectural slices of an application gives back a lot of freedom for writing cleaner and easier to understand applications.

| Comments (11) »

23-Sep-15


jOOQ and Spring: Manage your RecordMappers as @Components

Lately i’ve been evaluating jOOQ as a core database tool for ENERKO Informatik. Though i’ve got quite some experience (and good experience!) with Hibernate and Spring Data JPA, we have some projects around that are quite old but not outdated. They are in need for an UI/UX and some architectural make over, but the data model is mostly not but has never been designed with an ORM in mind. All that will be the topic of a later post, as I’m not done with my evaluation.

We will be using jOOQ as part of a Spring / Spring Boot project, so @petrikainulaines post Using jOOQ With Spring is of quite some use and i intend to add some info as well.

jOOQ provides several basic but quite functional ways to map records into POJOs as described here, but that’s pretty much it. jOOQs primary goal isn’t defining a new ORM, but the best way to write SQL in Java. Playing around with my data model, i really start liking it. Instead of defining multiple entity graphs, i can select the columns, children and everything i need the way it is meant to be and build my DTOs the way i want it. Enter RecordMappers for creating complex POJOS from records. If you don’t want to roll your own RecordMappers, there are quite a few out there .

Here is a super simple RecordMapper, that does pretty much nothing apart from setting an attribute:

import de.enerko.ensupply.db.tables.records.AnwenderRecord;
import org.jooq.RecordMapper;
import org.springframework.stereotype.Component;
 
@Component
public class AnwenderRecordMapper implements RecordMapper<AnwenderRecord, Anwender> {
    @Override
    public Anwender map(AnwenderRecord record) {
	final Anwender rv = new Anwender();
	rv.setName(record.getName());
	return rv;
    }
}

Notice the @Component annotation, which makes the bean a Spring Component. Alternatively it can be configured through plain Java or even XML configuration.

Enter my RecordMapperProviderImpl

What does it do? It retrieves a map of all beans implementing the RecordMapper interface and searches for the bean whose E type parameter (which isn’t erased when inheriting a typed interface like shown above) matches the target type.

I even wanted to compare the RecordType, but that type parameter is erased at runtime and so i’m basically comparing org.jooq.Record with itself. An API method to retrieve this would be nice, hint,hint, Lukas ;).

You may notice the @Cacheable annotation: If configured correctly (in Spring boot, just throw @EnableCaching at your Application class), Spring will cache the outcome of the annotated method and so preventing several expensive type lookups (which will be of some importance when mapping more than a handful of records).

Thanks to @thomasdarimont i got rid of the ApplicationContext dependency and @olivergierke was so kind about pointing me to ResolvableType so that i only depend on Spring and jOOQ.

The RecordMapperProviderImpl is registered with the jOOQ configuration as follows:

@Bean
public org.jooq.Configuration jooqConfig(
	    ConnectionProvider connectionProvider,
	    TransactionProvider transactionProvider, 
	    ExecuteListenerProvider executeListenerProvider,
	    RecordMapperProvider recordMapperProvider,
	    @Value("${jooq.renderFormatted:false}")
	    boolean renderFormatted
) {
	final DefaultConfiguration hlp = new DefaultConfiguration();
	return hlp
		.derive(hlp.settings()
			.withRenderFormatted(renderFormatted)
		)
		.derive(connectionProvider)
		.derive(transactionProvider)
		.derive(executeListenerProvider)	
		.derive(recordMapperProvider)
		.derive(SQLDialect.ORACLE);
}

(Bye the way, this will be done automatically in upcoming Spring Boot 1.3 given RecordMapperProviderImpl is an @Component like in the example).

If everything works well, expect some jOOQ and SQL content coming soon.

Update:

See my tweet, composing Record Mappers is really simple using that technique:

import de.enerko.ensupply.db.tables.records.AnwenderRecord;
import org.jooq.RecordMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class SpecialRecordMapper implements RecordMapper<Record, SomeObject> {
    private final AnwenderRecordMapper anwenderRecordMapper;	
 
    @Autowired
    public SpecialRecordMapper(final AnwenderRecordMapper anwenderRecordMapper) {
        this.anwenderRecordMapper = anwenderRecordMapper;
    }
 
    @Override
    public Anwender map(Record record) {
	SomeObject s = new SomeObject();
	// Do other mapping stuff
	s.setAnwender(this.anwenderRecordMapper.map(record.into(AnwenderRecord.class));
	return s;
    }
}

| Comments (2) »

09-Sep-15


Learning about the smarter and faster way to code at EuregJUG


euregjug-small

Geertjan Wielenga, who was inherited by Oracle from Sun and is now working as a product manager inside the NetBeans team, gave us the pleasure visiting the Euregio for the second talk at the EuregJUG that went by the title “Free Open Source Tools for Maven, HTML5, IoT and Java EE”.

We had 28 registered participants but i actually forgot to count our visitors, I was to concentrated on my spoken English introducing Geertjan. Edit: Actual number of visitors was 23. Thanks Stéphane.
So, what did we hear?

A brief introduction from where NetBeans came and how deeply it is embedded into the Java ecosystem and that is still the platform which is promoted by Oracle for Java development.


DSC03774

Many big private and public corporates are using NetBeans, often not in public, but nevertheless for developing mission critical applications. Among the users is certainly James Gosling, sometimes using NetBeans more than email.

I’d absolutely second the fact, that NetBeans is great for education: For teachers as well for technical leads who want to educate co-workers. Most of the time, its hassle free and it doesn’t get into your way with conflicting plugins and stuff. I’ve written about it some time ago in my NetBeans testimonial.

After that Geertjan showed some demos, especially in the area of Maven and embedded tooling, like inspections, refactoring and code quality.

Many of the stuff I’m using already but what i only saw at my wifes work was the incredible useful integration of NetBeans and Chrome: Through the use of a little plugin you can edit the DOM and shadow DOM of your next great HTML5 application inside NetBeans and need not to use the embedded Chrome tools. Awesome:

DSC03775

We also saw how great NetBeans is as a *drumroll* JavaScript editor. But, the word “editor” doesn’t do justice. The NetBeans team put really great effort into supporting AngularJS, Knockout and others and what i saw in the NetBeans 8.1 Beta: It looks and feels just right. So if you’re looking for an IDE doing JavaScript development, give NetBeans a try. I myself pull my imaginary hat for the effort put into that as I’m trying to build something based on Wro4J myself to only handle JavaScript, SASS and stuff in a sane way for Spring Boot applications.

I really like the presentation a lot and though Geertjan is promoting NetBeans for quite some time, you really get his enthusiasm for the IDE and the platform. As an added bonus, we were the first to see the cover of Geertjans upcoming “authoritative tutorial” Beginning NetBeans IDE including some nice illustrations of well known developers. The book will be available at JavaOne this year. The slides are available at Prezi.

I’d like to highlight one later remark: The fact that there are at least 3 great IDEs for Java is vital for the language. If there’s only one single IDE which may not support the latest and greatest features for language release, than that release is pretty much dead. Having more than one great IDE is a luxury and great value for the platform.

We actually had two talks this evening. Simon Heinen from our host bitstars presented their platform Holobuilder. Impressive UI! The talk about how Bitstars manages to use the same validations for back- and frontend was interesting as well and clearly shows that those kinda problems are still relevant today. Also: Thanks for the opportunity to try out Google Cardboard.


DSC03776

I’m very happy to announce Stéphane Nicoll as our next speaker. On October 8th he will be talking about “Building cloud native apps with Spring Boot”. Stéphane works on Spring Framework and Spring Boot from Belgium for Pivotal. Given my experiences the last 1,5 years with Spring Boot, i only can recommend not to miss this great opportunity to hear directly about the new features of Spring Boot 1.3 while they’re fresh at EuregJUG.

| Comments (0) »

26-Aug-15


New theme

I’ve been using the old “PlainTextBlog” theme since 2006, when i started writing this blog, time for a change, i guess.

I was very happy with the free template for michael-simons.eu by html5up.net, so i gave Pixelarity i try and bought access for some months.

This theme here is now based on Archetype and I’m really happy. Works great on smaller and larger desktop screens as well as on mobile devices (if i fix the images i recently used in some posts…).

Hope you like the new look as much as i do.

| Comments (0) »

20-Aug-15


EuregJUG: Free Open Source Tools for Maven, HTML5, IoT and Java EE

Geertjan Wielenga (read his bio here) from Oracle comes to Aachen on August 25th for giving a presentation about NetBeans titled “Free Open Source Tools for Maven, HTML5, IoT and Java EE” at the EuregJUG.

After writing my own NetBeans testimonial some days ago, i’m very happy to meet him in person once again.

The talk starts at 18:00 sharp, at bitstars GmbH headquarter, Hanbrucher Straße 40, 52064 Aachen. Admission is free, but you’re asked to register here. There’ll be a little raffle and also drinks.

Hope to see you!

talk-poster-2015-08-28

| Comments (0) »

03-Aug-15