10 Apr 2013
Sadly the support for i18n for Entities in JPA is actually very poor to non-existent. There's just basically no out of the box solution provided by Hibernate & Co, although i18n is a feature that could be considered mandatory for a powerful ORM Framework. If you take a look at PHP for example Doctrine supports i18n very well. So besides some really unpopular i18n extensions on forums/github you are basically on your own.
So how do you do it?
There isn't really a general solution to achieve i18n. There are many different ways and you have to choose which is actually best for you. If you do have a relatively small amount of data and ordering by translations is not necessary you can store "keys" in your tables that are being translated by Spring i18n for example. Spring i18n could store the translations in separate property files. Since you wont have to worry about performance, this is a very easy way to achieve i18n.
But lets say you have lots of data, and you need to order it on the database side. With such requirements you are better off storing translations inside your database tables. While there are guides, and also an opensource framework on the internet that implement i18n with one centralized translation-table that holds all translations i highly recommend not to follow that idea. The problem with this solution is, that you will have to add one more join for every field that has to be translated, whereas multiple joins for a single table with lots of data can easily become a performanceissue.
Its better to follow the approach to create a separate translation-table for every entity. This means that you would have one entity containing simple data, and another one containing only the fields that require translation. Like so:
This schema is pretty normalized and you only have a single join on fetching an entity, while you can still order appropriate.
Your entities would look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @Entity public class Book {
@Id private int isbn;
private String author;
private Date releaseDate;
@OneToMany @JoinColumn(name = "isbn") private List<BookTranslation> translations;
// constructor, getters and setters -...
}
|
and that
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @Entity public class BookTranslation implements Serializable {
@Id private int isbn;
@Id private String locale;
private String title;
private String description;
// constructor, getters and setters -...
}
|
You could then fetch a book with its translations with:
select b from Book b join fetch b.translations bt where bt.locale = 'de';
If you cannot accept your ServiceLayer to deliver two entities for every Book only because of translations, i suggest you to implement some DTO like this BookTO which holds all values.
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class BookTO {
private int isbn;
private String author;
private Date releaseDate;
private String title;
private String description;
}
|
You'd just need to map the values of Book and BookTranslation to BookTO within your ServiceLayer and also return BookTO instead of Book in your ServiceLayer.
This solution might not always be the most appropriate, but it definitely comes in handy sometimes.
24 Mar 2013
Drawing Class Diagrams preemptive is sometimes nice to optimize your thought of design. But it will still most likely change in the development phase. Since your Class Diagram is part of your documentation it should be up to date all the time. There is no point in having a Class Diagram if the code does not fit it. You could keep adapting the changes to the Class Diagram by hand, but that can get very time-consuming and exhausting. You should rather automate that process, and there are several ways to achieve exactly that. You could for example search for a UML Class Diagram Tool supporting roundtrip engineering. There are some commercial, and even some free ones available. Not all of them work very well and it can be a frustrating task to figure out which way to go. You would probably try out some and throw them away because they are just not what you expected.
Thats why i want to show you a different approach: Letting a Javadoc Doclet draw the Class Diagrams in build phase and embed them into your javadoc automatically. UMLGraph is such a doclet. It analyzes your code, draws Class Diagrams automatically and embed them into your javadoc.
Since maven can run javadoc at build phase it's perfect. You just have to configurate the maven-javadoc-plugin to use UMLGraph.
Configurate Maven to use UMLGraph
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <reporting> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>2.9</version> <configuration> <doclet>org.umlgraph.doclet.UmlGraphDoc</doclet> <docletArtifact> <groupId>org.umlgraph</groupId> <artifactId>umlgraph</artifactId> <version>5.6</version> </docletArtifact> <additionalparam>-views -all</additionalparam> <useStandardDocletOptions>true</useStandardDocletOptions> </configuration> </plugin> </plugins> </reporting>
|
Beware that the javadoc doclet api has changed from jdk 1.6 to jdk 1.7 and most of the online tutorials are outdated because of that. UMLGraph adapted to jdk 1.7 since version 5.5.
If we run mvn site right now, we will just get that error:
java.io.IOException: Cannot run program "dot": java.io.IOException: error=2, No such file or directory
This means that the program dot was not found which is a part of the graphviz library.
Install Graphviz
For UMLGraph to run you need graphviz installed. Go to the Download Page, and choose your package. On linux you could even sudo aptget install graphviz. Beware that you might have to reboot or relogin to use graphviz, because the Systems Path is extended during installation.
First Result
Run mvn site, and open target/site/apidocs/index.html afterwards.
As you can see its drawing beautiful and accurate UML Class Diagrams.
Custom Configuration
If you dont want attributes/methods or other extras you are totally free to configurate those graphs. See Class Diagram Options. Just add them to the
<additionalparam>-views -all</additionalparam>
tag in pom.xml
09 Mar 2013
⚠️ The following post confuses the Decorator Pattern with the Proxy Pattern.
While the structures of those Patterns are the same, they aim for different goals.
The Decorator adds functionality to the underlying object, whereas a Proxy controls access to it.
Therefor the usage of a cache is rather a Proxy than a Decorator.
The Decorator Pattern
Class Diagram:
Decorator Pattern is one of the most powerful Design Patterns, and its important to understand why. It allows you to add functionality to a Class without changing it. You use delegation instead of inheritance by just wrapping the existing Class in a "Suite" of your choice while the Interface stays the same. This way, you can even wrap a Class into multiple layers of Decorators where every Layer has its own and different purpose, and the Original Class even stays the same. Other than that the Layers are completely interchangeable and removable, because they all have the same Interface.
You can use your naked Object in the same manner as a decorated one with multiple Layers, and the rest of the Application wont even notice. Other components dont need to know whether a Class is decorated or not, because the only thing they care about is the Interface. The following Graphic should clear things up:
Just follow the Steps:
In the first example there is no Decorator. So SomeClass directly speaks to BookService
In the second example there is a single Decorator. Therefore the following steps apply
- SomeClass calls SomeDecoratorA.
- SomeDecoratorA delegates the call to the real BookService. The Decorator could even manipulate the call in this step.
- BookService returns a result. SomeDecoratorA now holds the result, and may manipulate it.
- Finally, SomeDecoratorA hands the result over to the original caller SomeClass.
In the third example, there are even 2 Nested Decorators. Since every Decorator speaks the Interface of the BookService Class you can wrap an infinite amount of Decorators upon.
Usage Examples
Most examples in Books and online Guides describe the Decorator Pattern used by some Graphic related stuff. You would have a normal line, and a line decorated with a shadow. Another example would be a Window in a GUI where you vary Decorators that add different kinds of styles (e.g. different Colors).
But its important to understand, that Decorators are not intended to just make Styling more dynamic. It is just one way to use them. Instead, there are many more great use cases for Decorators and i will show you an example applying cache functionality.
Applying Cache with Decorator Pattern
Class Diagram:
As you can see i am adding a BookServiceCacheDecorator that holds a Cache Component which temporarily stores a List of Books. The BookServiceCacheDecorator in the first place asks the Cache if there is a result available. If thats true, the decorator will use the cached result. Otherwise it will fetch the Result of the BookService itself, and store the Result in the Cache for later use.
I start with the BookService Interface,
1 2 3 | public interface BookService { public List<Book> findAll(); }
|
and its prime implementation.
1 2 3 4 5 6 7 8 9 10 11 12 | public class BookServiceImpl implements BookService {
@Override public List<Book> findAll() { System.out.println("load new data"); List<Book> books = new ArrayList<Book>(); books.add(new Book("BookA")); books.add(new Book("BookB")); books.add(new Book("BookC")); return books; } }
|
Here is the Code of the Cache Class. In this example it's caching forever, but thats alright.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public class Cache {
private List<Book> storage;
public void save(List<Book> books){ this.storage = books; }
public boolean hasResult(){ if(storage != null){ return true; }
return false; }
public List<Book> load(){ System.out.println("load from cache"); return storage; } }
|
Now lets continue with the Decorator Base Class. It has a preemtive Constructor to hand over the decorated Object.
1 2 3 4 5 6 7 8 | abstract public class BookServiceDecorator implements BookService{
protected BookService decorated;
public BookServiceDecorator(BookService decorated){ this.decorated = decorated; } }
|
And finally the CacheDecorator. It Checks the Cache before calling BookServiceImpl.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class BookServiceCacheDecorator extends BookServiceDecorator {
private Cache cache;
public BookServiceCacheDecorator(BookService decorated) { super(decorated); }
public BookServiceCacheDecorator(BookService decorated, Cache cache) { super(decorated); this.cache = cache; }
@Override public List<Book> findAll() { if(cache.hasResult()){ return cache.load(); } List<Book> books = decorated.findAll(); cache.save(books); return books; } }
|
Now two different use cases. One without Decorator, and one with the Cache Decorator:
1 2 3 4 5 6 7 8 9 | BookService bookService = new BookServiceImpl(); bookService.findAll(); // prints: load new data bookService.findAll(); // prints: load new data bookService.findAll(); // prints: load new data
BookService cachedBookService = new BookServiceCacheDecorator(new BookServiceImpl(), new Cache()); cachedBookService.findAll(); // prints: load new data cachedBookService.findAll(); // prints: load from cache cachedBookService.findAll(); // prints: load from cache
|
Thats basically it. Just read the Code carefully. The final use cases should make clear how the Decorator applies functionality. Decorator pattern really helps you create a very modular Code in many circumstances. You should not be afraid of the additional Classes the Pattern depends on, since they are really not a big deal. The modularity gained easily outweighs them.
06 Mar 2013
Today i want to show you another way to use the Builder Pattern. From what i've seen there are tons of examples of the Builder Pattern online. But they do all have one thing in common: They are used to create an Instance of an Object and "replace" its constructor. This way you can create a complex Object in a very clean and readable fashion using a Fluent Interface.
Other than that, there is also a slightly different way you can benefit of the Builder Pattern. Think of a Method with like 10 Parameters. Thats not quite nice, and should not ever happen. Robert C. Martin recommends a maximum amount of 3 Parameters in his book: Clean Code. You should rather use some kind of a Config Object holding those 10 parameters, to clean it up. But lets say, you have a BookService Class with a find(..) method, that allows to search by 10 different parameters, and every single one of them is optional. You could use the Builder Pattern with some kind of Query Object to solve the problem.
As we should always program against Interfaces to keep things modular, ill start with the Interface:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public interface BookService {
public Book create(Book book);
public void delete(String isbn);
public Query query();
public interface Query {
public Query isName(String name);
public Query hasAuthor(String author);
public Query isCheaperThan(Float price);
public Query isIsbn(String isbn);
public Query hasMorePagesThan(Long pages);
public Query isAvailable();
public List<Book> find();
} }
|
So the Interface looks pretty neat. It allows you to write something like:
bookService.query().hasAuthor("Bob").isCheaperThan(20.9).isAvailable().find();
While the Query could be considered as an implementation of the Query Object pattern it is not tied to any Database related stuff, which is very important. You dont want to be tied to Criteria Queries or SQL in this Layer. It should be independent of any implementation (e.g. Database or Filesystem).
To clear things up, i want to show you an implementation example using Spring-Data. I am a big fan of Spring-Data, since it allows you to create full featured DAOs with little to no Programming effort for many different Persistence Providers. If you havent used it yet, you should definitely give it a try.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | public class BookServiceImpl implements BookService {
@Autowired private BookRepository bookRepository;
// ...
@Override public Query query() { return new QueryImpl(this.bookRepository); }
public class QueryImpl implements Query{
private BookRepository bookRepository; private Specifications<Book> filters = null;
public QueryImpl(BookRepository bookRepository) { this.bookRepository = bookRepository; }
private void addFilter(Specification<FlowMessage> filter) { filters = (filters == null) ? where(filter) : filters.and(filter); }
public Query isName(String name) { if (name == null) return this; addFilter(BookSpecifications.isName(name)); return this; }
public Query hasAuthor(String author) { if (author == null) return this; addFilter(BookSpecifications.hasAuthor(author)); return this; }
// other criterias ...
public List<Book> find() { return this.bookRepository.findAll(filters); } } }
|
As you can see i am just joining filter Criterias together, and thats it. The implementation is really simple but also expandable. These filter Criterias are supported by my BookRepository (=DAO). I just have to define them in a helper class first. Check out this and that for a deeper understanding how to combine spring-data with criteria queries.