В @Formula обратитесь к зависимости соединения вне этой формулы (не к подвыборке и не к этому объекту) - PullRequest
0 голосов
/ 13 июля 2020

Я пишу Hibernate @Formula, который вернет определенное значение. @Formula существует в определенном объекте домена (Plans.java).

Однако это значение зависит от будущего JOIN, о котором он в настоящее время не знает. То есть

Класс планов

@Formula("CASE" + 
         "    WHEN " + 
         "                     nv.organizationalstat = 'FELLOW' " + 
         "                     AND nv.hi_education_cd IS NOT NULL " +
         "                     ... " + // Some PLANS_T fields here, which are OK, since it's this object
                                       // Independent SUB-Selects are also OK
                                       // But what doesn't work is the Future Join dependency, "nv"
         "    THEN 1 " +
         "    ELSE 0 " + ...

При построении запроса я выполняю соединение с другой таблицей, NVTable,

     Root<NVTable> nvRoot = criteriaQuery.from(NV.class);
     Join<Object,Object> plans = nvRoot.join("plans", JoinType.LEFT);

@ Формулы работают, когда у меня есть независимые подвыборки, например (SELECT .. FROM ..) внутри них, или если все они находятся строго внутри этого объекта. Но как мне включить поле Future Join, которое не является независимым Sub-Select?

1 Ответ

1 голос
/ 16 июля 2020

Это невозможно, вам придется выполнить отдельное соединение в подзапросе.

Сказав это, это идеальный вариант использования Blaze-Persistence Entity Views .

Blaze-Persistence - это построитель запросов поверх JPA, который поддерживает многие расширенные функции СУБД поверх модели JPA. Я создал Entity Views поверх него, чтобы упростить сопоставление между моделями JPA и моделями, определяемыми пользовательским интерфейсом, что-то вроде Spring Data Projection на стероидах. Идея состоит в том, что вы определяете свою целевую структуру так, как вам нравится, и сопоставляете атрибуты (геттеры) через выражения JPQL с моделью сущности. Поскольку имя атрибута используется в качестве сопоставления по умолчанию, в большинстве случаев явное сопоставление не требуется, поскольку в 80% случаев использования должны быть DTO, которые являются подмножеством модели сущности.

Предполагая, что у вас есть модель сущности вот так

@Entity
public class NV {
    @Id
    Integer id;
    String organizationalstat;
    String hiEducationCd;
    @ManyToOne
    Plans plans;
}

@Entity
public class Plan {
    @Id
    Integer id;
}

Отображение DTO для вашей модели может выглядеть так же просто, как следующее

@EntityView(Nv.class)
interface NvDto {
    Integer getId();
    @Mapping("CASE WHEN organizationalstat = 'FELLOW' AND hiEducationCd IS NOT NULL AND plans.someField = 'ABC' THEN 1 ELSE 0 END")
    Integer getYourFormulaResult();
}

Запрос - это вопрос применения представления сущности к запросу, простейший из которых - запрос по идентификатору.

NvDto dto = entityViewManager.find(entityManager, NvDto.class, id);

Но интеграция Spring Data позволяет вам использовать его почти как Spring Data Projection: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring -data-features

Он будет получать только те сопоставления, которые вы ему указали.

...