Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: Providing more detail in ConstraintViolation messages
PostPosted: Sun Feb 21, 2016 9:59 pm 
Newbie

Joined: Sun Feb 21, 2016 9:24 pm
Posts: 5
I'm trying to find a practical means of improving the detail in validation error messages. For simple objects (and object graphs) the validation messages can be made very descriptive by overriding the message for the various constraints.
For complex object graphs, particularly when value objects are used in multiple locations, this is no longer possible.

The constraint violations in a complex object might look like this:
  • "cast[0].actor: Actor is required"
  • "cast[2].character: Character name is required"
  • "cast[1].actor.lastName: Last Name is required"

(For the full example, please see https://gist.github.com/phaas/94b37d579b6eff9d1d60)

I would like to be able to present a list of only the error messages and have that be meaningful to the user. Unfortunately there appears to be no way to enhance the error message with additional details about the context where a constraint was violated.

In other situations, I've been able to access the property path and use that to control where error messages are displayed (i.e. map each violation to the corresponding UI element). This approach is very costly and complex to implement. It also doesn't work well for situations where there isn't a 1:1 mapping of violations to UI inputs (e.g. data is parsed from a file, validation result is emailed to user..)

I would like to hear from other users and developers if there are already existing ways of satisfying this use case.


I have thought of a couple of way of accommodating more informative messages, but the pluggable components of the Validation framework don't provide the hooks required to actually implement these ideas. I'll detail them in another post -- I don't want to presume a particular solution to this problem :)


Last edited by phaas on Mon Feb 22, 2016 12:27 am, edited 2 times in total.

Top
 Profile  
 
 Post subject: Re: Providing more detail / context in ConstraintViolationExcept
PostPosted: Sun Feb 21, 2016 10:24 pm 
Newbie

Joined: Sun Feb 21, 2016 9:24 pm
Posts: 5
The Hibernate implementation of the BeanValidation spec has already been enhanced to support EL expressions in validation messages. It would be convenient to be able to leverage this capability to provide the desired contextual information.

For example, a value object ("Actor") that's used in multiple locations could anticipate this by providing the additional context.
Code:
    public static class Actor {
        @NotEmpty.List({
                @NotEmpty(message = "First Name is required", groups = ActorValidation.class),
                @NotEmpty(message = "First Name is required for role \"${character}\"", groups = MovieValidation.class),
                @NotEmpty(message = "First Name is required for role \"${character}\" in movie \"${movieTitle}\"", groups = MovieListValidation.class)
        })
        public final String firstName;

        @NotEmpty.List({
                @NotEmpty(message = "Last Name is required", groups = ActorValidation.class),
                @NotEmpty(message = "Last Name is required for role \"${character}\"", groups = MovieValidation.class),
                @NotEmpty(message = "Last Name is required for role \"${character}\" in movie \"${movieTitle}\"", groups = MovieListValidation.class)
        })
        public final String lastName;

        public Actor(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }
    }


Full example: https://gist.github.com/phaas/94b37d579b6eff9d1d60#file-2-enhancedvalidationexample

In this example, I'm presuming that groups could be used to selectively enable or disable context-specific validations. I'm also imagining that the required EL variables "character" and "movieTitle" would be added to the validation context when the object graph is traversed. This could be done by annotating the relevant objects with an EL context variable provider that would be able to populate the expression variables using values of the current object being validated. These expression variables would need to be preserved / inherited as the validation descends to properties and nested objects.

Looking at the implementation of the validator framework however, this seems to break several fundamental assumptions made, which makes it not feasible to maintain such an enhancement other than as a "full fork" of the project (not something I'm at all interested in.)

I've also considered using the Path to describe the context of a constraint violation. If it was possible to access the "currentNode.object", "currentNode.parent.object" etc. in the EL expression, this could be used to extract information to describe the path to the user.
This option also seems to be actively discouraged not just by the information put in the EL context, but also by the Path interface, which seems to be lacking any way of looking 'up' the path (even though I'm pretty sure that the implementation does track this.)


Top
 Profile  
 
 Post subject: Re: Providing more detail / context in ConstraintViolationExcept
PostPosted: Sun Feb 21, 2016 10:41 pm 
Newbie

Joined: Sun Feb 21, 2016 9:24 pm
Posts: 5
I've also contemplated using the validation framework "as-is" and then rewriting the resulting ConstraintViolations:

path: "cast[2].character"
message : "Character name is required"
would be rewritten as: Movie "The Revenant" > Role[actor = "Tom Hardy", character = [blank] > Character name is required

Unfortunately I found that the path interface does not actually allow me to inspect the objects associated with the various nodes, I can only get a string representation of the path to the intermediate objects.
The rootBean and leafBeanInstance objects are accessible via the violation itself, but the intermediate objects don't appear to be recorded and could only be obtained by means of el-expression like reflection code using the string representation of the path.


Top
 Profile  
 
 Post subject: Re: Providing more detail / context in ConstraintViolationExcept
PostPosted: Mon Feb 22, 2016 12:18 am 
Newbie

Joined: Sun Feb 21, 2016 9:24 pm
Posts: 5
I've looked into the possibility of translating the path nodes into meaningful descriptions. I used the EL functionality to perform the translation, which works for the few limited cases that I tested.

https://gist.github.com/phaas/94b37d579 ... ancer-java

This process is able to translate these unhelpful messages
Code:
Last Name is required
Character name is required
Last Name is required
Actor is required
Actor is required
Character name is required


into something potentially more meaningful
Code:
Movie "The Revenant" > Role "Captain Andrew Henry", Actor "Domhnall [blank]" > Last Name is required
Movie "Bridge of Spies" > Role "[missing character name]", Actor "Tom Hanks" > Character name is required
Movie "Bridge of Spies" > Role "Agent Blasco", Actor "Domenick [blank]" > Last Name is required
Movie "The Revenant" > Role "Hugh Glass", Actor "[missing]" > Actor is required
Movie "Bridge of Spies" > Role "Rudolf Abel", Actor "[missing]" > Actor is required
Movie "The Revenant" > Role "[missing character name]", Actor "Tom Hardy" > Character name is required


This may be an acceptable workaround for the actual situation that I'm dealing with. I'm not really happy with the reliance on EL-interpretation though. I'd feel much better about this approach if Node's in a Path exposed the current Bean in some way.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.