Leaving JPA in an OSGi based world

Since a while, I have decided to leave JPA and use QueryDSL instead. JPA2 was great to go with, but after a while the life-cycles of Entity objects took more than they gave. It was only the Criteria API in JPA that we liked.

With OSGi it is much easier to develop reusable modules and with the help of type-safe SQL queries (like JPA Criteria API and QueryDSL) this re-usability can be extended onto the persistence level.

Check the Localization example. With Localization you can have an independent table in a separate modul. Based on the table you can have the same features as the ResourceBundle does in Java. However, it is also possible to create Util function that can return a SubQuery with the logic (based on the function COALESCE). You can embed the Localization logic into the selection part of query without knowing about the difficulty of the subquery. On the end, you will be able to query only a range of an ordered resultSet from a database where the ordering is done based on the localized column.

Question: How can we create the DDL scripts and when should we run them?

I have checked many projects and it seems that Liquibase is the tool what I need.

Liquibase in short: I can create an mostly database independent XML. The XML can contain schema definition but also uprade scripts (in case the current db uses an older version). Liquibase can run on existing database, validate it, or give advices what SQL should be applied on a production database by the DB Admin.

In case I have a module like Localization, it seems obvious to take the liquibase changelog XML into the META-INF folder of the bundle. What should pick it up and when?

I have a DS component in the bundle that registers the Localization service. Somehow the database should be validated/populated by Liquibase before my service is registered. I can do the database check when the DataSource reference is available in the component.

I have the following options, but I do not like any of them:

  • I generate the SQL scripts at development time for every supported database systems and put the native SQL scripts into the bundle, too. In that case I could give the SQL scripts to the DB Admins. However, this solution is not really good as Liquibase can handle version upgrades as well. In this case it is not really possible to do anything at runtime (even validate).
  • Hardcode the databae initiatization part of the component into the activate method by calling Liquibase code. What should be done than? Trying to update the database and if it is not necessary, saving the native SQL script somewhere to the file system or simply log it out with LogService?
  • Implementing a solution that can fit into the DS component registration based on service properties transparently. I am not sure it is even possible. What if my solution starts later than DS?
  • Creating Service Hooks… I will not do that for sure 🙂

This is a difficult question. I think at least the schema validation should be done during the Component activation when the DataSource is ready. Without writing Liquibase based code into the Activate function, I do not see if it is possible at all.


Tags: , ,

About Balázs Zsoldos

Balazs Zsoldos is the co-founder of Everit. He is the leader of the development of Everit OpenSource Components. Developing Java based solutions is not only his job but also his passion. He believes in simplicity. That is why he decided to design and build as many simple, but useful goal-oriented modules as he can. As the base of the stack, he chose OSGi. Balazs does not believe in monoholitic frameworks, therefore all of the solutions that was designed by him can be used separately. In the beginning of his career, Balazs was a big fan of JEE and Spring. After a while, he changed his mind and started to try replacing everything with non-magical solutions that do not contain interceptors, weaving, etc.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: