1

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();
Oleg Mikhailov
  • 5,751
  • 4
  • 46
  • 54

0 Answers0