Ошибка StackOverflow при использовании рекурсивного макроса в freemarker

У меня есть требование перебрать большое количество записей, используя итератор списка сущностей в Freemarker. Но при использовании рекурсивного макроса он выдает ошибку StackOverflow, когда достигает только 1000 записей. Ниже приведен фрагмент кода для того же.

<#macro recurseTest value>
  ${value.partyId!}
  ${value.firstName!}
  ${value.lastName!}
  <#local tmp = eli.next()!/>
  <#if tmp?has_content>
     <@recurseTest tmp/>
  </#if>
</#macro>
<#assign eli = EntityQuery.use(delegator).from("Person").queryIterator()/>
<br>
<@recurseTest eli.next()!/>
${eli.close()}

person Sonal Patwari    schedule 26.03.2018    source источник
comment
Какая версия FreeMarker?   -  person ddekany    schedule 26.03.2018


Ответы (1)


Независимо от FreeMarker, обработка тысяч элементов с помощью рекурсии не является обычной практикой (за исключением некоторых функциональных языков, которые не имеют обычной конструкции циклов, но имеют оптимизацию хвостовой рекурсии). Попробуйте использовать #list. Если вы не можете получить List или Iterator из этого API запроса (но посмотрите на него, если можете), в крайнем случае вы можете сделать этот хак (бедняга do { ... } while (cond)):

<#list 1..100000000 as _>
  ...
  <#if !tmp?has_content><#break></#if>
</#list>

(При достаточно высоком параметре конфигурации incompatible_improvements FreeMarker вы можете написать <#list 1.. as _>, но я не знаю, что там установлено. Поэтому я указал какое-то произвольное большое число, которое в любом случае вызовет тайм-аут или нехватку памяти на практике.)

person ddekany    schedule 26.03.2018