Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically convert a parameter with Spring Data JPA

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.

like image 824
Jan Thomä Avatar asked Apr 09 '14 14:04

Jan Thomä


1 Answers

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.
like image 196
falsarella Avatar answered Oct 07 '22 14:10

falsarella