объединение @NamedQuery из JPA и @Filter из Hibernate - PullRequest
0 голосов
/ 21 января 2020

У меня есть @NamedQuery. Я хочу добавить много разных фильтров в запрос согласно условию во время выполнения. В Hibernate есть еще одна концепция @Filter. Может ли эта концепция быть объединением, чтобы иметь комбинированный результат?

Предположим, у меня есть @NamedQuery(name="Users.someUsers",query="select u from Users where firstname='bob'")

. Предположим, я хочу отфильтровать результат по другому параметру. Могу ли я добавить @Filter, который может помочь?

Предполагается, что я хочу добавить файл возраста или фильтр мест поверх существующего Users.someUsers, включив соответствующий фильтр в базовом сеансе гибернации?

Ответы [ 2 ]

0 голосов
/ 22 января 2020

Полагаю, вы хотите определить именованные запросы и фильтры на уровне сущности и ожидать, что у именованных запросов будут фильтры, которые вы определили.

Я написал для него тест:

@Entity
@Table(name = "DEPARTMENT")
@NamedQueries({@NamedQuery(name=DepartmentEntity.GET_DEPARTMENT_BY_ID, query=DepartmentEntity.GET_DEPARTMENT_BY_ID_QUERY),})
@FilterDef(name="deptFilter", parameters={@ParamDef( name="name", type="string")})
@Filters( {@Filter(name="deptFilter", condition=":name = name")})
public class DepartmentEntity implements Serializable {

    static final String GET_DEPARTMENT_BY_ID_QUERY = "from DepartmentEntity d where d.id = :id";
    public static final String GET_DEPARTMENT_BY_ID = "GET_DEPARTMENT_BY_ID";
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", unique = true, nullable = false)
    private Integer id;

    @Column(name = "NAME", unique = true, nullable = false, length = 100)
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Теперь вы можете использовать оба варианта так:

Session session = (Session) entityManager.getDelegate();
    Filter filter = session.enableFilter("deptFilter");
    filter.setParameter("name", name);
    return (DepartmentEntity) session.getNamedQuery(DepartmentEntity.GET_DEPARTMENT_BY_ID)
            .setParameter("id", id)
            .uniqueResult();

Запрос, сгенерированный hibernate:

select department0_.ID as ID1_3_, department0_.NAME as NAME2_3_ from DEPARTMENT department0_ where ? = department0_.name and department0_.ID=?

Вам нужно будет добавить фильтры в сессию и затем создать именованный запрос. Если это не относится к вашему варианту использования, опубликуйте пример того, что вы хотите достичь.

0 голосов
/ 21 января 2020

Это то, для чего CriteriaQuery создан. Это позволяет создавать запросы во время выполнения. Избегайте использования именованных запросов для запросов, которые вы хотите построить во время выполнения на основе пользовательского ввода.

Пример

CriteriaBuilder builder = entityManager.getCriteriaBuilder();

CriteriaQuery<EntityType> criteria = builder.createQuery(EntityType.class);

Root<EntityType> root = criteria.from(EntityType.class);

criteria.where(
  builder.equal(root.get("owner"), "something")
);
 // Any conditions can be added to criteria here ar runtime based on user input

List<Topic> topics = entityManager
.createQuery(criteria)
.getResultList();

Именованные запросы предварительно компилируются при запуске EntityManagerFactory, поэтому они повышают производительность, если запросы stati c, но для динамических c запросов рекомендуется использовать CriteriaQueries

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...