Hibernate and Composite keys
March 22nd, 2009
I like using surrogate keys for most of the database designs for the following reasons:
- Simplifies design and may improve efficiency
- Maintainability: Change to the meaning of the natural key could change the table structures when using natural keys
- Natural key values may be recycled
Here is a partial list of issues I have encountered when using Hibernate with composite keys on a legacy database:
- The documentation (or lack there-of) for Composite Keys usage poses big problems. But, the source code really helps .
- Inserts/Updates are slightly inefficient when compared to surrogate keys if there is no versioning strategy implemented.
- Cannot have relationships (with CRUD operations) mapped in hibernate for each of the keys in the composite primary key. A read-only collection mapping is possible by mapping the relationship with the same column (that is part of the Composite Key) and making insert=”false” and update=”false”.
- It is impossible to determine if the object to be saved is a new one or an existing one when using “assigned” composite keys. Since the keys are “assigned”, the primary key is not null and so it is hard to determine if this is a new object without making another call in a new transaction to the DB. This becomes very cumbersome.
- The Hibernate reference documentation uses various phrases like “discourage it for serious applications” for certain types of Composite-id mappings (embedded composite identifier). There are several issues with using key-many-to-one mapping in the Composite-id elements, etc.
- In older versions of Hibernate (before 3.3.x), you can’t use an IdentifierGenerator to generate composite keys. The suggested approach was to use UserType or CompsiteUserType. A lot of people choose to use “assigned” strategy to avoid the complications with custom types. I think this is resolved in the latest Hibernate version. Again, the documentation here is almost non-existent. In order to make this work in my code, I had debug through the Hibernate source code and also use the test case code attached in this Hibernate CR.
Mock objects and Testing
March 15th, 2009
This has been a much discussed topic over the web in the last couple of years. I was responding to one of the emails at work about mock objects. While organizing my thoughts about Mock objects, I decided to write this post.
Various thought leaders in TDD promote Mock objects. I agree with some of it but not everything they say.
Some caution towards using Mocks extensively:
-
Using Mock objects might affect design decisions:
-
The mocked classes (and the methods used to set up expectations) cannot be final. If called, their normal code may be executed. I prefer making every class either final or abstract unless there is a strong reason to not to do so.
-
A class with only private constructors cannot be instantiated.
-
The behavior for equals() and hashCode() when using mocks may not be what you normally expect.
-
Private methods cannot be mocked. I prefer making every method private unless there is a strong reason to not to do so.
-
-
Trustworthiness & ROI of Mocks: Mocks may hide integration problems and push the burden on other tests. High-level and End-to-end tests give the most ROI, in my opinion. I would value these over the unit tests that use mocks extensively when constrained by Time & Resources. Most of the times, I have seen that tests using mocks extensively completely miss the intent of the test..!
-
Increased complexity and maintenance costs - Setting up mock object expectations create clutter and duplication to test code. Mocking Fine-Grained or Chatty Interfaces results in a lot of brittle unit-test code. High-level tests may not require such extensive changes.
-
It is a well-known fact that unit tests (that use mocks extensively) don’t catch as many bugs as the integration/high-level tests.
I do not want leave an impression that I do not like the idea of using Mock objects for testing. We just need to use it for the right things and right places after understanding it’s rewards and risks, just like any other tool/framework.
Mocking is still suitable for various scenarios that include:
-
Testing sub-systems that don’t exist yet or are being developed separately. But, then after the dependent code is available, I would switch back to real code from mock objects.
-
Legacy code that does not have interfaces and is tightly coupled.
-
Sometimes we may need to mock only some methods of a class and keep the normal behavior of others.
-
Testing against slow/heavyweight components that have significant dependencies.
-
To simplify Unit testing when there are no alternative ways to test the same effectively (for example, if the dependent component is very hard to setup/configure, etc.).
IMO, choosing the right scenarios objects (if any) for using Mock objects is the trickiest part.
I personally avoid using Mock Objects (unless there are no other easy options) by using good OO Design & Programming practices to write my code such that it is testable without having to use Mock Objects.
Application Configuration properties simplified by Spring
February 8th, 2009
The combination of PropertyPlaceholderConfigurer and PropertyOverrideConfigurer classes in Spring Beans API have been invaluable for me to simplify configuration properties for a few of applications I have worked-on recently. The placeholder configurer helps us to share the properties across various pieces of the application using “placeholders”.
As recommended in the Spring reference manual, I usually setup a “default” configuration file (app.properties.default) file that is packaged within one of the main Jar files. This keeps the actual (overriding production) properties file very short as you only override the properties that are different than the default properties file.
Sometimes, a simple loading of the configuration properties may not be enough. There might be a need for post-processing the properties using some custom code.
Certain properties may have to be:
- Selectively disabled/enabled
- Translated based on the values of others
- Set & be available within the application (in the code that is not wired-up in Spring XML)
Spring does have hooks for some of these to decrypt/encrypt properties, intercept the processing of each of the String values, etc. This means writing a new class that overrides the natural behavior of these Configurer classes.
Both of these Configurer classes are implemented as bean factory post-processors. So, if ApplicationContext is used instead of BeanFactory, these should automagically work. If you are using BeanFactory interface (eg., XMLBeanFactory class), then you will need to construct these Configurer classes and call the “postProcessBeanFactory” method by passing the BeanFactory instance as a parameter.
This method is also very helpful if there is a need to centralize the post-processing logic in one place and if this logic involves a lot of custom coding:
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
As per the Javadocs, this method is invoked after all bean definitions have been loaded, but no beans have been instantiated yet.
Best way to demo/learn a Java-based API
February 1st, 2009
I designed and implemented a dual-API SDK at my current job. This dual-API SDK did not initially run on any application server.
During this implementation, I learnt that it is best to use a dynamic language like JRuby or JPython or Groovy for demonstrating & learning the capabilities of the API as well as interactively test some edge-case scenarios that are not so easy to automate (randomly causing network outages, database outages, etc.). This was very useful especially at the Sprint reviews to demonstrate the new functionality.
It is incredibly easy it is to set up some complex scenarios interactively using the Java API calls in one of the above 3 dynamic languages. We are still using JDK 5 and so could not take advantage of the built-in scripting support in JDK 6.
We chose to use JRuby (due to the familiarity of Ruby to some developers) even though my favorite was JPython, especially because I have had experience building a large-scale enterprise system using Python in one of my previous jobs at a startup.
However, we ran in to one big problem: The APIs (API interfaces) that use Java Generics were impossible to test using JRuby. We kept the usage of generics to very minimal in our client API interfaces but for obvious reasons our SPI-side interfaces used generics heavily.
After a while, I also realized that it is impossible to type all of the JIRB commands correctly. Any typos in JIRB can lead to really ugly stack traces on the console. Hence, the need for tab-completion and file-based history to remember all of the commands that can be accessed by using the up-arrow/down-arrow keys.
Also, as a nice touch to our Sprint review demos, we customized the command prompt to display our product name (I have changed that to “MYSDK”, below). So, the following .irbrc file was created and copied to the user.home dir.
# ~/.irbrc
# enables Tab completion
require 'irb/completion'
#IRB.conf[:PROMPT_MODE] = :SIMPLE
IRB.conf[:USE_READLINE] = true
IRB.conf[:ECHO] = false
IRB.conf[:IRB_NAME] = “MYSDK”
IRB.conf[:DEBUG_LEVEL] = 0
IRB.conf[:AUTO_INDENT_MODE] = true
# Setup a file-based history across sessions of irb
require ‘irb/ext/save-history’
IRB.conf[:SAVE_HISTORY] = 100
IRB.conf[:HISTORY_FILE] = “#{ENV['IRBRC']}-history”
require ‘java’
import java.lang.System
# SDK stuff
# My SDK imports go here..
OSGi for Web Applications?
January 27th, 2009
Web applications are the most common type of deployments on the application servers.
So, if OSGi is going to be a serious contender in the application server market, I would expect it to have great support for deploying web applications using WAR files. So, I looked through the existing documentation on eclipse.org and played with Equinox, Tomcat and Jetty. Here is what I have learned so far:
There are two ways to integrate Equinox’s implementation of OSGi into your server-side environment:
- Embed your web application server within OSGi server
- Native OSGi HTTP service implementation of Servlet API 2.4
- Jetty-based implementation - Also requires the usage of the dynamic OSGi HTTP Service.
- Embed OSGi server into your existing web application server
- Equinox Bridge Servlet (Front controller servlet)
- Dynamic OSGi HTTP Service using the Equinox Bridge Servlet
Option #1 means that the developer is forced to use OSGi HTTP Service. This is great for new web applications built from scratch. The user can programmatically register the servlets and add service listeners to listen for any events (if any one of these instances are started, stopped or updated, we are notified). But, this complicates the development effort required for making an existing WAR file work with this setup. Traditionally, Servlets have been considered “static” - They do not have to be installed/started/stopped dynamically. So, the “dynamic” OSGi HTTP service becomes an overkill in this particular case, IMO. The other disadvantage of this approach is that not all aspects of the Servlet spec are implemented here. For ex., Servlet Filters are not yet available in the native OSGi HTTP service implementation. I am not sure how clustering can be achieved here.
Option #2 uses the standard “Front-controller” pattern and uses the Bridge Servlet as a Front controller servlet. org.eclipse.equinox.servletbridge and the Servlet API are exported automatically to the underlying OSGi framework. So, the modules deployed in the OSGi server have access to the Servlet API to register/unregister servlets. This approach obviously uses the web.xml. So, you can add more servlet mappings for JSPs, if necessary. The other sub-options here revolves around using this Servlet bridge to provide the dynamic OSGi HTTP service.
So, I do not feel comfortable with both of the above options provided by Equinox OSGi implementations. Perhaps, other implementations might have better solutions.
No wonder the folks at SpringSource chose not to implement OSGi HTTP service in their SpringDM server platform for now. They support the standard WAR file deployment within their embedded Tomcat server. This seems like a pragmatic approach to me to support all the existing standard Web Application Archive (WAR) files.
Although I like the other dynamic services (Logging, Configuration, Event Admin Service, etc.) in the OSGi Service Compendium, I am not so sure about the HTTP Service, especially for existing web applications.
What do you think?
Hibernate direct field acess and encapsulation
January 18th, 2009
I am a big fan of the Hibernate’s direct field access functionality. I am not sure why ”property” access is the default instead of “field”. Direct field access allows me to control the number of getters/setters that are actually needed from the DAO Client’s perspective.
I think using property access helps enforce better encapsulation of the data in the mapped/persistent classes. I have seen that most developers just use public getters and setters for all of the properties in the mapped class.
This creates problems for collections, especially. I seldom expose getters and setters for collections. I always use a combination of “addXXX(Obj)”, “removeXXX(Obj)” and “clearXXX()” (depending upon the need) instead of “get/setXXX”. This is for efficiency (as Hibernate uses a custom collection class) and better encapsulation.
The only situations where I do not use the direct field access are:
- If the DB schema data type does not directly map to the mapped attribute in Java where a translation is required. This is mostly true for Legacy Database schemas and also where custom introducing custom SQL type mapping is not an option perhaps due to inconsistent use of the same data type in legacy applications.
- If there are dependent (child) tables that have composite primary keys (which include the primary key of the parent table). In this case, for saving a new entity I would need to intercept the setter of the primary key of the parent table to set the appropriate fields in the child tables.
- If I use lazy initialization, I would use property access for the primary key. This allows us to call persistentObj.getId() without completely initializing the proxy. This is applicable only for the “Id” field.
- If there is any other need to intercept the getters/setters for whatever reasons (validation, logging, debugging, etc.). This is very unlikely.
Missing “friend” class access specifier in Java?
December 7th, 2008
I am in the process of rearchitecting a fairly large legacy web application. Almost all of the classes in the old code base are public classes with the key classes containing mostly public (and sometimes static) methods. I am tasked to modularize this application for various obvious reasons in an evolutionary and progressive manner.
Java package names are used for various purposes such as:
- Namespaces for tiers (web-tier, middle-tier, EIS-tier, etc.)
- Namespaces for layers (service layer, DAO layer, etc.)
- Namespaces for the purpose of the classes (Utility classes, implementation classes, etc.)
- Namespaces based on module structure, deployment architecture, etc.
So, it is not always possible to put the implementation classes and the classes that need to access the implementation classes in the same package for any combination of the above reasons or use inheritance between them. So, the standard Java package-private and protected access specifiers might come up short.
So, one of the consequences of these restrictions in Java is to make the class public, eventhough you may not want this class accessible to every other class in that module/bundle or classpath by default (depending on whether you are talking about OSGi or non-OSGi based applications).
Sometimes, I miss the C++ “friend” Class (not the function) access specifier. However, I think the “friend” class in Java should not have access to all of the private members, instead it should have access to the “friend” or “protected” members of the other class. But, perhaps the designers of the Java language may have decided against this due to fear that the not-so-OO-developers might violate encapsulation by misusing this feature.
I have seen or heard of various approaches to solve this problem:
- Use Delegation and/or Composition
- Use “internal” package names
- JavaDoc them as “for internal use only” (org.springframework.orm.hibernate3.SessionHolder in Spring API)
- Use classloading trickery to simulate “friend” access specifier. This may not work in web applications or OSGi (due to the “modularity” or various classloading architectures))
My preferred way to do this (if I absolutely cannot put them all in the same package and make them package-private) is to use delegation or composition or a factory class (depending upon the type of situation that causes this problem).
What do you think? Are there better ways to do this?
Don’t we need a modified form of “friend” access specifier in Java?
Essentials for OSGi-based middleware development
December 2nd, 2008
Here are the things every Java developer working on OSGi-based middleware must know, IMO:
Essentials:
- Design-by-Contract & SOA
- Component/Package Versioning
- OSGi Bundle Lifecycle
- Bundle Manifest directives
- Core OSGi services
- Spring DM (especially for simplification of the usage of OSGi services and writing in-container tests)
- BND tool (I cannot think of a better way to create the OSGi manifest files than this)
- Basics of classloading in OSGi
Advanced Topics:
- HTTP Server options in OSGi (OSGi HTTP Service, HTTP Servlet Bridge, etc.)
- OSGi “uses” directive and the “type leakage” problem
- OSGi Services vs. Extensions/Extension points
- Service Trackers
- Concurrency gotchas in OSGi
- The Whiteboard pattern
- The “Extender bundle pattern”
- OSGi Declarative Services and Configuration Admin Service
OutOfMemoryError: PermGen space
November 25th, 2008
Today, during load testing I saw one of those dreaded “java.lang.OutOfMemoryError: PermGen space” errors on our fairly large web application deployed in Tomcat running on Sun JDK 1.5.
We used to use the default (64m) for the perm space. I bumped it to 128 for now, until I can find some time to dig into this using JProfiler and JHAT.
I will be particularly looking at the amount of our classes loaded from WEB-INF/classes dir (we have a lot of generated classes from legacy code), Static references in our legacy code, Spring AOP/Hibernate CGLib usage and ThreadLocal usage in our application.
I found some useful information here:
OSGi - the next Java Middleware technology
November 24th, 2008
I think the Java developers (especially server side developers) have started looking at OSGi as the next-generation Java Middleware technology. This may not come as a surprise because of the adoption of OSGi by the JEE server vendors and Java (server, desktop and embedded Java) community in general.
OSGi technology:
- Enforces better componentization (separation of concerns) than most existing techniques in JEE (Using one classloader per bundle).
- Provides versioning of components and the ability to deploy multiple versions of the same components in the same VM, unlike JEE.
- Unless you use one ”component” for your entire application/product, OSGi enforces SOA for components using dynamic services (or “Extensions”/”Extension points” for those wanting to use the old Eclipse standard).
- Enforces loose coupling of components (using a publish/find/bind service model).
- Forces the resolution of application dependency problems (requiring explicit declaration of dependencies between components).
- OSGi ”fixes” Application server hot-deployment functionality (ability to deploy/undeploy software components without requiring the Server/JVM).
- There are multiple opensource OSGi implementations available:
- OSGi implementations are quite stable with many applications/servers using or running on them.
- Ricoh has been shipping Printers with OSGi since 2005.
- BMW 5 series cars ship with OSGi.
- JBoss, IBM WAS and BEA Weblogic servers are adopting OSGi.
- Sun’s Glassfish uses OSGi
- SpringSource dm server is built on top of OSGi.
- Mule ESB
- The OSGi implementations generally have a small footprint (With OSGi Jars that are less than 500 kb).
- OSGi has proven itself in the embedded and desktop application world too. The open source Eclipse IDE has been based on OSGi since 2004.