Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle Enums as string in spring data jpa Specification

Trying to use specification for filter data at database level. I have an entity with another entity as an instance wherein the instance variable class contains an Emun field. This defaults to a string in the database for the enum field.

@Entity
public class Outer{

    @OneToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
    @JoinColumn(name = "current_status")
    private Status current;

    @OneToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
    @JoinColumn(name = "past_status")
    private Status past;
...
...

@Entity
public class Status{

    @Enumerated(EnumType.STRING)
    @Column(name = "state")
    private State state;

    @Id
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid",strategy = "uuid2")
    @Column(name = "id")
    private String id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "outer_id")
    private Outer outer;

I have created static meta models for both the classes.

How do I create a Predicate to match State using a where in clause with the enum values supplied as Strings(not instances of enums) ?

like image 722
Rajeev Ranjan Avatar asked Nov 22 '17 12:11

Rajeev Ranjan


1 Answers

You modeled the entity attribute as an Enum and Hibernate, therefore, expects an enum in all JPQL or Criteria queries.

So, you either have to map all Strings to State enums or use a native SQL query.

Hibernate doesn't parse native queries, and they are based on the table model instead of the entity model. That allows you to use the String representation of your State enum.
You can do something like this:

List<State> states = ... // get or initialize your State list here
Query q = em.createNativeQuery("SELECT * FROM Status s WHERE state IN (:states)", Status.class);
q.setParameter("states", states);
List<Status> s = (List<Status>) q.getResultList();

The second parameter of the createNativeQuery method tells Hibernate to map each record of the result set to a Status entity. These entities are managed, and you can use them to update or remove the mapped database records.

To use this mapping, you need to make sure that your query selects all columns mapped by the entity. I wrote a series of posts that get into more details on the different result mapping options:

  • Result Set Mapping: The Basics
  • Result Set Mapping: Complex Mappings
  • Result Set Mapping: Constructor Result Mappings
  • Result Set Mapping: Hibernate specific features
like image 89
Thorben Janssen Avatar answered Nov 15 '22 00:11

Thorben Janssen