Skip to content

Instantly share code, notes, and snippets.

@jpsullivan
Created September 29, 2013 15:39
Show Gist options
  • Save jpsullivan/6753523 to your computer and use it in GitHub Desktop.
Save jpsullivan/6753523 to your computer and use it in GitHub Desktop.
package com.atlassian.stash.internal.hibernate;
import org.hibernate.CallbackException;
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
import java.io.Serializable;
/**
* Hibernate interceptor that guards against any empty strings being stored in the database. Empty strings are
* problematic because Oracle treats the empty string (zero-length) as {@code NULL}, which can cause all kinds
* of misery if the column in the database is {@code NOT NULL}, or if the application treats {@code null}s and
* empty values differently.
* <p/>
* To prevent such problems, this interceptor simply does not allow storing empty strings at all. All Hibernate
* entities should ensure that no empty strings are allowed, either through the use of JSR-303 validations or
* {@code Preconditions}-style checks. This interceptor is a catch-all for any empty strings which escape such
* validation, but the error messages are less helpful than the JSR-303 style messages.
*/
public class NoEmptyStringsInterceptor extends EmptyInterceptor {
@Override
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState,
String[] propertyNames, Type[] types) {
checkStrings(entity, id, currentState, propertyNames);
return false;
}
@Override
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
checkStrings(entity, id, state, propertyNames);
return false;
}
private static void checkStrings(Object entity, Serializable id, Object[] state, String[] propertyNames) {
StringBuilder errors = null;
if (entity.getClass().getPackage().getName().startsWith("com.atlassian.stash")) {
// only apply the check to Stash entities. Crowd can occasionally write empty strings, but can handle the
// Oracle quirks.
for (int i = 0; i < state.length; ++i) {
if ("".equals(state[i])) {
if (errors == null) {
errors = new StringBuilder()
.append(entity.getClass().getName())
.append(" with id '")
.append(id)
.append("' has empty string properties: [");
} else {
errors.append(", ");
}
errors.append(propertyNames[i]);
}
}
}
if (errors != null) {
errors.append("]");
throw new CallbackException(errors.toString());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment