Search code examples
javaspringfreemarker

Apache Freemarker NonHashException: Expected a hash, but this has evaluated to a string


I want to build a search site with Spring and Apache Freemarker. I have a form, that contains some data about a previous search, it's stored in a simple data class, like so:

import lombok.Data;

@Data
public class TicketSearchForm {
    private String status = "ALL";
    
    //More fields...
}

I wish to use that data, that is passed through the Model of my Spring Request, like so, to determine which value is the default on a select:

<select name="status" id="status" class="form-control select2">
                                        <option value="ALL" <#if previousSearch.getStatus().equals("ALL")>selected</#if>>Alle anzeigen</option>
                                        <option value="OPEN" <#if previousSearch.status.equals("OPEN")>selected</#if>>Offen</option>
                                        <option value="DONE" <#if previousSearch.status.equals("DONE")>selected</#if>>Geschlossen</option>
                                    </select>

However, this is rewarded with the error

Error executing FreeMarker template

freemarker.core.NonHashException: For "." left-hand operand: Expected a hash, but this has evaluated to a string (wrapper: f.t.SimpleScalar):
==> previousSearch.status  [in template "ticket/search.ftlh" at line 22, column 66]

----
FTL stack trace ("~" means nesting-related):
    - Failed at: #if previousSearch.status.equals("ALL")  [in template "ticket/search.ftlh" in macro "page_body" at line 22, column 61]
    - Reached through: @page_body  [in template "base.ftlh" at line 86, column 9]
    - Reached through: #include "/base.ftlh"  [in template "ticket/search.ftlh" at line 1, column 1]
----

The previousSearch does contain all the data, I can display it as a String on the site, but I can't seem to access any of it's properties. Why is that, and how can I access them? I'd rather not pass all of the values that I need as separate booleans through the Model, that just seems wrong to me.


Solution

  • The problem lied in the .equals()

    I got confused because of the java context of my application. Freemarker treats Strings differently than Java, and the way to go is to use == to compare Strings.