JPA: A row of a EnumSet with a @AtrributeConverter and jpa-ql query, that does not work anymore

42 Views Asked by At

Imagine, your JavaEE oder Spring application has to save a EnumSet into a database JPA/Hibernate. The easiest way to do, is to create a table/row like this:

@Entity
@Setter
@Getter
public class Person {

   /* ... */     

   @ElementCollection
   @Enumerated(EnumType.STRING)
   @CollectionTable(name = "SET_ATTRIBUTE")
   private Set<EnAttribute> setOfAttributes;

   /* ... */     
}

This simple implementation allows us to use the JPA-QL languange, in order to filter for Person entries by giving a enum attribute. This might be our finder, that resides in a SpringJPA reporistory (works similar in JavaEE):

public interface PersonRepo extends CrudRepository<Person, Long> {

    @Query("SELECT pers FROM Person pers WHERE :pAttr MEMBER OF pers.setOfAttributes ")
    List<Person> findPersonBy (final EnAttribute pAttr);
}

But sometimes, you may be envisaged with a low performance of the above shown filter, so you might get rid of the SET_ATTRIBUTE table and the implicit JOIN operation, by using a simple bitfield instead of a table. If the domain of the EnAttribute does not hold more that 30 enum-items, you may try to translate the enumeration ordinal number into a position of a number like, i.e. an integer.

Fortunately JPA comes with an attribute-converter, that can be used like this:

@Entity
@Setter
@Getter
public class Person {

   /* ... */     

   @Convert(converter = ConverterSetOfPersAttribute.class)
   private Set<EnAttribute> setOfAttributes;

   /* ... */     
}

This works perfectly for saving and loading complete (Entity)Sets into/from the database into your application by simply reading one db row. But there is one problem, my selected datatype may be wrong. I received immediately an exception, when my application was starting an JPA tried to translate the finder into the postgres database. I received an exception containing a similar message to "bytea is not compatible with integer".

This message make sense, JPA/Hibernate recognizes the absense of a SET_ATTRIBUTE and translates the member-of expression also to a numeric expression and expect it to be a array of bytes (bytea). So i guess i was choosing the wrong target datatype (integer).

My questions:

  • Shall i use one of both EnumSet implementation (for small and lage enumsets) or what type should i use to save the set as a cardinal into the database ?
  • I know, that postgres comes with the support of enumeration. Will the postgres hibernate implementation support these features in future ?

Thank you all!

I tried to change the set-representation in the database and expected the JPA-QL finder is still working, but i must be wrong.

0

There are 0 best solutions below