Как я могу получить Entity по идентификатору при применении Hibernate @Filter? - PullRequest
0 голосов
/ 01 октября 2019

Я создаю библиотеку для работы с временными сущностями на основе проекта DAO Fusion . Одна из проблем, с которой я столкнулся, это когда я запрашиваю у базы данных запись с идентификатором, который @Filter, который я определил в своем классе Entity, игнорируется.

Я создал фильтр в моем package-info.java следующим образом:

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

и простую сущность для использования в тестах:

@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пробовал следующие методы, чтобы получить по идентификатору

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

и

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

Однако единственный способ, которым я смог найти запись по I и применить фильтр, этоиспользуйте 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));

Это, однако, не очень надежно, поскольку оно зависит от поля идентификатора сущности с именем "id".

Есть ли другой, более надежный способ запроса по идентификатору при применении предиката фильтра?

1 Ответ

0 голосов
/ 01 октября 2019

Я нашел обходной путь. Я могу получить имя поля идентификатора следующим образом:

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

и использовать имя поля в предложении where

criteria.where(builder.equal(root.get(idField), id));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...