Is it possible to use a Enum-Method in a QueryDSL query

Deadly 提交于 2021-01-27 19:05:56

问题


I have an entity type that contains an enum field. I use a JPA 2.1 AttributeConverter to map enum instances/values to a database column. The Enum values contain additional information I'd like to use in a QueryDSL query as if that information would be stored in the database.

Example: A message entity that contains a messageType. The type is a enum value. The enum determines if the message is global or not. In the database, the enum is represented as an int-value. The information if global or not is part of the enum.

Is it possible to write something like this?

import static com.example.QMessage.message;

@Repository
public class MessageDao {

    @PersistenceContext
    protected EntityManager em;

    public List<Message> getGlobalMessages() {
        return new JPAQuery(em)
            .from(message)
            .where(message.messageType.global.isTrue())
            .list(message);
    }
}

The query should only return the messages with MessageTypes where global==true. But the generated QMessageclass doesn't provide that functionality. message.messageTypegives an EnumPath without the possibility to call a function of the enum.

Enum

public enum MessageType {
    WELCOME(0, true),
    REMINDER(1),
    IMPORTANT(0, true);

    private final int id;
    private final boolean global;

    private MessageType(int id) {
        this(id, false);
    }

    private MessageType(int id, boolean global) {
        this.id = id;
        this.global = global;
    }

    public int getId() {
        return this.id;
    }

    public boolean isGlobal() {
        return this.global;
    }
}

Entity

@Entity
public class Message {

    @Id
    private long messageId;

    @Column(name = "MESSAGE")
    private String message;

    @Column(name = "MESSAGE_TYPE")
    private MessageType messageType;

    // Getter and Setter
    // ... 
}

Converter

@Converter(autoApply = true)
public class MessageTypeConverter implements AttributeConverter<Integer, String> {

    @Override
    public Integer convertToDatabaseColumn(MessageType messageType) {
        return messageType.getId();
    }

    @Override
    public Locale convertToEntityAttribute(Integer dbValue) {
        for(MessageType type : values()) {
            if(type.getId() == dbValue) {
                return type;
            }
        }
        throw new IllegalArgumentException("Unknown id");
    }
}

回答1:


Enums are treated as value/literal types in JPA, so there is no clean way to handle it through a property/method reference.




回答2:


One possible solution/workaround would be to create a static method in the enum type that returns a Collection of matching enum values (global==true):

return new JPAQuery(em)
        .from(message)
        .where(message.messageType.in(MessageType.getGlobalMessageTypes())
        .list(message);


来源:https://stackoverflow.com/questions/30990371/is-it-possible-to-use-a-enum-method-in-a-querydsl-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!