Skip to content

AttributeConverter called multiple times for same record #2285

Closed
@SledgeHammer01

Description

@SledgeHammer01

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:

Image

convertToDatabaseColumn call callstack:

Image

2nd convertToEntityAttribute call callstack:

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions