Гормональная проекция и потеря метаинформации
При использовании проекции на свойства результат возвращается в виде списка с элементами в той же последовательности, что и в блоке проекций. В то же время имена свойств отсутствуют в списке, и это действительно невыгодно для разработчика, так как результат будет передан, и вызывающая сторона должна знать, какое значение принадлежит какому свойству. Есть ли способ вернуть карту из запроса Criteria с именем свойства в качестве ключа к значению?
Итак, следующий код:
def c = Trade.createCriteria()
def remicTrades = c.list {
projections {
property('title', 'title')
property('author.name', 'author')
}
def now = new Date()
between('publishedDate', now-365, now)
}
Это возвращает:
[['book1', 'author1']['book2', 'author2']]
Вместо этого я хотел бы вернуть:
[[book:'book1', author:'author1'][book:'book2', author:'author2']]
Я знаю, что могу сделать это после получения результата, но я искренне чувствую, что псевдоним свойства должен был использоваться критериями для получения списка карты, который имитирует результат запроса SQL, а не простой список.
2 ответа
Дубликат: запросы Grails с критериями: как вернуть карту со столбцом?
И соответствующий ответ (и решение): /questions/32419293/zaprosyi-grails-s-kriteriyami-kak-vernut-kartu-s-kolonkoj/32419311#32419311
Используйте resultTransformer.
import org.hibernate.criterion.CriteriaSpecification
Trade.withCriteria {
resultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP)
projections {
property('title', 'title')
property('author.name', 'author')
}
def now = new Date()
between('publishedDate', now-365, now)
}
Согласитесь с обоснованием вашего вопроса, это действительно должно быть частью основного решения GORM. Тем не менее, вот мой обходной путь;
def props = ['name','phone']
def query = Person.where {}.projections {
props.each{
property(it)
}
}
def people = query.list().collect{ row->
def cols = [:]
row.eachWithIndex{colVal, ind->
cols[props[ind]] = colVal
}
cols
}
println people // shows [['name':'John','phone':'5551212'],['name':'Magdalena','phone':'5552423']]