I'm looking for a way to map every object that is null to null instead of "org.dozer.MappingException: Source object must not be null" error.
I don't want to enumerate every class and say that null maps to null, I want to specify this as a general rule.
This one is a generic exception saying that you should not pass null object as a top level bean to mapper.map(src, dest) method. So putting guard check before invoking Dozer should help.
if (src == null) return null;
return dozer.map(src, dest);
In addition, 'map-null' policy is enabled by default, but it applies only to elements inside the bean you want to map (not top-level). So Dozer will properly map 'user.id' if it is null value. In the next version there will be a possibility to apply 'map-null' on global level as well without specifying each class. However this would only help to disable null mapping, since it is enabled by default.
Related
We are switching from using X509V3CertificateGenerator to the new X509v3CertificateBuilder class. It insists on having an X500Name object for the subject, and throws an NPE if it's null. In our case, we want a null subject and will be using the SubjectAlternativeName (marked critical) as an alternative, which the specification allows.
How do we make an empty X500Name object to pass in to the builder's constructor?
Found it.
new X500Name(new RDN[0])
I want to know how can I express one object is null on the left hand side when I use drools rule engine?
And anybody can tell me how to use the drools keyword "not" and so on.Thank you!
You can call not in when clause to check for null objects:
rule "somerule"
no-loop
when not AnObject()
then
// rule body when AnObject is null
end;
Drools is built on top of Java, so there is an instance of the object (which may or may not have null properties) or there is not. If the object is a 'fact' in working memory, then it is not null and your LHS should instead be determining whether it exists:
exists MyObject()
not exists MyObject()
However if you are trying to find facts with null properties, you can do this:
obj: MyObject(myProperty == null)
I have a TextField which overrides it's getConverter method to add a Joda time converter instead:
new TextField<P>(id) {
#Override
public <P> IConverter<P> getConverter(Class<P> type) {
return (IConverter<P>) new JodaDateTimeConverter();
}
};
The converter returns null if input was invalid. However, I want to be able to flag this field as required, and I don't know how to do that:
textField.isRequired(true) does not work, because required checks are done before conversion. This doesn't work for non-empty but invalid inputs.
textField.add(.. some validator ..) does not work because no validator is called if the converter returned null.
I really don't see an approach to flag my date fields as required. Do you know how to do that? Probably my approach is not suited at all?
If you add an INullAcceptingValidator instead of a regular one, it will be called for null values too.
Subclassing your validators to return true on validateOnNullValue() might be helpfull too.
From the JavaDocs:
Indicates whether or not to validate the value if it is null. It is
usually desirable to skip validation if the value is null, unless we
want to make sure the value is in fact null (a rare use case).
Validators that extend this and wish to ensure the value is null
should override this method and return true.
It's one of the parameters supplied to the CreateMetadata method (which you override if extending metadata support).
ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor, <<--THIS ONE
Type modelType,
string propertyName)
I had assumed that it allowed you to access the model object itself (e.g. for setting metadata based on model values), however when I try to use it to cast to my model object I just get null.
Entity ent = (Entity)modelAccessor(); // = Null
If I've missunderstood, can anyone explain what it's purpose is? Or alternatively, how to properly use it?
Thanks
We originally had that as "object model", rather than "Func modelAccessor". We had to change it late in MVC 2's ship cycle.
The purpose is to delay retrieving the actual value of the model until such point as you know you're going to need it (that is, until you call ModelMetadata.Model).
The problem it solves is actually a rather esoteric one related to model binding against a LINQ to SQL class that has a foreign key reference in it. The problem is, if you've retrieved the child object which is represented by a foreign key relationship (which usually means a delay load of that object), then you're no longer allowed to choose a new child object by setting the foreign key ID property. It's very common to model bind the foreign key ID (and not the whole foreign key entity) when model binding, but if we'd retrieved the foreign key entity object (for the purposes of populating the ModelMetadata class) then that binding would no longer be legal, and actually throw an exception. Since ModelMetadata is used for both directions of models -- inbound, via model binding, and outbound, via HTML generation -- we needed to introduce the layer of indirection to protect your ability to use it in both scenarios without disrupting LINQ to SQL's rules.
The modelAccessor parameter does not point to an instance of the object, but rather it is a function that will access some attribute of your object. The Func "encapsulates a method that has no parameters and returns a value of the type specified by the TResult parameter." For example, if we have following class:
public class Bar(){
[DisplayName("I am Foo.")]
public string Foo{get;}
}
When the CreateMetaData is called, it will be to create meta data for the Foo property and the modelAccessor will be a function that returns the value of Foo.
I did a little digging and found a way to get to the instance of the object, but it requires using reflection. You can do the following to get the Bar class in my example:
if (modelAccessor != null)
{
//Use reflection to get the private field that holds the Bar object.
FieldInfo container = modelAccessor.Target.GetType().GetField("container");
//Invoke field on the modelAccessor target to get the instance of the Bar object.
Bar myObject = (Bar)container.GetValue(modelAccessor.Target);
}
I've only run this against a simple test case, so your mileage may vary, but hopefully this will help clarify what is going on.
I'm trying to integrate NHibernate.Validator with ASP.NET MVC client side validations, and the only problem I found is that I simply can't convert the non-interpolated message to a human-readable one. I thought this would be an easy task, but turned out to be the hardest part of the client-side validation. The main problem is that because it's not server-side, I actually only need the validation attributes that are being used, and I don't actually have an instance or anything else at hand.
Here are some excerpts from what I've been already trying:
// Get the the default Message Interpolator from the Engine
IMessageInterpolator interp = _engine.Interpolator;
if (interp == null)
{
// It is null?? Oh, try to create a new one
interp = new NHibernate.Validator.Interpolator.DefaultMessageInterpolator();
}
// We need an instance of the object that needs to be validated, se we have to create one
object instance = Activator.CreateInstance(Metadata.ContainerType);
// we enumerate all attributes of the property. For example we have found a PatternAttribute
var a = attr as PatternAttribute;
// it seems that the default message interpolator doesn't work, unless initialized
if (interp is NHibernate.Validator.Interpolator.DefaultMessageInterpolator)
{
(interp as NHibernate.Validator.Interpolator.DefaultMessageInterpolator).Initialize(a);
}
// but even after it is initialized the following will throw a NullReferenceException, although all of the parameters are specified, and they are not null (except for the properties of the instance, which are all null, but this can't be changed)
var message = interp.Interpolate(new InterpolationInfo(Metadata.ContainerType, instance, PropertyName, a, interp, a.Message));
I know that the above is a fairly complex code for a seemingly simple question, but I'm still stuck without solution. Is there any way to get the interpolated string out of NHValidator?
Ok, so I know this is an old question, but I stumbled across this when trying to do the same thing, and it helped me get started - so I thought I would provide an answer.
I think the code in the question was on the right track but there are a couple of problems. The interpolator was not completely initialised with the ResourceManager and Culture details, and it doesn't seem to allow for the fact that you can only have one DefaultMessageInterpolator per validation attribute. Also, you don't need an instance of the object you are validating to get an interpolated message.
In the code in the question, where you are initialising the interpolator with the attribute value, you also need to initialise the interpolator with details of the ResourceManager to be used.
This can be done using the overloaded Initialize method on DefaultMessageInterpolator which has the following signature:
public void Initialize(ResourceManager messageBundle,
ResourceManager defaultMessageBundle,
CultureInfo culture)
The first parameter is a user-defined ResourceManager in case you want to use your own resource file for error messages, you can pass a null if you just want to use the default ResouceManager, the second parameter is the default ResourceManager - you can pass
new ResourceManager(
NHibernate.Validator.Cfg.Environment.BaseNameOfMessageResource,
Assembly.GetExecutingAssembly());
for this, the last parameter is the culture to use, (NHibernate.Validator comes with resource files with validation messages in several languages) - if you pass a null in to this it will just use CultureInfo.CurrentCulture
Lastly, you can only have one DefaultMessageInterpolator per attribute, so you will need to create a new DefaultMessageInterpolator for each validation attribute. You could make use of the DefaultMessageInterpolatorAggregator to handle this, or just roll your own.
I hope this helps someone.
Thanks for your help all--I'd upvote if I could. I just wanted to add that in addition to the first Initialize call on the DefaultMessageInterpolator that Stank illustrates, I also had to make a second different Initialize call to fully initialize it (I was getting some Null Reference Exceptions using only the first call). My code is as follows:
string interpolatedMessage = "";
DefaultMessageInterpolator interpolator = new DefaultMessageInterpolator();
interpolator.Initialize(null,
new ResourceManager(
NHibernate.Validator.Cfg.Environment.BaseNameOfMessageResource,
Assembly.Load("NHibernate.Validator")),
CultureInfo.CurrentCulture);
interpolator.Initialize(attribute as Attribute);
if (attribute is IValidator && attribute is IRuleArgs)
{
IValidator validator = attribute as IValidator;
IRuleArgs ruleArgs = attribute as IRuleArgs;
InterpolationInfo interpolationInfo = new InterpolationInfo(
validatableType,
null,
propertyName,
validator,
interpolator,
ruleArgs.Message);
interpolatedMessage = interpolator.Interpolate(interpolationInfo);
}