Handling empty string foreign key in database in Spring/Hibernate ORM

I recently came across an issue when using Hibernate to map entity classes to an existing database. The database does not define foreign key constrain and use empty string (“”) in the FK column instead of NULL when a data row has no relation to the second table. When I mapped the relationship in my entity class, Hibernate attempts to find the associated entity using “” as the key. For example, the following code will throw an ObjectNotFoundException

@Entity

@Table(…)

@Repository(“myLoadListener”)

public class MyEntity {

@OneToOne

@JoinColumn(name=”fkCol”)

private MyAssocEntity assocEntity;

}

To work around the above problem, I implement a custom hibernate load event listener by extending the standard DefaultLoadEventListener:

@Component
public class MyLoadEventListener extends DefaultLoadEventListener {

@Override
protected Object doLoad(
final LoadEvent event,
final EntityPersister persister,
final EntityKey keyToLoad,
final LoadEventListener.LoadType options) {

Object entity = handleEmptyStringFK(keyToLoad);
return entity == null ? super.doLoad(event, persister, keyToLoad,   options) : entity;
}

@Override
protected Object proxyOrLoad(
final LoadEvent event,
final EntityPersister persister,
final EntityKey keyToLoad,
final LoadEventListener.LoadType options) {
Object entity = handleEmptyStringFK(keyToLoad);
return entity == null ? super.proxyOrLoad(event, persister, keyToLoad, options) : entity;
}

I override both doLoad() and proxyOrLoad() methods by adding a new method handleEmptyStringFK() to check for empty string in the identifier property in the input argument ketToLoad and instantiate an empty object to bypass the exception to be thrown by the parent’s methods. proxyOrLoad() is required here as it is called when using lazy loading.

Now, the listener has to be registered to the session factory. I use Spring and have to add the following in the xml configuration file:

<eventListeners refid=”myloadListener”></eventListeners>

Admittedly, this is a database issue but I cannot modify the data or database schema and the above solution works fine for me.

Advertisements