How to ask BeanUtils to ignore null values - java

Using Commons beanUtils I would like to know how to ask any converter say the Dateconverter to ignore null values and use null as default. As an example consider a public class,
public class X {
private Date date1;
private String string1;
//add public getters and setters
}
and my convertertest as,
public class Apache {
#Test
public void testSimple() throws Exception {
X x1 = new X(), x2 = new X();
x1.setString1("X");
x1.setDate1(null);
org.apache.commons.beanutils.BeanUtils.copyProperties(x2, x1);
//throws ConversionException
System.out.println(x2.getString1());
System.out.println(x2.getDate1());
}
}
The above throws a NPE since the date happens to be null. This looks a very primitive scenario to me which should be handled by default (as in, I would expect x2 to have null value for date1). The doco tells me that I can ask the converter to do this. Can someone point me as to the best way for doing this ?
I dont want to get hold of the Converter and isUseDefault() to be true because then I have to do it for all Date, Enum and many other converters !

Apparently it looks like, there is a way to tell the ConvertUtils to not throw exceptions on null values which is achieved by calling
BeanUtilsBean.getInstance().getConvertUtils().register(false, false, 0);

The best solution is update to BeanUtils 1.9.0, since this problem is fixed as you can see here https://issues.apache.org/jira/browse/BEANUTILS-454

Maybe a little late but looks that you can register a DateConverter
https://issues.apache.org/jira/browse/BEANUTILS-387

I recently ran into this issue and just converted my variable to a string to avoid this error and converted it back to a date when needed. Not the most elegant solution, but for simplicity and to avoid problems like this, it's a viable solution. The other caveat was that BeanUtils would fire off it's methods before my classes would load, so I opted for this rather than a more complicated solution to the problem using custom classloaders.
By the way, prior to verion 1.8.0, BeanUtils itself would ignore these null values.
See this link:
No value specified for 'Date' when the field is a java.util.Date with a null value for a detailed explanation.

I am somewhat amazed that such a simple case as setting a null value in a bean, like this:
BeanUtils.setProperty(pojo, "date", null);
causes crashing behavior, as described above.
For what it's worth, here is my workaround:
import org.apache.commons.beanutils.BeanMap;
BeanMap beanMap = new BeanMap(pojo);
Method writeMethod = beanMap.getWriteMethod("date");
writeMethod.invoke(pojo, null);

Related

Mockito control output returned based off input

I have issue where when I use Java parallelStream instead of stream my tests fail. This happens because I am returning Mock objects in a strict order rather than controlling Mock objects returned based on input.
The following is my current code used to return mocks objects:
when(myOperation.getSomething(any(String.class)))
.thenAnswer(AdditionalAnswers.returnsElementsOf(aListOfThings)));
How can I concisely control the return value based off the argument I am passing to "getSomething"?
You can do something like that:
when(myOperation.getSomething(any(String.class))).thenAnswer(new Answer<SomeThing>() {
#Override
public SomeThing answer(final InvocationOnMock invocation) throws Throwable {
// HERE ====> use invocation.getArguments()
return new SomeThing();
}
});
Here the answer return a SomeThing instance, you will need to adjust to your needs
Some reading:
Java 8 custom answer support
doAnswer documentation
InvocationOnMock javadoc
Instead of using an Answer, you can just iterate across your values and set up specific stubs for each one. Unlike with an Answer, you have to be able to predict all values for which you're stubbed, but for your particular case here it sounds like that might not be a problem.
for (int i = 0; i < aListOfThings.size(); i++) {
when(myOperation.getSomething(aListOfKeys.get(i)))
.thenReturn(aListOfThings.get(i));
}

EclassImpl setEPackage()

I need to work with some emf code without having any clue how it works. The code uses EcoreUtil.copy(...) to clone the classes. I added a EClass to the class i created like this:
EClassImpl c = (EClassImpl)EcoreFactory.eINSTANCE.createEClass();
System.out.println(c.getEPackage().getEFactoryInstance());
And also overrode eStaticClass() like this:
#Override
protected EClass eStaticClass() {
EClassImpl c = (EClassImpl)EcoreFactory.eINSTANCE.createEClass();
return c;
}
Now i have the problem, that the copy routine tries to use:
eClass.getEPackage().getEFactoryInstance().create(eClass);
Which returns a nullpointer exception, since getEPackage() returns null. Unfortunatly there seems to be no setter for the EPackage, so how do i set it?
Had the same problem. See in http://emfjson.org/docs/ how they use the API as an example.
samplePackage
.getEClassifiers()
.add(userClass);
This will add the class to the package and vice versa.
I managed to solve it myself, here is my solution in case anybody else ever comes across this:
EPackageImpl epi = (EPackageImpl)EcoreFactory.eINSTANCE.createEPackage();
c.eBasicSetContainer(epi, EcorePackage.ECLASSIFIER__EPACKAGE, null);

Append type level validation error message to specific field

I've got a simple class which get's validated using the boolean isValid() method, which works and of course the error message is at class/type level.
Here's my simple class:
public class NewPasswordDTO {
#NotNull
public String password;
#NotNull
public String confirmation;
#AssertTrue(message="Passwords must match.")
protected boolean isValid() {
return password.equals(confirmation);
}
}
But what I really want is something like that:
public class NewPasswordDTO {
#NotNull
#Equals("confirmation", message="...")
public String password;
#NotNull
public String confirmation;
}
So the error message would be set at field level and not at class/type level.
Is this possible somehow? Maybe using a custom Validator for that class?
Thanks in advance!
SOLUTION:
Thanks to Gunnar! I've just came up with a nice, universal solution :-). I simply used (means copy & paste) the code from Hibernates #ScriptAssert and ScriptAssertValidator and modified it slightly:
#ScriptAssert:
Add new String field(). (this is where the error message gets appended)
ScriptAssertValidator:
Inside the initialize method, make sure to also save the fieldName and message properties, because we need to access them in the next step
Add this snippet at the bottom of isValid method:
context.buildConstraintViolationWithTemplate(errorMessage)
.addPropertyNode(fieldName).addConstraintViolation();
Also add context.disableDefaultConstraintViolation(); somewhere inside the isValid method to not generate the default error message which else would get appended at class level.
And that's it. Now I can use it like that:
#FieldScriptAssert(lang="javascript", script="_this.password.equals(_this.confirmation)", field="password", message="...")
public class NewPasswordDTO { ... }
You either could use the #ScriptAssert constraint on the class (note that a constraint should always be side-effect free, so it's not a good idea to alter the state of the validated bean; instead you should just check whether the two fieldss match) or you implement a custom class-level constraint.
The latter also allows to point to a custom property path for the constraint violation, which it allows to mark the "confirmation" property as erroneous instead of the complete class.
Simple answer : It is not (unless you implement it) :http://docs.oracle.com/javaee/6/api/javax/validation/constraints/package-summary.html shows all annotation constraints.
Of course you could inject your string as a resource in your class by #producer and so on (which recently is discussed to be removed in jdk8), but you could not use this value for your assert. In reply to the comment:
This was asuming that the nature is a constant string which you would like to use as a string resource.And then of course it is possible to write your own class based on java.lang.string with a #Producer which is then #Inject - able. Though it is certainly not the way I personally would deal with constant strings.
If you’re using the Spring Framework, then as an alternative to the #ScriptAssert using a JSR 223 scripting, you can use the #SpELAssert that uses the Spring Expression Language (SpEL). The advantage is that it doesn’t need any JSR 223 compliant scripting engine which may not be available on some environments. See this answer for more information.

Saving values of different types, with methods

I was to save some configuration values. :)
These values are might be defined in a xml file and might be of the types String, boolean, String[], ...
or others. These values might be defined in a xml file.
Is there a best practise way to save these values, together with their tagname in the xml file and a default value.
I want to clean up some ultra bad legacy code, where things look like this:
public static final String VIEWCOOKIE_MAXLENGTH_VALUENAME = "view_cookie_max_length";
public static final int VIEWCOOKIE_MAXLENGTH_DEFAULT = 512;
public static int viewCookie_maxLength = VIEWCOOKIE_MAXLENGTH_DEFAULT;
Integer temInt = basic.getTimedBaseIntegerValue(basic.c_adclear_section, null,
CookieValues.VIEWCOOKIE_MAXLENGTH_VALUENAME,
CookieValues.VIEWCOOKIE_MAXLENGTH_DEFAULT, currentTime);
if (firstLoad || basic.checkParamChanged(0,CookieValues.VIEWCOOKIE_MAXLENGTH_VALUENAME,
CookieValues.viewCookie_maxLength, temInt))
CookieValues.viewCookie_maxLength = temInt;
those lines for all values, and methods for all the different type.
Is there a better way like this:
public class Value<T> {
String valueName;
final T defaultValue;
T value;
Method method;
...
}
but I don't know if this is the best way and also I'm a little bit worried, because I don't want to slow down the server, due to all the Wrapppers. This problem is hard to search so I'm sorry if this has already been asked somewhere.
This might answer your question: What is the best way to convert a java object to xml with open source apis
Basically you have to use a Marshaller (something that converts an object to text and back), and there are tons of those for Java.

Is there an easy way to turn empty form inputs into null strings in Spring MVC?

I'm using Spring MVC and SimpleJdbcInsert to insert objects into a MySQL database. I'd like to set the blank input to NULL in the database rather than ''. I have quite a few fields, and I'm hoping for a way to do this without manually checking every value.
Thanks!
UPDATE
So I'm an idiot. Several errors combined on my part led me to believe the correct answers below were not correct. I'd written a PropertyEditorSupport like this:
class StringEditor extends PropertyEditorSupport {
public void setAsText(String text) {
String value = text.trim();
if ("" == value) {
setValue(null);
} else {
setValue(value);
}
}
}
There are two problems:
no getAsText, so my form was getting populated with "null" strings!
my equality check is C++, not Java. When I tried the recommended
setter, I just reloaded the post, which already contained the "null"
strings. Once I cleaned all that up, everything started working.
Thanks for the help, and sorry for my "operator error"!
Brett
The class you're looking for is:
org.springframework.beans.propertyeditors.StringTrimmerEditor
If you construct it with a true it will convert empty/whitespace strings to null. How to get it registered onto the binder depends on if you want it to be the default or only apply to certain views.
e.g., on a single controller you can just add
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
}
instructions here
I know this is old, but I wasted about 2 or 3 hours until I found a very easy way to apply a StringTrimmerEditor with a binder for all my controllers.
Once again: I must remember to RTFM.
In spring 3.2 you can create a #ControllerAdvice-annottated controller class and use the #InitBinder-annotated method just like the example #Affe gave.
http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-ann-initbinder-advice
Here is an example:
#ControllerAdvice
#Controller
public class AppBindingInitializer {
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
}
}
Hope it helps someone.
Perhaps you can use a custom Binder
Set the default value for your optional fields to NULL - actually is it not NULL by default?
Parse your input string and then explicitly specify only populated columns with
usingColumns
oh, and I'd advise to always sanitise your inputs...

Categories

Resources