Получение ClassCastException: java.lang.String нельзя привести к java.lang.Boolean при сохранении карты.в базу данных - PullRequest
0 голосов
/ 14 мая 2019

Я использую Spring MVC и пытаюсь сохранить базовую анкету с ответами да / нет (истина / ложь) на Map<String, Boolean>, где клавишей String является "Q1", "Q2" соответственно.

На стороне контроллера он связывается должным образом, устанавливая соответствующие входные значения на карту, но когда объект сущности передается в службу для сохранения, возникает исключение ClassCastException с жалобой на то, что его нельзя сохранить.Тип базы данных (postgres) - логический.

Исключение

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean
    at org.hibernate.type.descriptor.java.BooleanTypeDescriptor.unwrap(BooleanTypeDescriptor.java:19) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.type.descriptor.sql.BooleanTypeDescriptor$1.doBind(BooleanTypeDescriptor.java:44) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:74) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:280) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:275) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:39) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.persister.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:903) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.persister.collection.BasicCollectionPersister.doUpdateRows(BasicCollectionPersister.java:231) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.persister.collection.AbstractCollectionPersister.updateRows(AbstractCollectionPersister.java:1728) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]

Сущность

@Entity
public class Questionnaire {
    private static final long serialVersionUID = 1L;
    public static final String[] SHORT_QUESTIONS = {"q1", "q2", "q3", "q4", "q5", "q6", "q7"};

    @ElementCollection(fetch=FetchType.LAZY)
    @MapKeyColumn(name="question")
    @Column(name="answer")
    private Map<String, Boolean> shortForm = new LinkedHashMap<>();

    // constructor, setters and getters here
}

Метод контроллера:

@PostMapping("/questionnaire/save/{id}")
public String save(@ModelAttribute @Valid Questionnaire questionnaire, BindingResult binder, RedirectAttributes redirectAttrs, Model model) {
    if (binder.hasErrors()) {
        model.addAttribute("messageDanger", messages.getMessage("general.save.failed", null, LocaleContextHolder.getLocale()));
        return "questionnaire/full";
    }

    // these all bind properly and return true or false accordingly
    log.debug("q1: " + questionnaire.getShortForm().get("q1"));
    log.debug("q2: " + questionnaire.getShortForm().get("q2"));
    log.debug("q3: " + questionnaire.getShortForm().get("q3"));
    log.debug("q4: " + questionnaire.getShortForm().get("q4"));
    log.debug("q5: " + questionnaire.getShortForm().get("q5"));
    log.debug("q6: " + questionnaire.getShortForm().get("q6"));

    // Exception occurs here during .save()
    questionnaireSvc.save(questionnaire);

    redirectAttrs.addFlashAttribute("message", messages.getMessage("general.save.success", null, LocaleContextHolder.getLocale()));
    return "redirect:/questionnaire/full/" + questionnaire.getId();
}

HTML (Thymeleaf)

<tr th:each="question : ${T(app.model.Questionnaire).SHORT_QUESTIONS}">
    <td headers="question-col" th:utext="#{questionnaire.short.__${question}__}"></td>
    <td headers="applicant-col">
    <div class="custom-control custom-radio">
        <input type="radio" th:field="*{shortForm[__${question}__]}" class="custom-control-input" required value="false" />
        <label class="custom-control-label" th:text="#{general.no}" th:for="${#ids.prev('shortForm__${question}__')}"></label>
    </div>
    <div class="custom-control custom-radio">
        <input type="radio" th:field="*{shortForm[__${question}__]}" class="custom-control-input" required value="true" />
        <label class="custom-control-label" th:text="#{general.yes}" th:for="${#ids.prev('shortForm__${question}__')}"></label>
    </div>
</td>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...