Sunday, 27 July 2014

From Hibernate to EclipseLink

I've decided to try porting my little application from Hibernate to EclipseLink.

I am not currently using a lot of Hibernate specific functionality. The ones that occur to me at the moment is:
  • Hibernate Filters
  • Hibernate DELETE_ORPHAN

Filters

Filters are, as far as I know, currently not a part of the JPA Specification. Every ORM has its own implementation of dealing with it.

Below are the two different (very different!) implementations for Hibernate and EclipseLink. I find the Hibernate one to be more powerful.

Hibernate

Definition of the filter:
@FilterDef(name = "activePersons", defaultCondition="active = 1")
package mmud.database.entities;
Using the Filter on Entities:
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.Filters;

@Entity
@Filters({ @Filter(name = "activePersons") })
public class Person implements Serializable { ...
@Entity
public class Room implements Serializable {

   @OneToMany(cascade = CascadeType.ALL, mappedBy = "room")
   @Filter(name = "activePersons")
   private Set<Person> persons = new HashSet<>();
Enabling the Filter, upon starting a session:
// Hibernate specific
Session session = 
    ((org.hibernate.ejb.EntityManagerImpl)em.getDelegate()).getSession();// JPA1.0
// Session session = getEntityManager().unwrap(Session.class); // JPA2.0
session.enableFilter("activePersons");

EclipseLink

EclipseLink uses the AdditionalCriteria2 3 annotation on Entity level.
@Entity
@AdditionalCriteria("(:activePersonFilter <> 1 or this.active = 1)")
public class Person implements Serializable { ...
...
...
getEntityManager().setProperty("activePersonFilter", 1); // turns filter on

Unfortunately, I cannot not set it, as that will trigger the following:
org.eclipse.persistence.exceptions.QueryException.missingContextPropertyForPropertyParameterExpression(QueryException.java:260)
So I am obligated to turn the filter on or off at the boundary where the entityManager (or EntityManagerFactory) is first called.

And there is not a convenient way of turning a filter on or off. Right now, the turning on/off is part of the subquery.4

However, I do like the fact that my AdditionalCriteria suddenly works everywhere once I turn it on. I do not have to set specifics on the fields of an Entity. Of course, this does limit the flexibility, but in my case it is not an issue.

Deleting Orphans

Well, Hibernate was one of the first to implement the Delete-orphan functionality and it took a while for it to become meanstream in the JPA specification. But it's there now, and should be supported by all ORMs.

Hibernate

@OneToMany(cascade = CascadeType.ALL, mappedBy = "belongsto")
@Cascade({ org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
private Set<item> items;

JPA 2.0

@OneToMany(cascade = CascadeType.ALL, mappedBy = "belongsto", orphanRemoval = true)
private Set<item> items;

Sha1

Hibernate

Apparently JPA doesn't have an sha1 function, yet mysql does. Hibernate had no problems with it, so I looked for a solution from EclipseLink5.
@NamedQuery(name = "User.authorise", query = "select p from Person p WHERE p.name = :name and p.password = sha1(:password)")

JPA 2.1

It turns out JPA5 has a specific reserved word called "FUNCTION" to support this, that I quite like. It prevents me from having to write a specific MySQL Dialect.

Of course, it does tie me to the MySQL implementation, but you cannot have everything.
@NamedQuery(name = "User.authorise", query = "select p from Person p WHERE p.name = :name and p.password = FUNCTION('sha1', :password)")

Notes

I found EclipseLink to be very strict with the interpretation of JPQL.

Issue 1 - References

For example, it complains about:
SELECT max(id) FROM ItemDefinition i
Wanting something more along the lines of:
SELECT max(i.id) FROM ItemDefinition i

Issue 2 - Like statements

Then there's an issue with the following query statement:
SELECT s FROM SillyName s WHERE :name like s.name
That gave me the error message "You have attempted to set a value of type class java.lang.String for parameter name with expected type of class java.lang.Boolean". I had to do some voodoo magic to make it work:
SELECT s FROM SillyName s WHERE concat('',:name) like s.name
Yikes!

Issue 3 - Update statements

Furthermore, I got a warning when creating the following update statement:
UPDATE Item i SET i.container = :container WHERE i = :item and i.belongsto = :person
The warning was:
“Input parameters can only be used in the WHERE clause or HAVING clause of a query.”
Apparently JPQL doesn't allow named parameters (or parameters of any kind) outside a WHERE or HAVING clause.

This was only a warning and the thing does work, but I should heed it.

It is described in Chapter 10.2.5.4. JPQL Input Parameters of the JPQL Language Spec7

Netbeans

I especially liked the fact that in Netbeans, I can mouse over the NamedQueries in the Entities and it tells me in a popup what is wrong.

References

[1] The Java EE 7 Tutorial - Introduction to the Java Persistence API
http://docs.oracle.com/javaee/7/tutorial/doc/persistence-intro001.htm
[2] AdditionalCriteria
http://wiki.eclipse.org/EclipseLink/Development/AdditionalCriteria
[3] AdditionCriteria
https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Mapping/Additional_Criteria
[4] StackOverflow - Is there a way to disable additionalcriteria in EclipseLink?
http://stackoverflow.com/questions/15847792/is-there-a-way-to-disable-additionalcriteria-in-eclipselink
[5] StackOverflow - JPA How to persist column with sha1 encryption
http://stackoverflow.com/questions/7868939/jpa-how-to-persist-column-with-sha1-encryption
[6] EclipseLink UserGuide - Support for Native Database Functions
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/Support_for_Native_Database_Functions#FUNC
[7] Oracle - JPQL Language References
http://docs.oracle.com/cd/E17904_01/apirefs.1111/e13946/ejb3_langref.html

Tuesday, 22 July 2014

Venn Diagrams

At work I seem to be the authority on the presence (or absence) of a colleague of mine who is much requested within the company for his domain model knowledge. Let's call him Hans, for that is his name.

The reason I am an authority is because I always walk with him from the train station to work.

A fact is that we both have long hair.

Hence a colleague of mine assumed that Long hair is a requirement for people who work here and go by train.

Venn Diagrams

So we have the following sets:
  • people who go by train
  • people who have long hair
  • people who work at my company

Problems

As I pointed out, the people my colleague, Bart, knows who work at my company and travel by train, also happen to have long hair. But the people my colleague knows is just a subset of people at my company. So let's add the set "people who Bart knows". So we have the following sets:

  • people who go by train
  • people who have long hair
  • people who work at my company
  • people who Bart knows

Now, we run into a little problem with Venn diagrams. As always, Wikipedia[1] to the rescue.

It's not possible to show all possibilities using regular circles, when the sets increase to more than three. In our case, for four possibilities, we can use ellipses.

Euler Diagrams[2]

Venn Diagrams are a Subset of Euler Diagrams, because Euler Diagrams are a bit more flexible when it comes to showing only some instead of all possible intersections.

The relationship between Venn and Euler diagrams can be displayed as an Euler Diagram.

I'm going to stop now, before I break my brain on the recursion.

References

[1] Wikipedia - Venn Diagram
http://en.wikipedia.org/wiki/Venn_diagram
[2] Wikipedia - Euler Diagram
http://en.wikipedia.org/wiki/Euler_diagram

Saturday, 19 July 2014

Successfully completed Functional Programming Principles in Scala

I earned 97.7% with distinction.

Evaluation

One can tell that the subject matter was Academic, with a firm grounding in Mathematics, which appealed to me.

The assignments provided a lot of information on what is expected, so there are no surprises, but you do need to read carefully.

The one assigment that provided the most difficulty was assignment 6, regarding the discovery of Anagrams of a sentence.

I had to wrestle a bit with the Scala syntax. It's new for me.

I especially found foldLeft and foldRight counter-intuitive sometimes.

I learned a lot on the following topics, in no specific ordering.
Scala Programming Language
by the creator, Martin Odersky, himself.
Functional Programming
one of the main subjects of the course
Domain Specific Language
Scala provides several ways to program according to a domain model2, instead of a technical/software model
Mathematics - Set Theory
the code is very close to the mathematical theory. Purposefully crafted that way, of course. It means we can actually use mathematical operators (some of the time).
Behaviour Driven Development
you can write tests that read more naturally
Test Driven Development
assignments had to pass certain tests (that are unknown), so your own tests had better be complete/sufficient
Recursion
we used a lot of recursion, you do not see that in "normal" programming languages.
It was a huge amount of fun to do, both to learn a new Programming Language1 and to learn a new Programming Paradigm.

References

[1] Coursera - Functional Programming Principles in Scala, by Martin Odersky
https://class.coursera.org/progfun-004
[2] Wikipedia - Domain Model
http://en.wikipedia.org/wiki/Domain_model

Sunday, 13 July 2014

Migrating between JEE versions

I had an issue where I wanted to port my current JEE 6 (Web profile) application (YPPO) to JEE 7 (Full profile).

This concerns a Netbeans project (built using Ant)

I thought I'd just write down which files needed changing.
nbproject/project.properties
-j2ee.platform=1.6-web
+j2ee.platform=1.7
persistence.xml
-<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
+<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
beans.xml
-<beans xmlns="http://java.sun.com/xml/ns/javaee"
+<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">

+ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="annotated">
web.xml
-<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
+<web-app version="3.1" 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"></dd>

References

Github - changed from JEE 6 Web (Lite) to JEE 7 (Full).
https://github.com/maartenl/YourPersonalPhotographOrganiser/commit/82d0c00812ec626e21c7b48a6a5523fb0311218e
Github - changed from JEE 6 Web (Lite) to JEE 7 (Full) Part II.
https://github.com/maartenl/YourPersonalPhotographOrganiser/commit/a092896dc00805f640a1dd305e248c39aa3cf70b
Github - bean-discovery-mode required attribute in beans.xml
https://github.com/maartenl/YourPersonalPhotographOrganiser/commit/b979c896711e7ebf30f90534aaffe9ddbe855681

Monday, 7 July 2014

URI vs. URL vs. URN

What's a URI?


Uniform Resource Identifiers (URIs) are used to identify 'names' or 'resources'. They come in 2 varieties: URNs and URLs. In fact, a URI can be both an URN and an URL!

What's a URL?


Uniform Resource Locators (URLs) provide a way to locate a resource using a specific scheme, most often but not limited to HTTP. Just think of a URL as an address to a resource, and the scheme as a specification of how to get there.

What's a URN?


Uniform Resource Names are identifiers for resources. They are location independent and make use of the urn: scheme.

What's the syntax of a URI?


scheme:scheme-specific-part?query#fragment

Examples from the RFC:
ftp://ftp.is.co.za/rfc/rfc1808.txt
http://www.ietf.org/rfc/rfc2396.txt
ldap://[2001:db8::7]/c=GB?objectClass?one
news:comp.infosystems.www.servers.unix
tel:+1-816-555-1212
telnet://192.0.2.16:80/
urn:oasis:names:specification:docbook:dtd:xml:4.1.2

What's the syntax of a URL?


scheme://username:password@subdomain.domain.tld:port/path/file-name.suffix?query-string#hash

Examples:
http://www.google.com
http://foo:bar@w1.superman.com/very/long/path.html?p1=v1&p2=v2#more-details
https://secured.com:443
ftp://ftp.bogus.com/~some/path/to/a/file.txt

What's the syntax of a URN?


urn:namespame-identifier:namespace-specific-string

Examples from Wikipedia:
urn:isbn:0451450523
urn:ietf:rfc:2648
urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66

What's an XML Namespace?

<ui:composition
        contentType="text/html"
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:a4j="http://richfaces.org/a4j"
        xmlns:rich="http://richfaces.org/rich"
        xmlns:s="http://jboss.org/schema/seam/taglib"
        xmlns:git="http://www.gouwit.nl/jsf/corepresentation"
        xmlns:gbl="http://www.gouwit.nl/jsf/bl
        xmlns:g="http://java.sun.com/jsf/composite/components
        xmlns:p="http://primefaces.org/ui
        template="/layout/template_globals.xhtml"
>

An XML Namespace name is a uniform resource identifier (URI). However, the namespace specification does not require nor suggest that the namespace URI be used to retrieve information; it is simply treated by an XML parser as a string.

In general users should assume that the namespace URI is simply a name, not the address of a document on the Web.

Updated: 2014-09-18, added XML Namespace note.

References

Freeformatter.com
http://www.freeformatter.com/url-parser-query-string-splitter.html
Stackoverflow - What is the difference between a uri and a url
http://stackoverflow.com/questions/176264/whats-the-difference-between-a-uri-and-a-url
IETF - RFC3986
http://www.ietf.org/rfc/rfc3986.txt
Wikipedia - XML namespace
http://en.wikipedia.org/wiki/XML_namespace