I have a address entity like this:
@Entity
public class Address implements java.io.Serializable {
@Id @GeneratedValue(strategy = IDENTITY)
private Long id;
@Size(max = 100)
private String street;
@Size(max = 15)
private String nr;
@Field
@Size(min = 1, max = 20) @NotBlank
private String city;
}
This is part of several other entities. For one such entity the address is optional. I have a view where our users can edit the whole entity via several form inputs, including several address fields.
To be able to edit the address, I initialize the parent entity with an empty address entity.
Now the problem is: I don't want to persist an Address
on the entity when all address fields are empty. For that to work, I need to skip validation for the entity if (and only if) all fields of Address
are empty. How do I do that in the most elegant way?
What I'm currently doing is to skip bean validation altogether with <o:validateBean disabled="true" />
for the submit button, setting the address to null
if it comes out empty. But this sounds like a total hack as it disables all validation in all cases. How can I do better?
You can just use EL in disabled
attribute of <f:validateBean>
(and <o:validateBean>
). You can use EL to check if any of those fields have been filled. You can use binding
attribute to reference a component in EL. You can check if a field has been filled by checking the value of the request parameter associated with component's client ID.
Then, to disable bean validation on those fields when #{addressIsEmpty}
evaluates true
, it's easier to use <f:validateBean>
instead of <o:validateBean>
as the former can be used to wrap multiple input components.
So, all with all, this should do:
<c:set var="addressIsEmpty" value="#{empty param[street.clientId] and empty param[nr.clientId] and empty param[city.clientId]}" />
<f:validateBean disabled="#{addressIsEmpty}">
<h:inputText binding="#{street}" value="#{bean.address.street}" />
<h:inputText binding="#{nr}" value="#{bean.address.nr}" />
<h:inputText binding="#{city}" value="#{bean.address.city}" />
</f:validateBean>
The <o:validateBean>
is only easier to use if you intend to control it on a per-input or per-command basis.
Cross validation of multiple fields can be a tough issue. But in this situation it is not validation per se that bothers you in the first place but rather possibility to nullify some instance on some condition in your bean before you'd persist the entity.
The most straightforward way would be to mark all fields associated with Address
entity as required="false"
in your view not to care of fields being filled in (or just omit it as it's the default) and do all the checks of, and modifications to the placeholder in your action method, right before calling your EJB service. Like so:
public String save() {
//do some checks
if((entity.getAddress().getStreet() == null) && ...) {
//assign address to null
entity.setAddress(null);
}
entityService.persist(entity);
return "success";
}
来源:https://stackoverflow.com/questions/17492169/how-can-i-skip-bean-validation-if-all-fields-for-the-entity-are-empty