Unfortunately, Jakarta Persistence API (formerly Java Persistence API aka JPA) does not support BIT having a parametrised length. Fortunately, hibernate (one of the implementation of JPA) supports custom types, thus you can define your own BIT type with a parametrised length.
Custom Definition of BIT
First, you need to create BitStringType
, BitStringJavaDescriptor
, and BitStringSqlDescriptor
:
public class BitStringType extends AbstractSingleColumnStandardBasicType<String> {
public static final BitStringType INSTANCE = new BitStringType();
public BitStringType() {
super(VarcharTypeDescriptor.INSTANCE, BitStringJavaDescriptor.INSTANCE);
}
@Override
public String getName() {
return "BitString";
}
}
public class BitStringJavaDescriptor extends AbstractTypeDescriptor<String> {
public static final BitStringJavaDescriptor INSTANCE = new BitStringJavaDescriptor();
public BitStringJavaDescriptor() {
super(String.class, ImmutableMutabilityPlan.INSTANCE);
}
@Override
public String fromString(String string) {
return string;
}
@Override
public <X> X unwrap(String value, Class<X> type, WrapperOptions options) {
if (value == null)
return null;
if (String.class.isAssignableFrom(type))
return (X) value;
throw unknownUnwrap(type);
}
@Override
public <X> String wrap(X value, WrapperOptions options) {
if (value == null)
return null;
if (String.class.isInstance(value))
return (String) value;
throw unknownWrap(value.getClass());
}
}
@Override
public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
return new BasicBinder<X>(javaTypeDescriptor, this) {
@Override
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
st.setObject(index, javaTypeDescriptor.unwrap(value, String.class, options), Types.OTHER);
}
@Override
protected void doBind(CallableStatement st, X value, String name, WrapperOptions options) throws SQLException {
st.setObject(name, javaTypeDescriptor.unwrap(value, String.class, options), Types.OTHER);
}
};
}
@Override
public <X> ValueExtractor<X> getExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) {
return new BasicExtractor<X>(javaTypeDescriptor, this) {
@Override
protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
return javaTypeDescriptor.wrap(rs.getString(name), options);
}
@Override
protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {
return javaTypeDescriptor.wrap(statement.getString(index), options);
}
@Override
protected X doExtract(CallableStatement statement, String name, WrapperOptions options) throws SQLException {
return javaTypeDescriptor.wrap(statement.getString(name), options);
}
};
}
}
Use Your Custom BIT Type
Having those classes, you can define a type for your field. Please, use the correct package (in my case I’ve used the one from my demo com.yonlabs.jpa
):
@Column
@Type(type = "com.yonlabs.jpa.BitStringType")
private String bits;
You can also register this type with hibernate to use a registered name instead of a fully qualified Java class.