简体   繁体   English

如何在应用 Hibernate @Filter 时通过 ID 获取实体?

[英]How can I get an Entity by ID whilst applying a Hibernate @Filter?

I'm creating a library for dealing with temporal entities based on the DAO Fusion project.我正在创建一个用于处理基于DAO Fusion项目的时间实体的库。 One of the issues I've come across is when I query the database for a record by ID the @Filter I've defined on my Entity class is ignored.我遇到的一个问题是,当我通过 ID 查询数据库以获取记录时,我在我的实体 class 上定义的@Filter被忽略了。

I've created a filter in my package-info.java as follows:我在 package-info.java 中创建了一个过滤器,如下所示:

@FilterDef(name=EFFECTIVITY_FILTER, parameters={@ParamDef(name=EFFECTIVITY_PARAMETER, type=EFFECTIVITY_TYPE)})

and a simple entity for use within tests:和一个用于测试的简单实体:

@Entity
@Table(name = "USER")
@AttributeOverride(name="id", column = @Column(name="USER_ID"))
@Filter(name=EFFECTIVITY_FILTER, condition=":effective between start and end")
public class ImmutableUserEntity extends ImmutablePersistentTimestampTemporalEntity<Long> implements UserEntity<Long> {

  private static final long serialVersionUID = 843453303283850791L;

  private String firstName;
  private String secondName;

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getSecondName() {
    return secondName;
  }

  public void setSecondName(String secondName) {
    this.secondName = secondName;
  }
}

I've tried the following methods to get by ID我尝试了以下方法通过 ID 获取

IdentifierLoadAccess<Long> longIdentifierLoadAccess = getSession().byId(Long.class);
longIdentifierLoadAccess.getReference(id);

and

getEntityManager().find(getEntityClass(), id)

However the only way I've been able to lookup a record by I and apply the filter is to use a QueryBuilder with an equals predicate for the ID:但是,我能够通过 I 查找记录并应用过滤器的唯一方法是使用带有 ID 等于谓词的 QueryBuilder:

CriteriaBuilder builder = getSession().getCriteriaBuilder();
    CriteriaQuery<S> criteria = builder.createQuery(targetEntityClass);
    Root<S> root = criteria.from(targetEntityClass);
    criteria.where(builder.equal(root.get("id"), id));
    List<S> resultList = getSession().createQuery(criteria).getResultList();
    if (resultList.size() > 1) {
      throw new NonUniqueResultException();
    }
    return resultList.isEmpty() ? Optional.empty() : Optional.of(resultList.get(0));

This, however, is not very robust as it is dependant on the Entity's ID field to be named "id".然而,这不是很健壮,因为它依赖于实体的 ID 字段被命名为“id”。

Is there another, more robust way I can query by ID whilst applying the filter predicate?在应用过滤谓词时,是否有另一种更强大的方法可以通过 ID 进行查询?

I've found a workaround.我找到了解决方法。 I can get the name of the ID field as follows:我可以按如下方式获取 ID 字段的名称:

String idField = ((MetamodelImplementor)sessionFactory.getMetamodel()).entityPersister(getEntityClass()).getIdentifierPropertyName();

and use the field name in my where clause并在我的 where 子句中使用字段名称

criteria.where(builder.equal(root.get(idField), id));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM