How I can transfer atrributes values from a Objects to another - java

I want tranfers attributes values from a object that came from my Entity manager to a new object.
The return Object is always null
public class ReflectionUtil {
public static Object copyAttributesFromTo(Object a, Object b) throws IllegalArgumentException, IllegalAccessException {
Field[] fieldsFromFirstClass = a.getClass().getDeclaredFields();
Field[] fieldsFromSecondClass = b.getClass().getDeclaredFields();
for (Field currentFieldFromTheFirstClass : fieldsFromFirstClass) {
for (Field currentFieldFromTheSecondClass : fieldsFromSecondClass) {
String nameOfTheFirstField = currentFieldFromTheFirstClass.getName();
String nameOfTheSecondField = currentFieldFromTheSecondClass.getName();
if (!Modifier.isFinal(currentFieldFromTheFirstClass.getModifiers())) {//Dispensa os Final
if (!currentFieldFromTheFirstClass.isAnnotationPresent(Id.class)) {//Não sobescreve campo id
if (nameOfTheFirstField.equals(nameOfTheSecondField)) {
currentFieldFromTheFirstClass.setAccessible(true);
currentFieldFromTheSecondClass.setAccessible(true);
currentFieldFromTheSecondClass.get(b));
currentFieldFromTheFirstClass.set(a, currentFieldFromTheSecondClass.get(b));
}
}
}
}
}
return a;
}
}
In the Facade call I always have to put all the attribute values to new object
public void update(Profile object) {
dao.beginTransaction();
Profile persistedObject = dao.find(object.getId());
persistedObject.setName(object.getName());
dao.commitAndCloseTransaction();
}
So I think to create some like that
public void update(Profile object) {
dao.beginTransaction();
Profile persistedObject = dao.find(object.getId());
ReflectionUtil.copyAttributesFromTo(persistedObject , object);
dao.commitAndCloseTransaction();
}

really miss understood why u are using 2 loop? .. if the classes are same . u dont need to do it .. just do it in 1 loop .. and use fields get for obj which is holding data .. and use set for to set .. here is the more better way .. if the same object is required u can use generics .. and same object type will be required ( request return type )
public static <T> T copyAttributesFromTo(T value, T dataHolder) throws IllegalArgumentException, IllegalAccessException {
if (value == null || dataHolder == null) {
throw new IllegalArgumentException();
}
final Field[] fields = value.getClass().getDeclaredFields();
for (Field field : fields) {
if (!Modifier.isFinal(field.getModifiers())) {
field.setAccessible(true);
field.set(value, field.get(dataHolder));
}
}
return value;
}

The return Object is always null
It is impossible for the return object (i.e. whatever a contains when you return) to be null.
It is easy to see that the code does not change the reference a. There are no assignments to it in the method, so it cannot change.
The other possibility was that you called the method with a null value for a. But if you did that, the first line of the method calls a.getClass() and that will throw an NPE if a is null.
TL;DR - it is impossible.
So what does this mean?
Here are the most likely explanations:
You are mistaken that null is being returned. Perhaps the method is not being called? Perhaps, it is not returning?
Maybe you have misinterpreted the evidence in some other way. It is hard to know without seeing the code ... and the evidence.
Maybe you don't mean that the method is returning Object; i.e. I misunderstood the question. (Your problem description is pretty unambiguous though ...)

I make a change in the code and works to update for me
public static Object copyAttributesFromTo(Object a, Object b) throws IllegalArgumentException, IllegalAccessException {
Field[] fieldsFromFirstClass = a.getClass().getDeclaredFields();
Field[] fieldsFromSecondClass = b.getClass().getDeclaredFields();
//JSFMessageUtil.addMsgLog(JSFMessageUtil.matricula, ReflectionUtil.class.getCanonicalName(), "ReflectionUtil: Aqui");
for (Field currentFieldFromTheFirstClass : fieldsFromFirstClass) {
for (Field currentFieldFromTheSecondClass : fieldsFromSecondClass) {
Object nameOfTheFirstField = currentFieldFromTheFirstClass.getName();
Object nameOfTheSecondField = currentFieldFromTheSecondClass.getName();
if (!Modifier.isFinal(currentFieldFromTheFirstClass.getModifiers())) {//Dispensa os Final
//if (!currentFieldFromTheFirstClass.isAnnotationPresent(Id.class)) {//Não sobescreve campo id
if (nameOfTheFirstField.equals(nameOfTheSecondField)) {
currentFieldFromTheFirstClass.setAccessible(true);
currentFieldFromTheSecondClass.setAccessible(true);
//JSFMessageUtil.addMsgLog(JSFMessageUtil.matricula, ReflectionUtil.class.getCanonicalName(), "ReflectionUtil: " + currentFieldFromTheSecondClass.get(b));
currentFieldFromTheFirstClass.set(a, currentFieldFromTheSecondClass.get(b));
}
//}
}
}
}
return a;
}
The call
public void update(Aluno a) {
try {
Aluno aluno = new Aluno();//(Aluno) em.find(Aluno.class, a.getId());
em.getTransaction().begin();
//aluno.setNome(a.getNome());
ReflectionUtil.copyAttributesFromTo(aluno, a);
em.merge(aluno);
em.getTransaction().commit();
} catch (Exception e) {
System.out.println("Error " + e.getLocalizedMessage());
JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), "Erro", JOptionPane.ERROR_MESSAGE);
} finally {
em.close();
}
}

Related

Is there design pattern to update hundreds of attributes of a Java class?

We have a use case where there is a class that has more than 130 attributes. There is a method that populates all the attributes and it is just very long just because of large number of attributes. Just the setters would make the method very long.
Just to give context about the source for these attributes, these are populated by different datasources. Few of them are from different micro services and few of them are from a mysql tables.
Our current solution is to group them into different groups based on the source or some similar business trait and update them in different methods. This has made some of the setters in different methods and just makes it very hard to read.
I have read else where about the builder pattern. But most of these attributes need some transformation after fetching from source and assigning each of the attributes to a temp variables and using them in the builder doesn't help much.
"Is there a design pattern...?" Nope.
First and foremost, reconsider whether this object even needs that many fields. "Our current solution is to group them into different groups" this suggests it doesn't.
If it genuinely needs that many fields and if the fields are identically named on both the source and target objects, i.e. the main instance with 130 fields is basically a composite of all the others, then you could consider using reflection.
e.g. for the following value objects
class Main {
private String a;
private Number b;
private String c;
private String d;
}
class A {
private final String a;
A(String a) {
this.a = a;
}
}
class B {
private final Integer b;
B(Integer b) { this.b = b; }
}
class C {
private final String c;
C(String c) { this.c = c; }
}
A simple example would be
public static void main(String[] args) throws Exception {
Main main = new Main();
A a = new A("a1");
B b = new B(2);
C c = new C("c3");
// Get all values from all sources
Map<String, Object> fieldToValue = new HashMap<>();
Stream.of(a, b, c).forEach(obj -> {
Field[] fields = getFieldsForInstance(obj);
for (Field field : fields) {
try {
Object prevValue = fieldToValue.put(field.getName(), field.get(obj));
if (prevValue != null) {
throw new RuntimeException("Duplicate source field " + field.getName());
}
}
catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
});
// Set the values on main instance
Field[] mainFields = getFieldsForInstance(main);
for (Field field : mainFields) {
if (fieldToValue.containsKey(field.getName())) {
Object value = fieldToValue.get(field.getName());
if (value != null) {
if (field.getType().isAssignableFrom(value.getClass())) {
field.set(main, value);
}
else {
throw new RuntimeException("Incompatible types for field " + field.getName());
}
}
}
else {
System.out.println("warning: field " + field.getName() + " is unset on main");
}
}
}
private static Field[] getFieldsForInstance(Object obj) {
Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
}
return fields;
}
I'd also consider whether you could use code generation at compile time, e.g. JavaPoet.

How to "merge" two objects of the same class

The code is groovy but the answer can be both, Groovy or Java.
I have a Person class with this fields:
class Person(){
String name
String lasName
}
I have a method that returns two objects from the same class. One object with some fields and the other with the rest, in my example it would be like this:
person1 = "name : Jon"
person2 = "lastName : Snow"
What I need is to replace all the null fields of person1 with the person2 field if this is not null, in our example, the output would be:
person1.merge(person2)
person1= "name : Jon, lastName : Snow"
Is there any method on Java or Groovy to do something similar to this without writing all my fields(using some kind of loop)?
If there isn't any default method to use, how can I iterate through all the fields from a class?
Just tested using reflection. The desired output is
merged person:Person{name=John, lastName=Snow}
public static void testReflection() {
Person p1 = new Person("John", null);
Person p2 = new Person(null, "Snow");
Person merged = (Person) mergePersons(p1, p2);
System.out.println("merged person:" + merged);
}
public static Object mergePersons(Object obj1, Object obj2) throws Exception {
Field[] allFields = obj1.getClass().getDeclaredFields();
for (Field field : allFields) {
if (Modifier.isPublic(field.getModifiers()) && field.isAccessible() && field.get(obj1) == null && field.get(obj2) != null) {
field.set(obj1, field.get(obj2));
}
}
return obj1;
}
mergePersons accepts two Objects.
Then it go through all fields and validate if the first object has a null value.
If yes, then it verify if the second object is not nulled.
If this is true it assigns the value to the first Object.
Providing this solution you only access public data. If you want to access private data aswell, you need to remove the Modifier verification and set if accessible before like:
public static Object mergePersons(Object obj1, Object obj2) throws Exception {
Field[] allFields = obj1.getClass().getDeclaredFields();
for (Field field : allFields) {
if (!field.isAccessible() && Modifier.isPrivate(field.getModifiers()))
field.setAccessible(true);
if (field.get(obj1) == null && field.get(obj2) != null) {
field.set(obj1, field.get(obj2));
}
}
return obj1;
}
This is a quick (and presumptuous) approach that is basically the same as using reflection on the fields but instead uses:
Groovy's built-in getProperties() method on java.lang.Object, which provides us with a Map of its property names and values
Groovy's default Map constructor, which allows use to create instances of an Object given a Map of properties.
Given these two features, you can describe each object you want to merge as a Map of their properties, strip out the null-valued entries, combine the Maps together (and remove the pesky 'class' entry which is readonly), and use the merged Map to construct your merged instance.
class Person {
String first, last, middle
}
def p1 = new Person(first: 'bob')
def p2 = new Person(last: 'barker')
Person merged = (p1.properties.findAll { k, v -> v } // p1's non-null properties
+ p2.properties.findAll { k, v -> v }) // plus p2's non-null properties
.findAll { k, v -> k != 'class' } // excluding the 'class' property
assert merged.first == 'bob'
assert merged.last == 'barker'
assert merged.middle == null
Given Groovy fields are implemented as a getter/setter pair with a backing field you can probably do it this way in Groovy:
static <T> void merge(T from, T to) {
from.metaClass.properties.findAll { p ->
p.getProperty(to) == null &&
p.getProperty(from) != null &&
to.respondsTo(MetaProperty.getSetterName(p.name))
}
.each {
p -> p.setProperty(to, p.getProperty(from))
}
}
You're going to have to go the reflection route. I'm assuming you have a default constructor, otherwise the following won't work. Also, it needs two same types.
public static <T> T mergeObjects(T first, T second) throws IllegalAccessException, InstantiationException {
Class<?> clazz = first.getClass();
Field[] fields = clazz.getDeclaredFields();
Object returnValue = clazz.newInstance();
for (Field field : fields) {
field.setAccessible(true);
Object value1 = field.get(first);
Object value2 = field.get(second);
Object value = (value1 != null) ? value1 : value2;
field.set(returnValue, value);
}
return (T) returnValue;
}
Here is example
import java.lang.reflect.Field;
public class Merge2Obj {
private String name;
private String lasName;
public Merge2Obj() {
super();
}
public Merge2Obj(String name, String lasName) {
super();
this.name = name;
this.lasName = lasName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLasName() {
return lasName;
}
public void setLasName(String lasName) {
this.lasName = lasName;
}
public static <T> T mergeObjects(T first, T second) throws IllegalAccessException, InstantiationException {
Class<?> clazz = first.getClass();
Field[] fields = clazz.getDeclaredFields();
Object returnValue = clazz.newInstance();
for (Field field : fields) {
field.setAccessible(true);
Object value1 = field.get(first);
Object value2 = field.get(second);
Object value = (value1 != null) ? value1 : value2;
field.set(returnValue, value);
}
return (T) returnValue;
}
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Merge2Obj obj1 = new Merge2Obj("ABC", null);
Merge2Obj obj2 = new Merge2Obj("PQR", "LMN");
Merge2Obj obj3 = mergeObjects(obj1, obj2);
System.out.println(obj3.name);
System.out.println(obj3.lasName);
}
}
Assuming a mutable data class with getters and setters, Apache BeanUtils may suit your needs.
By default BeanUtilBeansBean.copyProperties(Object dest, Object orig) looks for pairs of T orig.get*() and dest.set*(T value), and calls the latter with the result of the former.
But you can inject a custom PropertyUtilsBean, so you could wrap the default one to prevent it from replacing non-null properties:
public NoClobberPropertyUtilsBean extends PropertyUtilsBean {
#Override
public void setSimpleProperty((Object bean,
String name,
Object value)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException {
if(getProperty(bean,name) == null) {
super.setSimpleProperty(bean,name,value);
}
}
}
Now you can merge with:
BeanUtilsBean beanUtils = new BeanUtilsBean(new ConvertUtilsBean(), new NoClobberPropertyUtilsBean());
Person merged = new Person();
beanUtils.copyProperties(person1);
beanUtils.copyProperties(person2);
If a property is non-null in both sources, the first copyProperties wins.
You could of course change the semantics, for example it would behave a different way if the guard was if(value != null).
At one level BeanUtils is just a wrapper around the kind of Reflection operations other answers suggest. It's up to you whether you want the extra level of abstraction. You may need to override more methods if you want to support map/list members, or BeanUtils' DynaBean class.

How can I test if a Method will accept a parameter type?

Say I have the following code...
#FunctionalInterface
static interface MessageFunction<T> {
void send(T obj);
}
static #interface Message {
Class<?> value();
}
static class Foo {
#Message(String.class)
MessageFunction<String> bass = (string) -> {
// Do Stuff
};
}
static class MessageManager {
Map<Class<?>, MessageFunction<?>> messages = new HashMap<>();
public void register(Object obj) {
for (Field field : obj.getClass().getDeclaredFields()) {
Message message = field.getAnnotation(Message.class);
if (message != null) {
MessageFunction<?> function;
try {
function = (MessageFunction<?>) field.get(obj);
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
return;
}
Method sendMethod;
try {
// Will this work?
sendMethod = function.getClass().getDeclaredMethod("send", Object.class);
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
return;
}
// How do I do something like this?
/*if (sendMethod.testParamaters(message.value())) {
this.messages.put(message.value(), function);
}*/
}
}
}
}
public static void main(String[] args) {
MessageManager manager = new MessageManager();
manager.register(new Foo());
}
I am reflecting a field that references an #FunctionalInterface of a generic type. Because the method parameter is also generic I have no way of knowing what parameters it accepts, Thus I must pass it along through other means (the annotation).
The issue is that there is the annotation value and the generic type do not have to match and there seems to be no way to check. I wan't it to fail in registration if the type listed in the annotation would not be accepted into the send method.
How would I go about thing this without actually calling the method. Is there a way? Better yet although I know its most likely impossible, is there a way to know what the parameter type is without the annotation?
The following is just a suggestion, I have used it in my project. But it is not a perfect solution for the question. May be you can download the source of GenericHibernateDao framework and see the sourcecode of method "getTypeArguments". I think it is so cool!.
// get a class object for your entity
Class clazz = ...
Type type = clazz.getGenericSuperclass();
if (type instanceof ParameterizedType) {
Type trueType = ((ParameterizedType)type).getActualTypeArguments()[0];
Class modelClass = (Class) trueType;
// Now you can creat an Instance in you generic parameterType
Object entity = modelClass.forInstance();
}
I do something similar in some of my code Here is a snippet.
Method[] meths = actionClass.getMethods();
for (Method meth : meths) {
Class<?>[] pTypes = meth.getParameterTypes();
/*
* Filter out all methods that do not meet correct
* signature. The correct signature for an action method
* is: String actionName(HttpServletRequest request)
*/
//...check for the correct number of params and the correct param type
if (pTypes.length != 1 || !HttpServletRequest.class.toString().equals(pTypes[0].toString())) {
continue;
} else {
//...check for return type
if (!String.class.toString().equals(meth.getReturnType().toString())) {
continue;
}
}
//If you make it here than that means the method
//meets the requirements to be a full fledged action.
//...
}

Determine if a field is a type I created, using reflection

Assuming I have an object and I took it fields:
Field[] fields = obj.getFields();
Now I'm iterating through each one and would like to print their members if it's some kind of class, otherwise just use field.get(obj) in case it's a string, int or anything that this command will print its value, not just the reference pointer.
How can I detect it?
You can get, without instantiation required, the Type of each field of a class like this:
public class GetFieldType {
public static void main (String [] args) {
Field [] fields = Hello.class.getFields();
for (Field field: fields) {
System.out.println(field.getGenericType());
}
}
public static class Hello {
public ByeBye bye;
public String message;
public Integer b;
...
}
}
You can use instanceof to tell the objects apart.
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
Object[] objects = new Object[4];
objects[0] = new Integer(2);
objects[1] = "StringTest";
objects[2] = new BigDecimal(2.00d);
for (Object obj : objects) {
if (obj != null) {
if (obj instanceof BigDecimal) {
System.out.println("bigdecimal found " + obj);
} else if (obj instanceof String) {
System.out.println("String found " + obj);
} else {
System.out.println("Integer found " + obj);
}
}
else{
System.out.println("object is null");
}
}
}
If you need to test if an object is from your project, you can look at the package name and compare it to your project's package name.
You can either do this on the declared type of the field or on the runtime type of the field contents. The snippet below demonstrates the latter approach:
SomeClass foo = new SomeClass();
for (Field f : foo.getClass().getDeclaredFields()) {
boolean wasAccessible = f.isAccessible();
try {
f.setAccessible(true);
Object object = f.get(foo);
if (object != null) {
if (object.getClass().getPackage().getName()
.startsWith("your.project.package")) {
// one of yours
}
} else {
// handle a null value
}
} finally {
f.setAccessible(wasAccessible);
}
}
Do remember that obj.getFields(); only returns publicly-accessible fields. You may want to consider getDeclaredFields() as I've done above. If you stick with getFields(), you can omit the accessibility code in the above example.
With a bit of work, you could distinguish your classes by the classloader that loaded them. Take a look at this:
Find where java class is loaded from
Though this could help, it's not going to be the silver bullet for your problem, mainly because:
primitives (byte, short, char, int, long, float, double, and boolean) are not classes.
the architecture of classloaders is different in different app servers.
the same class could be loaded many times by different classloaders.
what I understood is you what to go recursive in object hierarchy and get values of primitives
public class ParentMostClass {
int a = 5;
OtherClass other = new OtherClass();
public static void main(String[] args) throws IllegalArgumentException,
IllegalAccessException {
ParentMostClass ref = new ParentMostClass();
printFiledValues(ref);
}
public static void printFiledValues(Object obj)
throws IllegalArgumentException, IllegalAccessException {
Class<? extends Object> calzz = obj.getClass();
Field[] fileds = obj.getClass().getDeclaredFields();
for (Field field : fileds) {
Object member = field.get(obj);
// you need to handle all primitive, they are few
if (member instanceof String || member instanceof Number) {
System.out.println(calzz + "->" + field.getName() + " : "
+ member);
} else {
printFiledValues(member);
}
}
}
}
public class OtherClass {
int b=10;
}
I got output as
class com.example.ParentMostClass->a : 5
class com.example.OtherClass->b : 10

Dynamic null check [duplicate]

This question already has answers here:
Check chains of "get" calls for null
(11 answers)
Closed 3 years ago.
I intend to make a common dynamic null check function on any object before doing some work on it.
For example:
Class A{
B b;
// with getters and setters of b
}
class B{
C c;
//with getters and setters of c
}
class C{
BigInteger d;
//with getters and setters of d
}
now, I want to check whether objA.getB().getC().getD() returns some value or throws NullPointerException?
By common I mean I can pass any kind of object to it, something like below function
CheckNull.checkingDynamicNull( "objA.getB().getC().getD()" )
will return me true or false depending on the case.
Any ideas?
Unfortunately it is not possible to pass a funktion into a method in Java (yet, Java 8 will). Also, if you pass the variable name as String this wont work, since the recieving method has no way of knowing what Object is mapped to that variable (if you ignore reflection but even with that you are screwed if its a local variable).
Another way would be to do something like this
boolean nullCheck(Object obj, String Methods)
and then parse the String to Methods and invoke them on the object. But that wont work if you have Methods with arguments.
In short: It's more trouble then it's worth
In the most cases you want to have something like this
if(object == null){
//error behavior
}
This assumes that you want to throw a certain Exception, have means to get a value for the null object elswhere or want to do something before you throw an exception.
If you simply want to throw an Exception (that is not a NullPointerException)
assert object != null
What about this:
public boolean checkingDynamicNull(A objA) {
try {
objA.getB().getC().getD().toString();
} catch(NullPointerException npe) {
return true;
}
return false;
}
To know if a statement would return null, you would have to execute it first. Even if you somehow manage to execute the statement given in String to your method, it would be no different than just running it and checking whether the result is null, or catching the NullPointerException.
You are looking for something that will be part of Java 8 (or 9 or 10?) soon. Cf. http://viralpatel.net/blogs/null-safe-type-java-7-nullpointerexception/
With reflection it could be something like that:
nullCheck(objA, "getB", "getC", "getD" );
public static boolean nullCheck(Object obj, String... methods) {
Object o = obj;
Class<?> clazz = obj.getClass();
Method method = null;
try {
for( String name : methods ) {
method = clazz.getMethod( name, null );
o = method.invoke( o, null );
clazz = method.getReturnType();
}
} catch( NullPointerException e ) {
System.err.println(clazz.getSimpleName()+"(null)."+method.getName());
return false;
} catch( NoSuchMethodException e ) {
e.printStackTrace();
} catch( SecurityException e ) {
e.printStackTrace();
} catch( IllegalAccessException e ) {
e.printStackTrace();
} catch( IllegalArgumentException e ) {
e.printStackTrace();
} catch( InvocationTargetException e ) {
e.printStackTrace();
}
return true;
}
System.out.println(nullCheck(GraphicsEnvironment.getLocalGraphicsEnvironment(), "getDefaultScreenDevice", "getDisplayMode", "toString"));
System.out.println(nullCheck(GraphicsEnvironment.getLocalGraphicsEnvironment(), "getDefaultScreenDevice", "getFullScreenWindow", "doLayout"));
brings
true
false
'Window(null).doLayout'
you can achieve this by using reflection, here is your method:
public boolean dynamicNullCheck(Object o, String path) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
Object object= o;
for (String element : path.split("\\."))
{
Field field = object.getClass().getDeclaredField(element);
field.setAccessible(true);
Object fieldVal = field.get(object);
if (fieldVal!=null)
{
field.setAccessible(true);
object = fieldVal;
}
else
{
return true;
}
}
return false;
}
use it by giving your root element and path to each object, ie dynamicNullCheck(objA,"b.c.d")

Categories