JAVA : How to get the name of variable with annotation in Java? - java

I am trying to get the name of variable in android using java.
The variable has a annotation, and I want to get the variable's name with the annotation's name. is this possible?
just like this,
#getnameofthisfield
private String name;
use getnameofthisfield and get name

You can do it like this:
Class<YourClass> clazz = // somehow get a reference to the class that contains the field
Field[] fields = clazz.getDeclaredFields();
List<String> fieldNames = new LinkedList<>();
for (Field field : fields) {
if (field.isAnnotationPresent(#getnameofthisfield.class)) {
fieldNames.add(field.getName);
}
}
In the end fieldNames will contain the names of all fields, annotated with #getnameofthisfield.

This comes up when you have a Data holder class that is a model for Firebase fields (for example) and the spelling of the member names must exactly equal the Strings in the Firebase tree. While I have not eliminated the duplicate typing/spelling of the Strings/fields, this will at least detect these programming errors at run-time.
public class User {
private String email;
private String name;
// avoid out-of-sync String names of fields in other files
public static String getFieldName(String fieldRequest) {
try {
return User.class.getDeclaredField(fieldRequest).getName();
} catch (NoSuchFieldException e1) {
e1.printStackTrace();
throw new RuntimeException("Unrecognized field in "
+ User.class.getSimpleName() + ", (" + fieldRequest + ")"); }
}
Here is an example usage:
// demonstration of how the getFieldName() protects against mistakes...
String userNameField = User.getFieldName("name"); // this works
String userEmailField = User.getFieldName("userEmail"); // this throws an error

Get annotation value
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class Util{
#SuppressWarnings("unchecked")
public static<T> T getAnnotationValue(Class<?> clazz,Class<? extends Annotation> annotationClass,String element) throws Exception {
Annotation annotation = clazz.getAnnotation(annotationClass);
Method method = annotationClass.getMethod(element,(Class[])null);
if (annotation == null)
return((T)method.getDefaultValue());
return((T)method.invoke(annotation,(Object[])null));
}
}

In my understanding that isnt possible, the java compiler doesn't save variable names. What is it that your trying to do with such name?

Related

Java JAXB marshall/unmarshall using Java Optionals

My applications needs to convert data between Java and XML.
When converting the data, I need to distinguish whether or not the value was present, the value was set explicitly to null or the value had a value.
XML example:
<person><name>Bob</name></person> <-- element 'name' contains value "Bob"
<person><name nil="true"/></person> <-- element 'name' was set explicitly to 'nil'/null
<person></person> <-- element 'name' is missing
As Java types like 'String' only knows two states (null or not null), I tried to use Java Optionals to solve this.
A mapping between XML and Java Optionals could look like this:
<person></person> <=> Optional<String> name = null;
<person><name>Bob</name></person> <=> Optional<String> name = Optional.of("Bob");
<person><name nil="true"/></person> <=> Optional<String> name = Optional.empty();
I tried to use JAXB for the marshalling and unmarshalling. The idea was that the setter of a field only gets invoked when a value needs to be set explicitly to an value. That means that a value is absent implicitly.
I had a look on other stackoverflow questions like the following, but all of them were incomplete handling the behaviour I need to achieve:
How to generate JaxB-Classes with java.util.Optional?
Using generic #XmlJavaTypeAdapter to unmarshal wrapped in Guava's Optional
Using Guava's Optional with #XmlAttribute
I've been struggling with this problem for two days now. I tried to use the XMLAdapter and GenericAdapter, tried several ways how to annotate the fields and getter/setter with #XmlElement, tried to use #XmlAnyElment with and without lax, but all of them only led to a partial success. Either the nil value was not handeld correctly, the lists were not printed out correctly, ...
I think every Java webservice with a properly implemented patch operation should have had this problem. (not talking about the "json patch approach" (RFC 6902))
Is there a common way to solve my problem?
The following code is able to distinguish empty name from null name. To make the solution work, I created a PersonList element to contain all of the person elements. Each Person contains a Name that will have isNil() return true if the element was explicitly set to null by the XML:
Person.java:
import java.util.Optional;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlType(propOrder = {"name"})
#XmlRootElement(name = "person")
public class Person {
private Optional<Name> optionalName;
public Person() {
optionalName = Optional.<Name>empty();
}
public Optional<Name> getOptionalName() {
return optionalName;
}
public Name getName() {
return (optionalName.isPresent()) ? (optionalName.get()) : (null);
}
#XmlElement(name = "name", required = false)
public void setName(Name name) {
optionalName = Optional.ofNullable(name);
}
#Override
public String toString() {
return String.format("Person(optionalName.isPresent() = %s, name = %s)",
Boolean.toString(optionalName.isPresent()),
((getName() == null) ? ("null") : (getName().toString())));
}
}
Name.java:
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "name")
public class Name {
#XmlAttribute(name = "nil")
private boolean nil;
#XmlValue
private String value;
public Name() {
nil = false;
value = null;
}
public boolean isNil() {
return nil;
}
public void setNil(boolean torf) {
this.nil = torf;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
#Override
public String toString() {
return String.format("Name(nil = %s, value = %s)",
Boolean.toString(nil),
(value == null) ? ("null"):("\""+getValue()+"\""));
}
}
PersonList.java:
import java.util.Iterator;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "PersonList")
public class PersonList {
private List<Person> persons;
public PersonList() {
persons = null;
}
#XmlElement(name = "person")
public List<Person> getPersons() {
return persons;
}
public void setPersons(List<Person> persons) {
this.persons = persons;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder("PersonList(persons = ");
if(persons == null) {
sb.append("null");
}
else {
sb.append("[");
Iterator<Person> iterator = persons.iterator();
while(iterator.hasNext()) {
sb.append(iterator.next().toString());
if(iterator.hasNext()) {
sb.append(", ");
}
}
sb.append("]");
}
sb.append(")");
return sb.toString();
}
}
Main class to demonstrate the solution:
import java.io.ByteArrayInputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
public class XmlOptional {
public static final int STATUS_OKAY = 0;
public static final int STATUS_ERROR = -1;
public static final String XML_DATA = "<PersonList>" +
"<person><name>Bob</name></person>" +
"<person><name nil=\"true\" /></person>" +
"<person></person>" +
"</PersonList>";
private XmlOptional() {
}
private static PersonList loadXml() {
try {
ByteArrayInputStream bais = new ByteArrayInputStream(XML_DATA.getBytes());
JAXBContext context = JAXBContext.newInstance(PersonList.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
PersonList personList = (PersonList)unmarshaller.unmarshal(bais);
return personList;
}
catch(Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
int status = STATUS_OKAY;
try {
PersonList personList = loadXml();
System.out.format("Xml contained: %s%n", personList);
}
catch (Throwable thrown) {
status = STATUS_ERROR;
thrown.printStackTrace();
}
finally {
System.exit(status);
}
}
}
Sample output:
Xml contained: PersonList(persons = [Person(optionalName.isPresent() = true, name = Name(nil = false, value = "Bob")), Person(optionalName.isPresent() = true, name = Name(nil = true, value = "")), Person(optionalName.isPresent() = false, name = null)])
Since I was not able to solve the problem completely by solely using and configuring JAXB properly, I decided to solve it as follows:
(The main goal was to write a subsystem to communicate with an external system based on XML)
As a starting point, I used the XSD schema provided by the target system to communicate with and generated the corresponding (XML)Java classes using JAXB and the XSD file. All the fields in those generated classes were of type JAXBElement<>, in order to be able to hold the 3 states needed (absent, null, someValue).
On the business model side, I used Java classes with Optional<> field types in order to hold the 3 states.
For the mapping, I wrote a mapper which uses reflection to recursively map from JAXB to Java and vice versa. When mapping from Java to JAXB, the mapper used the ObjectFactory to create the JAXBElement objects. (Mapper itself just had about 300 lines of code).
The fields were mapped based on the matching field names.
The most ugly and challenging part was, that the XSD schema file needed to be altered, in order to make JAXB generated classes that uses JAXBElement field types. Therefore I had to manually add the attribute minOccurs="0" nillable="true" to the XML elements, if not already set.
With that solution above, I finally managed to map the XML to Java and vice versa considering the 3 states needed, easily.
Of course, this solution has its drawbacks.
One is the manual modification of the XSD file. Usually bad practice to alter the XSD file provided by the external system, which acts as an interface contract.
For my requirements at the time, the solution worked perfectly. Even changes to the interface contract of the external system could be implemented very easily.
You can use some validation in your java class like #NotNull, #Size and so on. Or you can put default value , to be sure , that it will be not null. After that you can create DTOs (Data transfer object) with the recommended Xml annotations and mapped it with the ModelMapper.

Mapping one custom Java field to many JSON fields using Jackson #JsonDeserializer

I have a java class representing a JSON using Jackson. All of the fields, with one exception, can be translated using no annotations at all. 1-to-1, simple translations (although some of them are nested POJOs).
#Data
#AllArgsConstructor
#NoArgsConstructor
public class MyPojo {
private String someString;
private AnotherPojo someOtherPojo;
//The problem child:
private Object value;
}
The field value which is an exception to this rule, can represent any JSON field matching value* where * is a wildcard of indefinite length. That means valueString or valueReference in JSON will be assigned to this field with the assertion that only one may be present.
{
"someString": "asdasdadasdsa",
"someOtherPojo": {
"someOtherProperty": "whatever"
},
"valueCodeableConcept": {
"text": "text value",
"coding": [
{
"code": "my-code"
}
]
}
}
Using a custom deserializer on the top-level class, I can scrape all of the fields from the root node (baseNode in the following example) that start with value and set the value field appropriately. That works great! However, in doing so, I now have to set every other field in this MyPojo class manually in my deserializer, and I have to put a custom copy of this deserializer on each POJO that uses a field like value*.
private Object parseValueX(JsonNode baseNode, DeserializationContext context) throws IOException {
//Find the concrete implementation referred to by the value[x] field
Set<String> concreteNames = new HashSet<>();
baseNode.fieldNames().forEachRemaining(name -> {
if (name.startsWith("value")) {
concreteNames.add(name);
}});
if (concreteNames.isEmpty()) {
return null;
}
if (concreteNames.size() > 1) {
throw JsonMappingException.from(context, "The field value[x] must have no more than one concrete " +
"implementation, ex: valueCode, valueCodeableConcept, valueReference");
}
String concreteName = concreteNames.stream().findFirst().orElseThrow(() -> new RuntimeException(""));
JsonNode jsonSource = baseNode.get(concreteName);
//...deserialize from jsonSource, solved, but not relevant to question...
}
To make this apply to any value* property on any POJO, I tried to move the deserializer to the value attribute in the POJO (whereas it's on the top-level resource now). The first flaw is that the deserializer isn't even invoked unless the JSON property exactly matches value. What I actually need is for the entire parent JSON resource to be passed to that field-specific deserializer, so that I may find the matching field and assign it -- OR -- I need to be able to have the deserializer on MyPojo only assign the one field value and allow the automatic deserialization to take care of the others. How do I do either of these?
For those curious about my motivation, I am implementing the HL7 FHIR Specification, which specifies generic attributes called value[x] (here's one example: https://www.hl7.org/fhir/extensibility.html#Extension) where [x] becomes the type of the resource.
I think a good fit for you problem is #JsonAnySetter. This method annotation tells Jackson to route unknown properties to it. the arg (in your case) is a Map containing the json tree of the unknown property. if I understand your code properly, the name of the value property contains the class name of the target Pojo. so once you have a class name, you can tell Jackson how to "deserialize" the map into an instance of the target class.
Here is an example based on the code from the question
public class MyPojo {
public String someString; // made properties into public for this example...
public AnotherPojo someOtherPojo;
public Object value;
#JsonAnySetter
public void setValue(String name, Object value) {
System.out.println(name + " " + value.getClass());
System.out.println(value);
// basic validation
if (name.startsWith("value") && value instanceof Map) {
String className = "com.company." + name.substring("value".length());
System.out.println(name + " " + value.getClass() + " " + className);
System.out.println(value);
try {
// nice of Jackson to be able to deserialize Map into Pojo :)
ObjectMapper mapper = new ObjectMapper();
this.value = mapper.convertValue(value, Class.forName(className));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(this.value + " " + this.value.getClass());
}
}
}
public class AnotherPojo {
public String someOtherProperty;
}
public class CodeableConcept {
public String text;
public Code[] coding;
}
public class Code {
public String code;
}

How to iterate over all the declared fields of an object of a class [duplicate]

I need to make sure that no object attribute is null and add default value in case if it is null. Is there any easy way to do this, or do I have to do it manually by checking every attribute by its getters and setters?
You can use reflection to iterate over the object's field, and set them. You'd obviously need some sort of mapping between types or even field names and required default values but this can be done quite easily in a loop. For example:
for (Field f : obj.getClass().getFields()) {
f.setAccessible(true);
if (f.get(obj) == null) {
f.set(obj, getDefaultValueForType(f.getType()));
}
}
[Update]
With modern Java, you can use annotations to set the default values for fields on a per class basis. A complete implementation might look like this:
// DefaultString.java:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
#Retention(RetentionPolicy.RUNTIME)
public #interface DefaultString {
String value();
}
// DefaultInteger.java:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
#Retention(RetentionPolicy.RUNTIME)
public #interface DefaultInteger {
int value();
}
// DefaultPojo.java:
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
public class DefaultPojo {
public void setDefaults() {
for (Field f : getClass().getFields()) {
f.setAccessible(true);
try {
if (f.get(this) == null) {
f.set(this, getDefaultValueFromAnnotation(f.getAnnotations()));
}
} catch (IllegalAccessException e) { // shouldn't happen because I used setAccessible
}
}
}
private Object getDefaultValueFromAnnotation(Annotation[] annotations) {
for (Annotation a : annotations) {
if (a instanceof DefaultString)
return ((DefaultString)a).value();
if (a instanceof DefaultInteger)
return ((DefaultInteger)a).value();
}
return null;
}
}
// Test Pojo
public class TestPojo extends DefaultPojo {
#DefaultString("Hello world!")
public String stringValue;
#DefaultInteger(42);
public int integerValue;
}
Then default values for a TestPojo can be set just by running test.setDetaults()
You need to manually filter input to constructors and setters. Well... you could use reflection but I wouldn't advise it. Part of the job of constructors and setters is to validate input. That can include things like:
public void setPrice(double price) {
if (price < 0.0d) {
throw new IllegalArgumentException("price cannot be negative " + price);
}
this.price = price;
}
and
public void setName(String name) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
}
You could use wrapper functions for the actual check and throwing the exception.
Non-reflective solution for Java 8, without using a series of if's, would be to stream all fields and check for nullness:
return Stream.of(id, name).allMatch(Objects::isNull);
This remains quite easy to maintain while avoiding the reflection hammer.
This will return true for null attributes.
Maybe check Hibernate Validator 4.0, the Reference Implementation of the JSR 303: Bean Validation.
This is an example of an annotated class:
public class Address {
#NotNull
private String line1;
private String line2;
private String zip;
private String state;
#Length(max = 20)
#NotNull
private String country;
#Range(min = -2, max = 50, message = "Floor out of range")
public int floor;
...
}
For an introduction, see Getting started with JSR 303 (Bean Validation) – part 1 and part 2 or the "Getting started" section of the reference guide which is part of the Hibernate Validator distribution.
You can create a function that returns a boolean value and checks every attribute. You can call that function to do the job for you.
Alternatively, you can initialize the object with default values. That way there is no need for you to do any checking.
I don't have enough context to give you a correct answer, but I'll suggest you to make you code immutable as much as possible. Use public final fields. No more getters or setters : every field has to be defined by the constructor. Your code is shorter, more readable and prevents you from writing code with side effects.
It doesn't prevent you from passing null arguments to your constructor though... You can still check every argument as suggested by #cletus, but I'll suggest you to throw IllegalArgumentException instead of NullPointerException that doesn't give no new hint about what you've done.
Anyway, that's what I do as much as I can and it improved my code (readability, stability) to a great extend. Everyone in my team does so and we are very happy with that. We learned that when we try to write some erlang code where everything is immutable.
Hope this helps.
I tried this and it works without any issues to validate if the field is empty.
I have answered your question partially as I haven't personally tried to add default values to attributes
if(field.getText()!= null && !field.getText().isEmpty())
Hope it helps
This is not to check for null, instead this will be helpful in converting an existing object to an empty object(fresh object). I dont know whether this is relevant or not, but I had such a requirement.
#SuppressWarnings({ "unchecked" })
static void emptyObject(Object obj)
{
Class c1 = obj.getClass();
Field[] fields = c1.getDeclaredFields();
for(Field field : fields)
{
try
{
if(field.getType().getCanonicalName() == "boolean")
{
field.set(obj, false);
}
else if(field.getType().getCanonicalName() == "char")
{
field.set(obj, '\u0000');
}
else if((field.getType().isPrimitive()))
{
field.set(obj, 0);
}
else
{
field.set(obj, null);
}
}
catch(Exception ex)
{
}
}
}

Java - Get object of class depending on its name

this is my situation:
I have a method which has a String as parameter. This method has to receive an object from a class called Urls. The object it has to recieve, has the same name as the value of the String. Here is my code:
private Object getObject(String objectName){
try
{
Field field = Urls.class.getField(objectName);
}
catch (NoSuchFieldException e)
{}
catch (IllegalAccessException e)
{}
}
And here is my Urls class:
public class Urls{
public static final String[] ASTUN = new String[]{
"http://www.astun.com/camara/truchas.jpg",
"https://www.todonieve.com/photowebcam.asp?fotografia=astun/astun.jpg",
"http://www.astun.com/camara/caba%C3%B1a%20sarrios.jpg",
"http://www.astun.com/camara/sector%20sarrios.jpg",
"http://www.astun.com/camara/sector%20raca%20prad.jpg",
"http://www.astun.com/camara/sector%20aguila%20cr.jpg",
"http://www.astun.com/camara/sector%20truchas.jpg",
"http://www.astun.com/camara/sector%20llanos%20.jpg",
"http://www.astun.com/camara/llegada.jpg",
"http://www.astun.com/camara/terraza.jpg",
"http://www.astun.com/camara/panoramica.jpg",
"http://www.astun.com/camara/snow.jpg"
};
private static final String[] CANDANCHU = new String[]{
"https://www.todonieve.com/photowebcam.asp?fotografia=candanchu/candanchu.jpg",
"https://www.todonieve.com/photowebcam.asp?fotografia=CandanchuNew/CandanchuNew.jpg",
"https://www.todonieve.com/photowebcam.asp?fotografia=candanchu_rinconada/candanchu_rinco.jpg",
"https://www.todonieve.com/photowebcam.asp?fotografia=candanchu_tobazo/candanchu_tobazo.jpg"
};
}
So, that way I have a Field object, but how can I get the String[] of that field? I have read about the get(Object object) method of Field class but it seems that i doesnt do what I want to do...
EDIT: I WANT TO GET ASTUN OR CANDACHU STRING ARRAYS
Avoid reflection whenever possible. It often does more harm than good.
Put them into a map:
public class Urls {
//put your arrays here
private static final Map<String,String[]> urlsLists = new HashMap<>();
static {
urlLists.put("ASTUN", ASTUN);
urlLists.put("CANDANCHU", CANDANCHU);
}
public static String[] getUrlList(String name) {
return urlLists.get(name);
}
}
And then call it like this:
private Object getObject(String objectName){
return Urls.getUrlList(objectName);
}
Update
You loose a lot of nice stuff Java help you with, including type-safety, encapsulation and compile-time checks. Because of this it is a lot more error prone. There is a much increased risk of run-time errors and you need a bunch of extra code to handle this. Your brief example already have two catch clauses. Trust me - that will just get worse.
You can even improve type-safety more by creating an Enum to define url-types. Then you will get compile time checks that you have spelled the name right and even auto-completion all through-out your code. :)
public class Urls {
public enum UrlTypes {ASTUN; CANDANCHU;}
// ..
private static final Map<UrlTypes,String[]> urlsLists = new HashMap<>();
static {
urlLists.put(UrlTypes.ASTUN, ASTUN);
urlLists.put(UrlTypes.CANDANCHU, CANDANCHU);
}
..
public static String[] getUrlList(UrlTypes name) {
return urlLists.get(name);
}
}
Every error you can catch at compile-time instead of at run-time can save you between half an hour or half a week of work, when things get complex.
You will need something like this:
private Object getObject(String objectName){
try
{
Field field = Urls.class.getField(objectName);
Object o = field.get(null); // null works as well.
return o;
}
catch (NoSuchFieldException e)
{ e.printStackTrace(); }
catch (IllegalAccessException e)
{ e.printStackTrace(); }
}
private String[] getStringArray(String arrayName)
{
return (String[]) getObject(arrayName);
}
Usage:
Object o = getObject("ASTUN");
// or:
String[] arr = getStringArray("ASTUN");
getField will return the (reflexive) representation of the field concept in the Urls class. You then need to bind it with an actual object of that class to have access to the contents of the field in that object.
Field field = Urls.class.getFiled(objectName);
String[] values = (String[]) field.get(o);
where o is a variable of type Urls.
Note the cast to String[] as Field.get() will return an Object as it does not know the actual type. You should make sure that the type is indeed correct by using the Field.getType() method and compare that to Urls.class.
Since objects dont have names, you will need to create ypur own class, put the field variable in there, then use that instead of Object. Or use a Map for better key/value logging.

How to avoid overwriting of non-null values with null values?

I'm using spring MVC for receiving a JSON from client and automatically create an object from it. The problem is that the client doesn't send to server all the fields that are in the entity, but some fields are null and overwrite existing values calling userDao.persist(user). For example, i have this entity:
#Entity
public class User {
#Id #GeneratedValue
private int id;
private String username;
private String password;
private String email;
But the user never send me the password, so the object built from JSON has "password" field empty. I don't want the password field to be overwritten by a null value. There's a way to say to hibernate "if you find a null value ignore it and don't overwrite the value that is saved in database?". I can't believe that there isn't a easy solution to this apparently simple problem.
I think the source of your problem is that the object you're getting back from your JSON parsing never had the actual values in it. It is a bean that has only the values set that are in your JSON.
You need to load your entity from the DB and then set the non-null fields from your JSON onto the loaded entity. That way only fields that are supplied in the JSON will be set.
I recommend an adapter of some sort to "merge" (not JPA merge) the DB version and the JSON version before saving the DB version.
Adding a #NotNull constraint and Bean Validation will make sure the values are not null when attempting to save. Unfortunately they won't help you get the values into the entity to save.
I have the same issue.
I solved it in this way.
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import java.lang.reflect.Field;
import java.util.Hashtable;
public class Updater {
private final static Logger log = LogManager.getLogger(Updater.class);
public static <E> E updater(E oldEntity, E newEntity) {
Field[] newEntityFields = newEntity.getClass().getDeclaredFields();
Hashtable newHT = fieldsToHT(newEntityFields, newEntity);
Class oldEntityClass = oldEntity.getClass();
Field[] oldEntityFields = oldEntityClass.getDeclaredFields();
for (Field field : oldEntityFields){
field.setAccessible(true);
Object o = newHT.get(field.getName());
if (o != null){
try {
Field f = oldEntityClass.getDeclaredField(field.getName());
f.setAccessible(true);
log.info("setting " + f.getName());
f.set(oldEntity, o);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
return oldEntity;
}
private static Hashtable<String, Object> fieldsToHT(Field[] fields, Object obj){
Hashtable<String,Object> hashtable = new Hashtable<>();
for (Field field: fields){
field.setAccessible(true);
try {
Object retrievedObject = field.get(obj);
if (retrievedObject != null){
log.info("scanning " + field.getName());
hashtable.put(field.getName(), field.get(obj));
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return hashtable;
}
}
It is clearly a workaround but it seems to work smoothly... in the next days I think I'll write the recursive part.
Implement setters for you attributes and do the checks there.
Check Hibernate Validation project, which can be used to verify your object on DAO level, as well as on Spring Web layer.
I wrote this answer while being an unexpirienced studen. Today my answer would be similar to the one from #James DW. Also, from the term userDao, I assume that it is some kind of ORM/ODM. In that case it is definitly worth searching "pros and cons of ORM/ODM".
original answer (which was accepted back in 2011):
If your problem is only the database, then I suggest you use a stored procedure, which checks if that value is null, and then dose not change the existing value. That way you can still send a null value, and your validation is on server side which is more robust.

Categories