Description
Testing this with Hibernate Reactive 4.0.0.Beta1
I have an entity that has fields that looks like this:
@Convert(converter = RatingConverter.class)
private Rating rating;
@Convert(converter = VectorConverter.class)
@Column(name = "desc_embedding")
private Vector descriptionEmbedding;
@Converter
public class RatingConverter implements AttributeConverter<Rating, String> {}
@Converter
public class VectorConverter implements AttributeConverter<Vector, String> {}
when I retrieve a single record, the RatingConverter
gets called as follows:
at startup, convertToDatabaseColumn() gets called 5 times (for each enum value)
Query occurs
convertToEntityAttribute()
gets called once as expected
However, for some reason, the VectorConverter
gets called as follows:
convertToDatabaseColumn() -- does NOT get called at startup
convertToEntityAttribute() -- with data from the database
convertToDatabaseColumn() -- with result from convertToEntityAttribute()
convertToEntityAttribute() -- with result from convertToDatabaseColumn()
In this particular case, for supporting Vector types, the database read and write are in different formats since Vert.x (or is it hibernate?) doesn't seem to support Vector types natively, so it gets encoded as a ISO_8859_1 string on the read, but you can't send it back that way because the database doesn't know how to convert it.
So this causes an issue because convertToEntityAttribute#1 is fine and I decode it properly. convertToDatabaseColumn#1 seems like a useless call because the conversion for vectors is kind of expensive, but still converts it back properly. Then it calls convertToEntityAttribute#2 and that's where things blow up because the string is in the WRITE format and not the READ format.
I do get that the converter is "supposed" to be symmetrical :), but in this case its not due to how vectors and vert.x work. From what I can tell, there's basically 2 ways I can send the vector back to the DB, a "compact" format and a "non-compact" format. I do have it working with the non-compact format because I can detect that its the second convertToEntityAttribute() call and act accordingly, but the compact format is indistinguishable from the database read format, so ...
First convertToEntityAttribute call callstack:
convertToDatabaseColumn call callstack:
2nd convertToEntityAttribute call callstack: