В этом и заключается подвох: мы создали веб-приложение, использующее Spring MVC, которое подключалось к базе данных Oracle 12c, используя Hibernate и Hikari в качестве пула соединений.
мы используем стиль запросов HQL для выбора данных с помощью Spring Data JPA.Мы используем select from multiple tables
запрос для серверной части.
Вот часть внутреннего хранилища:
@Query(value = "SELECT t1.p1 as p1, " +
" t2.p2 as p2, " +
" t3.p3 as p3, " +
" t4.p4 as p4, " +
"from Model1 t1, " +
" Model2 t2, " +
" Model3 t3, " +
" Model4 t4 " +
"where t1.p1 = t2.p1 " +
" and t2.p2 = t2.p2 " +
" and t3.p3 = t3.p3 " +
" and (p1 = ?1 or ?1 is null) " +
" and (p2 = ?2 or ?2 is null) " +
" and (p3 = ?3 or ?3 is null) " +
" and (p4 = ?4 or ?4 is null) ")
fun finder(
@Param("p1") p1: String?,
@Param("p2") p2: String?,
@Param("p3") p3: String?,
@Param("p4") p4: String?,
pageable: Pageable
): Page<Array<Any>>
, как вы можете видеть, мы используем Spring Data Pagination.
сейчасвплоть до проблемы.
для отображения данных, на внешней стороне мы используем jQuery Datatable и HTML.
внешний код на стороне HTML выглядит следующим образом:
<div class="col-xs-12">
<div class="box box-danger">
<div class="box-body">
<table id="tnTable" class="table table-bordered table-striped">
<thead>
<tr>
<th>P1</th>
<th>P2</th>
<th>P3</th>
<th>P4</th>
<th>P5</th>
<
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
javascript code:
_initTable: function () {
var self = this;
_table = $("#tnTable").DataTable({
deferLoading: 0,
serverSide: true,
pageLength: 25,
autoWidth: false,
searching: false,
ajax: {
"url": "/request/ajax",
"data": function(data) {
data.p1 = $('#filter1').val();
data.p2 = $('#filter2').val();
data.p3 = $('#filter3').val();
data.p4 = $('#filter4').val();
}
},
columns : [
{ data: 'p1', orderable: false},
{ data: 'p2', orderable: false},
{ data: 'p3', orderable: false},
{ data: 'p4', orderable: false},
{ data: 'p5', orderable: false},
{ data: 'p6', orderable: false},
{ data: 'p7'}
],
order: [[ 6, "desc" ]],
drawCallback: function(settings) {
$.unblockUI();
}
});
контроллер на бэкэнд-коде:
@RequestMapping(value = ["/ajax"], method = [RequestMethod.GET])
fun ajax(request: HttpServletRequest): DataTableModel {
// begin filter request
val p1 = request.getParameter("p1")
val p2 = request.getParameter("p2")
val p3 = request.getParameter("p3")
val p4 = request.getParameter("p4")
// end filter request
val pageSize = Integer.valueOf(request.getParameter("length"))
val page = Integer.valueOf(request.getParameter("start")) / pageSize
var sortBy = "p1"
val order = request.getParameter("order[0][dir]")
when (Integer.valueOf(request.getParameter("order[0][column]"))) {
0 -> sortBy = "t1.p1"
6 -> sortBy = "t4.p6"
}
val pageable = PageRequest.of(page, pageSize, if (order.equals("asc", ignoreCase = true)) Sort.Direction.ASC else Sort.Direction.DESC, sortBy)
val data = service.finder(
p1,
p2,
p3,
p4,
)
val modelList: MutableList<SomeModel> = ArrayList()
val draw = Integer.valueOf(request.getParameter("draw"))
for (o in data) {
val model = SomeModel(0[0].toString(), 0[1].toString(), (etc..))
modelList.add(model)
}
return DataTableModel(draw, data.totalElements, data.totalElements.toInt(), data)
}
service
слой просто проходит через запрос к уровню хранилища, поэтому я подумал, что его код нездесь неважно.
оглядываясь на код, по частям javascript ясно, что индекс столбца с номером 6 был отправлен в качестве значения порядка, можно предположить, что это значение должно быть сопоставлено с таблицей t4 столбца.p6.
, поэтому мы предполагаем, что это будет переведено с помощью гибернации и сопоставленной корреляции с предварительно созданным запросом, поскольку мы добавили префикс для упорядочивания деталей здесь:
when (Integer.valueOf(request.getParameter("order[0][column]"))) {
0 -> sortBy = "t1.p1"
6 -> sortBy = "t4.p6"
}
, но чтослучилось здесь, мы получилиследующая ошибка из Hibernate:
org.hibernate.QueryException: could not resolve property: t4.p6 of: com.example.domain.Model1
затем мы попытались переименовать передаваемое значение порядка следующим образом:
when (Integer.valueOf(request.getParameter("order[0][column]"))) {
0 -> sortBy = "p1"
6 -> sortBy = "p6"
}
без удачи.
и так посленекоторые копания об ошибке, из того, что мы понимаем здесь, это попытка перехода в спящий режим для сопоставления значения порядка поля p6 , которое должно быть членом поля класса Model4 , с классом Model1, которого там нет из-за появления порядка выбора здесь, в части внутреннего хранилища, Model1 находится в первом списке:
"from Model1 t1, " +
" Model2 t2, " +
" Model3 t3, " +
" Model4 t4 " +
, потому что, однако, мы играем с частью поля заказа на стороне контроллера, из каждого полячлен за пределами Model1
, он просто выдает ту же ошибку.
НО , если мы изменим внешний вид порядка в части хранилища бэкэнда без изменений по сравнению с другими частями предыдущего кода, как это:
"from Model4 t4, " +
" Model2 t2, " +
" Model3 t3, " +
" Model1 t1 " +
Нет ошибок.он просто сопоставлен правильно, поэтому из-за этих обстоятельств появления порядка упорядочения таблиц в запросе выбора должны быть составлены так, чтобы соответствовать элементу значения порядка, который сопоставляется с той таблицей, впервые появившейся в операторе выбора таблицы.
мы имеемуже пытался использовать необработанный запрос в качестве замены для стиля HQL, но, насколько мы можем судить, ошибка и проблема остаются.
Это известная проблема?Как я могу преодолеть это, если это возможно?
Любой указатель высоко ценится, спасибо.