Configure hibernate (using JPA) to store Y/N for type Boolean instead of 0/1
This is pure JPA without using getters/setters. As of 2013/2014 it is the best answer without using any Hibernate specific annotations, but please note this solution is JPA 2.1, and was not available when the question was first asked:
@Entity
public class Person {
@Convert(converter=BooleanToStringConverter.class)
private Boolean isAlive;
...
}
And then:
@Converter
public class BooleanToStringConverter implements AttributeConverter<Boolean, String> {
@Override
public String convertToDatabaseColumn(Boolean value) {
return (value != null && value) ? "Y" : "N";
}
@Override
public Boolean convertToEntityAttribute(String value) {
return "Y".equals(value);
}
}
Edit:
The implementation above considers anything different from character "Y", including null
, as false
. Is that correct? Some people here consider this incorrect, and believe that null
in the database should be null
in Java.
But if you return null
in Java, it will give you a NullPointerException
if your field is a primitive boolean. In other words, unless some of your fields actually use the class Boolean it's best to consider null
as false
, and use the above implementation. Then Hibernate will not to emit any exceptions regardless of the contents of the database.
And if you do want to accept null
and emit exceptions if the contents of the database are not strictly correct, then I guess you should not accept any characters apart from "Y", "N" and null
. Make it consistent, and don't accept any variations like "y", "n", "0" and "1", which will only make your life harder later. This is a more strict implementation:
@Override
public String convertToDatabaseColumn(Boolean value) {
if (value == null) return null;
else return value ? "Y" : "N";
}
@Override
public Boolean convertToEntityAttribute(String value) {
if (value == null) return null;
else if (value.equals("Y")) return true;
else if (value.equals("N")) return false;
else throw new IllegalStateException("Invalid boolean character: " + value);
}
And yet another option, if you want to allow for null
in Java but not in the database:
@Override
public String convertToDatabaseColumn(Boolean value) {
if (value == null) return "-";
else return value ? "Y" : "N";
}
@Override
public Boolean convertToEntityAttribute(String value) {
if (value.equals("-") return null;
else if (value.equals("Y")) return true;
else if (value.equals("N")) return false;
else throw new IllegalStateException("Invalid boolean character: " + value);
}
Hibernate has a built-in "yes_no" type that would do what you want. It maps to a CHAR(1) column in the database.
Basic mapping: <property name="some_flag" type="yes_no"/>
Annotation mapping (Hibernate extensions):
@Type(type="yes_no")
public boolean getFlag();