简体   繁体   中英

Convert Hashmap with simple, indexed, nested, or combined type attributes as keys into a Java Bean

I am trying to convert a java bean to hashmap and then later convert the hashmap to java bean. For converting Java Object to hashmap this post helped me. Convert a JavaBean to key/value Map with nested name using commons-beans BeanUtils

Code below

    public class Ax {
    String axAttr;

    public String getAxAttr() {
        return axAttr;
    }

    public void setAxAttr(String axAttr) {
        this.axAttr = axAttr;
    }

    List<Bx> bxs;

    public List<Bx> getBxs() {
        return bxs;
    }

    public void setBxs(List<Bx> bxs) {
        this.bxs = bxs;
    }
}

public class Bx {
    String bxAttr;

    public String getBxAttr() {
        return bxAttr;
    }

    public void setBxAttr(String bxAttr) {
        this.bxAttr = bxAttr;
    }

    List<Cx> cxs = new ArrayList<Cx>();

    public List<Cx> getCxs() {
        return cxs;
    }

    public void setCxs(List<Cx> cxs) {
        this.cxs = cxs;
    }
}

public class Cx {
    String cxAttr;

    public String getCxAttr() {
        return cxAttr;
    }

    public void setCxAttr(String cxAttr) {
        this.cxAttr = cxAttr;
    }

    List<String> items;

    public List<String> getItems() {
        return items;
    }

    public void setItems(List<String> items) {
        this.items = items;
    }
}

below is the key value-pairs stored in the HashMap

axAttr --> axString
bxs[0].bxAttr --> bxString
bxs[0].cxs[0].cxAttr --> cxString
bxs[0].cxs[0].items[0] --> One
bxs[0].cxs[0].items[1] --> Two
bxs[0].cxs[0].items[2] --> Three

I stored these key values in DB and later retrieve them and want to convert to Java Bean again. But for converting the same HashMap to Java object with the help of propertyUtilsbean I am getting NullPointerException.

This is how I executed:

public static void main(String[] args) throws Exception {
        Ax ax = new Ax();
        ax.setAxAttr("axString");

        Bx bx = new Bx();
        bx.setBxAttr("bxString");

        Cx cx = new Cx();
        cx.setCxAttr("cxString");

        List<Bx> bxs = new ArrayList<Bx>();
        ax.setBxs(bxs);
        ax.getBxs().add(bx);

        List<Cx> cxs = new ArrayList<Cx>();
        bx.setCxs(cxs);
        bx.getCxs().add(cx);


        List<String> xs = new ArrayList<String>();
        cx.setAxs(xs);

        cx.getAxs().add(new String("One"));
        cx.getAxs().add(new String("Two"));
        cx.getAxs().add(new String("Three"));


        MyPropertyUtils myPropertyUtils = new MyPropertyUtils();

        Map map = new HashMap();
        for (String name :  myPropertyUtils.listNestedPropertyName(ax)) {
            map.put(name, PropertyUtils.getNestedProperty(ax, name));
        }

        Ax axNew = new Ax();

        Set<Entry> set = map.entrySet();


        for (Entry entry :set) {
            BeanUtils.setProperty(axNew, entry.getKey().toString(), entry.getValue().toString());
        }



    }

Exception

Exception in thread "main" java.lang.NullPointerException
    at org.apache.commons.beanutils.PropertyUtilsBean.getIndexedProperty(PropertyUtilsBean.java:507)
    at org.apache.commons.beanutils.PropertyUtilsBean.getIndexedProperty(PropertyUtilsBean.java:410)
    at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:768)
    at org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:846)
    at org.apache.commons.beanutils.BeanUtilsBean.setProperty(BeanUtilsBean.java:903)
    at org.apache.commons.beanutils.BeanUtils.setProperty(BeanUtils.java:456)
    at com.wavecrest.aspect.Test1.main(Test1.java:57)

Any suggestions are accepted:

BeanUtils don't create objects instances for you inside axNew instance. So, calling

BeanUtils.setProperty(axNew, "bxs[0].cxs[0].cxAttr", "Some value"); 

Means "Get first element of 'bxs' collection, then get first element of it and then update the 'cxAttr' property of this object". But bxs property of axNew is null at this moment, which causes NullPointerException .

You need to initialize your objects with empty objects and only then you will be able to update their properties with setProperty method, eg:

axNew.setBxs(new ArrayList<Bx>());
axNew.getBsx().add(new Bx());
// should works fine
BeanUtils.setProperty(axNew, "bxs[0].bxAttr", "Some value"); 

I would also add that it is not the best way to store objects with complex hierarchy inside DB. There are other more useful methods of serialization:

  • ORM
  • Conversion to XML/JSON
  • Java Serialization
  • etc.

You could convert a java bean to a hash map such that the map's keys are the bean's property names. For nested beans you could have property Path keys like "proprty1.property2". If this fits the bill, I got a solution for you with my juffrou-reflect library. Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM