Поля результатов совокупного запроса Hibernate OGM не работают с типами оболочек

Я использую Hibernate OGM (5.2.0.Alpha1) с Mongodb (3.4)

Пример:

@Entity
@Table(name = "jangad")
@JsonInclude(Include.NON_EMPTY)
public class Jangad {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonSerialize(using = ToStringSerializer.class)
    public ObjectId id;

    public String name;

    @OneToMany(mappedBy = "jangad")
    public Set<SalesStoneCharacteristics> setOfSalesStoneCharacteristics;

    // Note : Integer data type for this not working with aggregation result.
    public Integer totalStones;

    getter....
    setter....

}


@Entity
@Table(name = "sales_stone_details")
@JsonInclude(Include.NON_EMPTY)
// @JsonFilter(value = SalesUtils.MY_CUSTOM_FILTER_FOR_SURAT_POLISH_STONES)
public class SalesStoneCharacteristics {
     @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "SALES_STONE_CHARACTERISTICS_ID", unique = true, nullable = false)
    @JsonSerialize(using = ToStringSerializer.class)
    public ObjectId id;

    private String name;

    @ManyToOne
    @JsonIgnore
    private Jangad jangad;

    setter....
    getter....
}

Дао Слой...

public <T> List<T> executeQuery(String query, Integer startPosition, Integer noOfRecords, T t) {
        List<T> listOfT = new ArrayList<>();

        if (SalesUtils.isObjectisNullOrEmpty(startPosition, noOfRecords)) {
            listOfT = entityManager.createNativeQuery(query.toString(), t.getClass()).getResultList();
        } else {
            listOfT = entityManager.createNativeQuery(query.toString(), t.getClass()).setFirstResult(startPosition)
                    .setMaxResults(noOfRecords).getResultList();
        }
        return SalesUtils.isListIsNullOrEmpty(listOfT) ? new ArrayList<>() : listOfT;
    }

Сервисный уровень....(ошибка)

@Transaction
public void executeQuery() {

    String query = "db.jangad.aggregate({'$project': { 'totalStones': { '$size':'$setOfSalesStoneCharacteristics' }}} , { '$match' : { '_id' :ObjectId('5a60784e8daff90498ba74e4')} } )";

    List<Jangad> listOfJangads = jangadDao.executeQuery(sb.toString(), null, null, new Jangad());
    if (!SalesUtils.isListIsNullOrEmpty(listOfJangads)) {                   
        System.out.println(listOfJangads.get(0).getTotalStones()) // Error
    }
}

Временное решение: изменен тип поля totalStones с Integer на int из Jangad.java

Объяснение ошибки уровня обслуживания....(Ошибка)

здесь, если я устанавливаю тип totalStones как тип Wrapper (например, Integer,Double), тогда это дает ошибку, поэтому я должен установить для этих типов полей значение int или double.

Кажется, что результат агрегирования не работает с любым типом Java Wrapper.

Я прав?

1 ответ

Есть две проблемы с этим запросом. Во-первых, вы не передаете его как массив, и, следовательно, синтаксический анализатор выдал исключение. Вы должны добавить [ а также ] вот так:

String query = "db.jangad.aggregate([{'$project': { 'totalStones': { '$size':'$setOfSalesStoneCharacteristics' }}} , { '$match' : { '_id' :ObjectId('5a60784e8daff90498ba74e4')} }] )";

Это должно работать.

Но если вы заинтересованы только вtotalStones почему бы просто не вернуть это значение? Это будет выглядеть так:

String totalStones = "db.jangad.aggregate([{'$project': { 'totalStones': { '$size':'$setOfSalesStoneCharacteristics' }}} , { '$match' : { '_id' :ObjectId('5a60784e8daff90498ba74e4')} }, {'$project':{ '_id': 0}}] )";
Integer size = (Integer) em.createNativeQuery( query ).getSingleResult();

Вам не нужно каждый раз создавать объект, если вам нужны только определенные поля, и вам не нужно отображать поле totalStones на объекте.

РЕДАКТИРОВАТЬ: из-за ошибки в распознавании 0, этот последний запрос будет работать только для версий после Hibernate OGM 5.2.CR1

Если вы хотите / должны создать объект сущности, убедитесь, что запрос возвращает все поля, или OGM создаст неполный объект. В этом случае Jangad будет иметь только id и свойство totalStones.

Другие вопросы по тегам