0

I have an old system (java8 jee7 glassfish5 spring5) that includes ejb and web tiers. I recently moved it to new system (java17 jee10 glassfish7 spring6). After all coding and configuration changes I finally make most of it works, except for propagating jpa validation result to web tier. Here is my coding. In an entity I have

@Entity
public class Student {
...
@NotNull
private String name;
@Max(20)
private int age;

In the old system I have spring's dispatcher-servlet.xml

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename" value="/WEB-INF/messages" />
</bean>

In the new system I use WebConfig class instead

@Bean
public MessageSource messageSource() {
    ReloadableResourceBundleMessageSource source = new ReloadableResourceBundleMessageSource();
    source.setBasename("/WEB-INF/messages");
    source.setDefaultEncoding("UTF-8");
    return source;
}

and added this to the web.xml

<init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>test.config.WebConfig</param-value>
</init-param>

I've checked that messages.properties is under /WEB-INF/ in the war file, and contains

NotNull.studentForm.name = must not be blank
Max.studentForm.age = must not be older than {value}
typeMismatch.studentForm.age = must be numeric

In the spring controller

@Controller
public class StudentMaint {
....
@RequestMapping(value = "/StudentMaintEdit.htm")
public String edit(@ModelAttribute("studentForm") @Valid StudentForm form,
        BindingResult result, Map model, HttpServletRequest request) throws Exception {
    if (result.hasErrors()) {
        form.setMode("show");
        return "StudentMaint";
    }
    ....... (no validation coding here)
    studentFacade.edit(student);     (no try/catch for any exception here)

The StudentFacade also doesn't have any validation related coding

In StudentForm

@Component
public class StudentForm {
....
@Valid
private String name;
@Valid
private int age;

The only difference between old and new system is the use of config class instead of xml. Other validation related coding have no change at all. In the old system validation error messages are correctly set by controller and showed through the jsp: name will have must not be blank and age will have must be numeric or must be less than or equal to 20 (note: the last one is not from messages.properties). But in the new system, only the first two violations are showed correctly, the last one causes constraints violation exception and shows the stack trace. My understanding is the first two are spring validation at the web tier while the last one is jpa validation at the ejb tier. But somehow in the old system the jpa violation can be propagated to the web tier with the default message must be less than or equal to 20 while in the new system it didn't. What have I missed?

The old system was built with ant library and the new one with maven which may not be relevant. I've also added a catcher in the controller to catch the violation

@ExceptionHandler(ConstraintViolationException.class)
public String handleConstraintViolation(ConstraintViolationException ex,
        Model model, HttpServletRequest request) {
    Set<ConstraintViolation<?>> violations = ex.getConstraintViolations();
    List<String> errors = new ArrayList<>();
    for (ConstraintViolation<?> violation : violations) {
        ConstraintDescriptor des = violation.getConstraintDescriptor();
        Annotation atn = des.getAnnotation();
        log.info("atn = " + atn.toString());
        log.info("msg = " + violation.getMessage());
        errors.add(violation.getMessage());
    }

I got

atn = @jakarta.validation.constraints.Max(message="{jakarta.validation.constraints.Max.message}", payload={}, groups={}, value=20L)
msg = must be less than or equal to 20

so I added to messages.properties

jakarta.validation.constraints.Max.message = must be <= {value}

but still doesn't work. Please help.

0

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.