There is a class Order
with inks
field which is a collection of 4 possible Ink
constants: Ink.YELLOW, Ink.MAGENTA, Ink.CYAN, Ink.BLACK
. Inks
are converted into single Integer
as a bit mask using each Ink
's position. For example { Ink.MAGENTA, Ink.CYAN } => 0110 => 6
.
For some reason AttributeConverter
receives empty Inks
when saving entity to database and always produces 0
in database column. When it is run directly everything works just fine.
I see the AttributeConverter
is being run twice. Inks
argument is empty only the second time. I believe something is wrong with mapping.
Order
@Entity
public class Order {
@Id
public int id;
@Convert(converter = InksConverter.class)
public Inks inks = new Inks();
//...
}
Inks
public class Inks {
private TreeSet<Ink> set = new TreeSet<>();
public Inks(Ink... inks) {
set.add(inks);
}
public void add(Ink... inks) {
for (int i = 0; i < inks.length; i++) set.add(inks[i]);
}
public int toInteger() {
Integer i = 0;
for (Ink ink : set) i |= (1 << ink.id);
return i;
}
public Inks fromInteger(int i) {
Inks inks = new Inks();
Ink.set.forEach(ink -> {
if ((i & (1 << ink.id)) == 1) inks.add(ink);
});
return inks;
}
//...
}
InksConverter
@Converter(autoApply = true)
public class InksConverter implements AttributeConverter<Inks, Integer> {
@Override
public Integer convertToDatabaseColumn(Inks inks) {
return inks.toInteger();
}
@Override
public Inks convertToEntityAttribute(Integer i) {
return Inks.fromInteger(i);
}
}
Saving order into database
Session session = configuration.buildSessionFactory().openSession();
Order order = new Order();
order.inks.add(Ink.BLACK, Ink.CYAN);
session.save(order);
session.close();