Всякий раз, когда имеется малейшая вероятность того, что данная строка не содержит Integer, вам придется обрабатывать этот специальный случай. К сожалению, стандартные Java-методы Integer::parseInt
и Integer::valueOf
выдают NumberFormatException
, чтобы сигнализировать об этом специальном случае. Таким образом, вы должны использовать исключения для управления потоком, которые обычно считаются плохим стилем кодирования.
На мой взгляд, этот особый случай должен быть обработан возвратом Optional<Integer>
. Поскольку Java не предлагает такой метод, я использую следующую оболочку:
private Optional<Integer> tryParseInteger(String string) {
try {
return Optional.of(Integer.valueOf(string));
} catch (NumberFormatException e) {
return Optional.empty();
}
}
Использование:
// prints 1234
System.out.println(tryParseInteger("1234").orElse(-1));
// prints -1
System.out.println(tryParseInteger("foobar").orElse(-1));
Хотя это все еще использует исключения для управления потоком внутри, использование код становится очень чистым.
В представлении entitymanager уже закрыт, и поэтому элементы в ваших коллекциях не могут получить там свойства. Код, который вы написали в контроллере, не инициализирует элементы в коллекции (это коллекция LAZY), но инициализируется только коллекция (а не элементы внутри нее).
Либо заставить entitymanager оставаться откройте конфигурацию OpenEntityManagerInViewFilter
в вашей веб-конфигурации.
Или измените код контроллера, чтобы включить вызов Hibernate.initialize
для правильной инициализации вашей коллекции.
@Transactional
public void doSomething(String partId, Map<String, Object> model) {
AssessmentPart assessmentPart = //laods a part with entity manager
Assessment assessment = assessmentPart.getAssessment(); //Getting the assessments
Hibernate.initialize(assesment.getAssesmentParts()); // Init collection
model.put("assessmentParts", assessment.getAssessmentParts()); //adding all assessments parts into spring model map
}
Либо это или создать пользовательский запрос, который заставляет загружать сборку.
Загрузка оценкиПарт из EntityManager будет загружать оценку @ManyToOne(fetch = FetchType.EAGER)
AssessmentPart assessmentPart = //laods a part with entity manager
Assessment assessment = assessmentPart.getAssessment();
Попытка извлечь оценки из оценки не будет работать, так как это не @OneToMany(fetch = FetchType.LAZY)
, а сеанс уже закрыт
model.put("assessmentParts", assessment.getAssessmentParts());
Получить список оценок по оценке от EntityManager в новом методе должен решить проблему.
Измените
model.put("assessmentParts", assessment.getAssessmentParts());
на
Hibernate.initialize(assessment.getAssessmentParts());
, чтобы инициализировать вашу коллекцию.
Вызов метода assessment.getAssessmentParts()
не инициализирует вашу коллекцию. Этот вызов метода просто вернет вам обертку коллекции и эту оболочку, которую вам нужно передать методу Hibernate.initialize
для ручной инициализации.
EDIT:
С помощью JPA вы можете получить AssessmentParts
вместе с Assessment
(где необходимо) с использованием JPK Fetch Joins, переопределяя поведение по умолчанию:
SELECT a FROM Assessment asmt LEFT JOIN FETCH asmt.assessmentParts WHERE asmt.id = :id