Automatically convert a parameter with Spring Data JPA

22,499

You could use a custom type in your entity with JPA 2.1 @Convert, so JPA makes the conversion for you (I've tested it with Spring Data JPA also, and it worked transparently!), see:

Entity:

@Entity
class SomeEntity {

    @Column(name = "my_id_column_name")
    @Convert(converter = MyIDConverter.class)
    private ID itsID;
}

Converter:

public class MyIDConverter implements AttributeConverter<ID, String> {

    @Override
    public String convertToDatabaseColumn(ItStaticDataKey javaKey) {
        // your implementation here
    }

    @Override
    public ItStaticDataKey convertToEntityAttribute(final String databaseKey) {
        // your implementation here
    }

}

Notes:

  1. Make sure you're using a JPA-2.1-compatible Spring Data JPA version. (I'm sure that Spring Data JPA 1.7.0 (and above) are (or at least should) be compatible).
  2. Unfortunately, it won't work if that field should also be annotated with @Id.
  3. If you use EclipseLink, you have to define converter in persistence.xml, or it doesn't pick it up. https://bugs.eclipse.org/bugs/show_bug.cgi?id=412454.
  4. With JPA on Spring, package containing converters have to appear in property packageToScan on EntityManagerFactoryBean.
Share:
22,499
Jan Thomä
Author by

Jan Thomä

Updated on July 09, 2022

Comments

  • Jan Thomä
    Jan Thomä almost 2 years

    In our entity beans we use a custom ID format which includes a checksum to verify that the ID is actually valid. Ids look like ID827391738979. To make sure that all code uses correct IDs only we created a code wrapper around an ID String:

    class ID {
        public ID(String id) {
           // parse and verify ID
        }
    
        public String toString() {
           return id;
        }
    }
    

    All code just uses this ID object. However in our entity we have defined the ID as a String:

    class SomeEntity {
        @Column
        private String itsID;
    }
    

    Now we want to use Spring-Data-JPA to query some object by it's id. So we do:

    public SomeEntity findByItsID(ID itsId);
    

    Problem is, that now Spring Data JPA tries to assign the ID-typed parameter to the query, while the query of course expects a String.

    Is it possible to have Spring Data JPA convert the parameter to the expected type (e.g. by registering a Spring converter) before it is inserted into the query? Or, do we have to let the method take a String like this:

    public SomeEntity findByItsId(String itsId);
    

    I would rather avoid this, so all code can use the ID class instead of resorting to Strings.

  • osundblad
    osundblad about 8 years
    Thanks for number 2 been siting with it for two hours
  • Vladimir
    Vladimir over 6 years
    will a converter of type AttributeConverter<String, String> work? Its doesnt seem to be getting picked up by JPA
  • Peter Wippermann
    Peter Wippermann over 5 years
    @Vladimir : From AttributeConverter<X,Y>s JavaDoc: " A class that implements this interface can be used to convert entity attribute state into database column representation and back again. Note that the X and Y types may be the same Java type."
  • Julien Kronegg
    Julien Kronegg over 4 years
    Also you can't have both @Convert and @Enumerated on the field at the same time (I made this mistake and the converter was not taken into account).
  • Krish
    Krish over 3 years
    @falsarella How to deal with multiple datasource configuration ? I am not able to get the property value from properties file when I use multiple datasource configuration.
  • falsarella
    falsarella over 3 years
    Sorry @Krish I've been focused on frontend for some time. But it looks like your issue is more related to the configuration itself than the converter.
  • Datz
    Datz almost 2 years
    If you add @Converter(autoApply = true) to the converter-class, you can omit the @Convert... annotation and the converter is used automatically in all places where it fits.