0

I have an application with two entities that have a bidirectional one to many relationship. Owners and Bicycles.

So getting the owners via curl will give

[
    {"id":1,
    "userName":"user1",
    "bicycles":
        [
            {
                "id":1,
                "make":"dawes",
                "model":"civic",
                "owner":1
            }
        ]
    },
    {"id":2,
    "userName":"user2",
    "bicycles":
        [
            {
                "id":2,
                "make":"whyte",
                "model":"montpellier",
                "owner":2
            }
            ,{
                "id":4,
                "make":"dahon",
                "model":"tern A7",
                "owner":2
            }
        ]
    } ]

which is fine.

If I create a template which loops in a table,

<table>
    <tr th:each="owner : ${owners}">
      <td th:text="${owner.userName}"></td>
      <td th:text="${owner.bicycles[0].make}"
          th:if="${#lists.size(owner.bicycles)} > 0">"</td>
      <td th:text="${owner.bicycles[0].model}"
          th:if="${#lists.size(owner.bicycles)} > 0"></td> 
    </tr>
  </table>

then I get the expected result in the browser. I realise the above is awful code but I am just interested in getting thymeleaf to work at the moment.

But if I do the following code

<table>
    <tr th:each="owner : ${owners}">
      <td th:text="${owner.userName}"></td>
      <tr th:each="bike : ${owner.bicycles}">
          <td th:text="${bike.make}"></td>
          <td th:text="${bike.model}"></td>  
      </tr>  
    </tr>
  </table>

then I get the following console error

nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "owner.bicycles" (template: "nutsthymeleaf" - line 23, col 15)] with root cause

org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'bicycles' cannot be found on null

What I find confusing is that owner.bicycle[index] works. It shows make and model. Yet owner.bicycles appears to be a null field according to the error.

So obviously I am doing something wrong ….

5
  • 1
    From my point of view also the first solution should give you a Property or field 'bicycles' cannot be found on null exception. Just tried it with an example. Check if bicycles is really not null. Commented Jun 24, 2019 at 13:58
  • Is that the actual code? The error message is not saying that bicycles doesn't exist, but rather that ${owner} is null, and so it can't get a property of a null object. Are you sure that you didn't accidentally close the loop and ${owner} is out of scope? Commented Jun 24, 2019 at 14:49
  • @Metroids - I can't see how it goes out of scope. Owner is supposed to be valid to all child tags. Hopefully that includes another each. This has proved valid in other stackoverflow questions. I accept that it is saying owner is null. Is <tr> within a <tr> legal? Commented Jun 24, 2019 at 16:07
  • Well, typically you'd do that with a <th:block> rather than nested <tr>s, but it should work either way. I'm just saying that the error you are getting can't be explained by the code you have (as far as i can tell). Commented Jun 24, 2019 at 22:22
  • just before you do return can yo debug to see how the owners attribute that you add on model looks like Commented Jun 25, 2019 at 14:32

3 Answers 3

1

So I found this

Thymeleaf: Getting Property or field cannot be found on null. Iteration of list inside a list

and that has stopped SpelException.

Having played around with it, it does not need 3 levels but just two. The problem arises if a th:each is nested within a th:each. The second th:each has to be in a th:block (or possibly div).

Sign up to request clarification or add additional context in comments.

Comments

0

Try if for check bicycles is null or not

<table>
    <tr th:each="owner : ${owners}">
      <td th:text="${owner.userName}"></td>
      <tr th:if={owner.bicycles != null} th:each="bike : ${owner.bicycles}">
          <td th:text="${bike.make}"></td>
          <td th:text="${bike.model}"></td>  
      </tr>  
    </tr>
</table>

1 Comment

Same error but slightly different. Exception evaluating SpringEL expression: "owner.bicycles" (template: "nutsthymeleaf" - line 23, col 49) org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "owner.bicycles" (template: "nutsthymeleaf" - line 23, col 49) And the code is <tr th:if="${owner.bicycles} != null" th:each="bike : ${owner.bicycles}"> So, it seems to accept owner.bicycles in the if but not in the each. And, of course, it accepts owner.bicycles[index].field in earlier code and when finding the length of the list.
0

The problem seems to be that you are trying to generate invalid HTML by nesting table row <tr> elements.

To generate the HTML you want, you should use the syntethic th:block tag , which allows you to generate the cells for each bike.

<table>
    <tr th:each="owner : ${owners}">
      <td th:text="${owner.userName}"></td>
      <th:block th:each="bike : ${owner.bicycles}">
          <td th:text="${bike.make}"></td>
          <td th:text="${bike.model}"></td>  
      </th:block>  
    </tr>
  </table>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.