[java] How to use BeanUtils.copyProperties?

I am trying to copy properties from one bean to another. Here are the signature of two beans:

SearchContent:

public class SearchContent implements Serializable {

    private static final long serialVersionUID = -4500094586165758427L;

    private Integer id;
    private String docName;
    private String docType;
    private String docTitle;
    private String docAuthor;
    private String securityGroup;
    private String docAccount;
    private Integer revLabel;

    private String profile;
    private LabelValueBean<String> workflowStage;

    private Date createDate;
    private Date inDate;

    private String originalName;
    private String format;
    private String extension;
    private Long fileSize;

    private String author;

    private LabelValueBean<String> entity;
    private LabelValueBean<String> brand;
    private LabelValueBean<String> product;
    private LabelValueBean<String> collection;
    private LabelValueBean<String> subCollection;

    private String description;
    private LabelValueBean<String> program;
    private String vintage;
    private String model;
    private String restrictedZone;
    private LabelValueBean<String> event;
    private LabelValueBean<String> language;
    private String geographicLocation;
    private String watermark;
    private Integer pageNumber;
    private String summary;
    private String agentName;
    private String commissionedByName;
    private String commissionedByDepartment;
    private LabelValueBean<Integer> bestOf;
    private String mediaLocation;

    private LabelValueBean<Integer> fullRights;
    private LabelValueBean<String> mediaUsage;
    private Date rightsEndDate;
    private String geographicRights;
    private LabelValueBean<Integer> evinConformity;
    private String contactReference;
    private LabelValueBean<String> publicationScope;
    private String rightsComment;

    /**
     * Constructor SearchContent
     * @author TapasB
     * @since 15-Oct-2013 - 5:45:55 pm
     * @version DAM 1.0
     */
    public SearchContent() {

    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getDocName() {
        return docName;
    }

    public void setDocName(String docName) {
        this.docName = docName;
    }

    public String getDocType() {
        return docType;
    }

    public void setDocType(String docType) {
        this.docType = docType;
    }

    public String getDocTitle() {
        return docTitle;
    }

    public void setDocTitle(String docTitle) {
        this.docTitle = docTitle;
    }

    public String getDocAuthor() {
        return docAuthor;
    }

    public void setDocAuthor(String docAuthor) {
        this.docAuthor = docAuthor;
    }

    public String getSecurityGroup() {
        return securityGroup;
    }

    public void setSecurityGroup(String securityGroup) {
        this.securityGroup = securityGroup;
    }

    public String getDocAccount() {
        return docAccount;
    }

    public void setDocAccount(String docAccount) {
        this.docAccount = docAccount;
    }

    public Integer getRevLabel() {
        return revLabel;
    }

    public void setRevLabel(Integer revLabel) {
        this.revLabel = revLabel;
    }

    public String getProfile() {
        return profile;
    }

    public void setProfile(String profile) {
        this.profile = profile;
    }

    public LabelValueBean<String> getWorkflowStage() {
        return workflowStage;
    }

    public void setWorkflowStage(LabelValueBean<String> workflowStage) {
        this.workflowStage = workflowStage;
    }

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    public Date getInDate() {
        return inDate;
    }

    public void setInDate(Date inDate) {
        this.inDate = inDate;
    }

    public String getOriginalName() {
        return originalName;
    }

    public void setOriginalName(String originalName) {
        this.originalName = originalName;
    }

    public String getFormat() {
        return format;
    }

    public void setFormat(String format) {
        this.format = format;
    }

    public String getExtension() {
        return extension;
    }

    public void setExtension(String extension) {
        this.extension = extension;
    }

    public Long getFileSize() {
        return fileSize;
    }

    public void setFileSize(Long fileSize) {
        this.fileSize = fileSize;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public LabelValueBean<String> getEntity() {
        return entity;
    }

    public void setEntity(LabelValueBean<String> entity) {
        this.entity = entity;
    }

    public LabelValueBean<String> getBrand() {
        return brand;
    }

    public void setBrand(LabelValueBean<String> brand) {
        this.brand = brand;
    }

    public LabelValueBean<String> getProduct() {
        return product;
    }

    public void setProduct(LabelValueBean<String> product) {
        this.product = product;
    }

    public LabelValueBean<String> getCollection() {
        return collection;
    }

    public void setCollection(LabelValueBean<String> collection) {
        this.collection = collection;
    }

    public LabelValueBean<String> getSubCollection() {
        return subCollection;
    }

    public void setSubCollection(LabelValueBean<String> subCollection) {
        this.subCollection = subCollection;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public LabelValueBean<String> getProgram() {
        return program;
    }

    public void setProgram(LabelValueBean<String> program) {
        this.program = program;
    }

    public String getVintage() {
        return vintage;
    }

    public void setVintage(String vintage) {
        this.vintage = vintage;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public String getRestrictedZone() {
        return restrictedZone;
    }

    public void setRestrictedZone(String restrictedZone) {
        this.restrictedZone = restrictedZone;
    }

    public LabelValueBean<String> getEvent() {
        return event;
    }

    public void setEvent(LabelValueBean<String> event) {
        this.event = event;
    }

    public LabelValueBean<String> getLanguage() {
        return language;
    }

    public void setLanguage(LabelValueBean<String> language) {
        this.language = language;
    }

    public String getGeographicLocation() {
        return geographicLocation;
    }

    public void setGeographicLocation(String geographicLocation) {
        this.geographicLocation = geographicLocation;
    }

    public String getWatermark() {
        return watermark;
    }

    public void setWatermark(String watermark) {
        this.watermark = watermark;
    }

    public Integer getPageNumber() {
        return pageNumber;
    }

    public void setPageNumber(Integer pageNumber) {
        this.pageNumber = pageNumber;
    }

    public String getSummary() {
        return summary;
    }

    public void setSummary(String summary) {
        this.summary = summary;
    }

    public String getAgentName() {
        return agentName;
    }

    public void setAgentName(String agentName) {
        this.agentName = agentName;
    }

    public String getCommissionedByName() {
        return commissionedByName;
    }

    public void setCommissionedByName(String commissionedByName) {
        this.commissionedByName = commissionedByName;
    }

    public String getCommissionedByDepartment() {
        return commissionedByDepartment;
    }

    public void setCommissionedByDepartment(String commissionedByDepartment) {
        this.commissionedByDepartment = commissionedByDepartment;
    }

    public LabelValueBean<Integer> getBestOf() {
        return bestOf;
    }

    public void setBestOf(LabelValueBean<Integer> bestOf) {
        this.bestOf = bestOf;
    }

    public String getMediaLocation() {
        return mediaLocation;
    }

    public void setMediaLocation(String mediaLocation) {
        this.mediaLocation = mediaLocation;
    }

    public LabelValueBean<Integer> getFullRights() {
        return fullRights;
    }

    public void setFullRights(LabelValueBean<Integer> fullRights) {
        this.fullRights = fullRights;
    }

    public LabelValueBean<String> getMediaUsage() {
        return mediaUsage;
    }

    public void setMediaUsage(LabelValueBean<String> mediaUsage) {
        this.mediaUsage = mediaUsage;
    }

    public Date getRightsEndDate() {
        return rightsEndDate;
    }

    public void setRightsEndDate(Date rightsEndDate) {
        this.rightsEndDate = rightsEndDate;
    }

    public String getGeographicRights() {
        return geographicRights;
    }

    public void setGeographicRights(String geographicRights) {
        this.geographicRights = geographicRights;
    }

    public LabelValueBean<Integer> getEvinConformity() {
        return evinConformity;
    }

    public void setEvinConformity(LabelValueBean<Integer> evinConformity) {
        this.evinConformity = evinConformity;
    }

    public String getContactReference() {
        return contactReference;
    }

    public void setContactReference(String contactReference) {
        this.contactReference = contactReference;
    }

    public LabelValueBean<String> getPublicationScope() {
        return publicationScope;
    }

    public void setPublicationScope(LabelValueBean<String> publicationScope) {
        this.publicationScope = publicationScope;
    }

    public String getRightsComment() {
        return rightsComment;
    }

    public void setRightsComment(String rightsComment) {
        this.rightsComment = rightsComment;
    }
}

And Content:

public class Content implements Serializable {

    private static final long serialVersionUID = 2999449587418137835L;

    private Boolean selected;
    private Boolean renditionInfoFetched;

    private String searchPageImageRendition;
    private String detailPageImageRendition;

    private String videoRendition;

    private Integer id;
    private String docName;
    private String docType;
    private String docTitle;
    private String docAuthor;
    private String securityGroup;
    private String docAccount;
    private Integer revLabel;
    private String profile;

    private Date createDate;
    private Date inDate;

    private String originalName;
    private String format;
    private String extension;
    private Long fileSize;

    private String author;

    private LabelValueBean<String> entity;
    private LabelValueBean<String> brand;
    private LabelValueBean<String> product;
    private LabelValueBean<String> collection;
    private LabelValueBean<String> subCollection;

    private String description;
    private LabelValueBean<String> program;
    private String vintage;
    private String model;
    private String restrictedZone;
    private LabelValueBean<String> event;
    private LabelValueBean<String> language;
    private String geographicLocation;
    private String watermark;
    private Integer pageNumber;
    private String summary;
    private String agentName;
    private String commissionedByName;
    private String commissionedByDepartment;
    private LabelValueBean<Integer> bestOf;
    private String mediaLocation;

    private LabelValueBean<Integer> fullRights;
    private LabelValueBean<String> mediaUsage;
    private Date rightsEndDate;
    private String geographicRights;
    private LabelValueBean<Integer> evinConformity;
    private String contactReference;
    private LabelValueBean<String> publicationScope;
    private String rightsComment;

    public Boolean getSelected() {
        return selected;
    }

    public void setSelected(Boolean selected) {
        this.selected = selected;
    }

    public Boolean getRenditionInfoFetched() {
        return renditionInfoFetched;
    }

    public void setRenditionInfoFetched(Boolean renditionInfoFetched) {
        this.renditionInfoFetched = renditionInfoFetched;
    }

    public String getSearchPageImageRendition() {
        return searchPageImageRendition;
    }

    public void setSearchPageImageRendition(String searchPageImageRendition) {
        this.searchPageImageRendition = searchPageImageRendition;
    }

    public String getDetailPageImageRendition() {
        return detailPageImageRendition;
    }

    public void setDetailPageImageRendition(String detailPageImageRendition) {
        this.detailPageImageRendition = detailPageImageRendition;
    }

    public String getVideoRendition() {
        return videoRendition;
    }

    public void setVideoRendition(String videoRendition) {
        this.videoRendition = videoRendition;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getDocName() {
        return docName;
    }

    public void setDocName(String docName) {
        this.docName = docName;
    }

    public String getDocType() {
        return docType;
    }

    public void setDocType(String docType) {
        this.docType = docType;
    }

    public String getDocTitle() {
        return docTitle;
    }

    public void setDocTitle(String docTitle) {
        this.docTitle = docTitle;
    }

    public String getDocAuthor() {
        return docAuthor;
    }

    public void setDocAuthor(String docAuthor) {
        this.docAuthor = docAuthor;
    }

    public String getSecurityGroup() {
        return securityGroup;
    }

    public void setSecurityGroup(String securityGroup) {
        this.securityGroup = securityGroup;
    }

    public String getDocAccount() {
        return docAccount;
    }

    public void setDocAccount(String docAccount) {
        this.docAccount = docAccount;
    }

    public Integer getRevLabel() {
        return revLabel;
    }

    public void setRevLabel(Integer revLabel) {
        this.revLabel = revLabel;
    }

    public String getProfile() {
        return profile;
    }

    public void setProfile(String profile) {
        this.profile = profile;
    }

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    public Date getInDate() {
        return inDate;
    }

    public void setInDate(Date inDate) {
        this.inDate = inDate;
    }

    public String getOriginalName() {
        return originalName;
    }

    public void setOriginalName(String originalName) {
        this.originalName = originalName;
    }

    public String getFormat() {
        return format;
    }

    public void setFormat(String format) {
        this.format = format;
    }

    public String getExtension() {
        return extension;
    }

    public void setExtension(String extension) {
        this.extension = extension;
    }

    public Long getFileSize() {
        return fileSize;
    }

    public void setFileSize(Long fileSize) {
        this.fileSize = fileSize;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public LabelValueBean<String> getEntity() {
        return entity;
    }

    public void setEntity(LabelValueBean<String> entity) {
        this.entity = entity;
    }

    public LabelValueBean<String> getBrand() {
        return brand;
    }

    public void setBrand(LabelValueBean<String> brand) {
        this.brand = brand;
    }

    public LabelValueBean<String> getProduct() {
        return product;
    }

    public void setProduct(LabelValueBean<String> product) {
        this.product = product;
    }

    public LabelValueBean<String> getCollection() {
        return collection;
    }

    public void setCollection(LabelValueBean<String> collection) {
        this.collection = collection;
    }

    public LabelValueBean<String> getSubCollection() {
        return subCollection;
    }

    public void setSubCollection(LabelValueBean<String> subCollection) {
        this.subCollection = subCollection;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public LabelValueBean<String> getProgram() {
        return program;
    }

    public void setProgram(LabelValueBean<String> program) {
        this.program = program;
    }

    public String getVintage() {
        return vintage;
    }

    public void setVintage(String vintage) {
        this.vintage = vintage;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public String getRestrictedZone() {
        return restrictedZone;
    }

    public void setRestrictedZone(String restrictedZone) {
        this.restrictedZone = restrictedZone;
    }

    public LabelValueBean<String> getEvent() {
        return event;
    }

    public void setEvent(LabelValueBean<String> event) {
        this.event = event;
    }

    public LabelValueBean<String> getLanguage() {
        return language;
    }

    public void setLanguage(LabelValueBean<String> language) {
        this.language = language;
    }

    public String getGeographicLocation() {
        return geographicLocation;
    }

    public void setGeographicLocation(String geographicLocation) {
        this.geographicLocation = geographicLocation;
    }

    public String getWatermark() {
        return watermark;
    }

    public void setWatermark(String watermark) {
        this.watermark = watermark;
    }

    public Integer getPageNumber() {
        return pageNumber;
    }

    public void setPageNumber(Integer pageNumber) {
        this.pageNumber = pageNumber;
    }

    public String getSummary() {
        return summary;
    }

    public void setSummary(String summary) {
        this.summary = summary;
    }

    public String getAgentName() {
        return agentName;
    }

    public void setAgentName(String agentName) {
        this.agentName = agentName;
    }

    public String getCommissionedByName() {
        return commissionedByName;
    }

    public void setCommissionedByName(String commissionedByName) {
        this.commissionedByName = commissionedByName;
    }

    public String getCommissionedByDepartment() {
        return commissionedByDepartment;
    }

    public void setCommissionedByDepartment(String commissionedByDepartment) {
        this.commissionedByDepartment = commissionedByDepartment;
    }

    public LabelValueBean<Integer> getBestOf() {
        return bestOf;
    }

    public void setBestOf(LabelValueBean<Integer> bestOf) {
        this.bestOf = bestOf;
    }

    public String getMediaLocation() {
        return mediaLocation;
    }

    public void setMediaLocation(String mediaLocation) {
        this.mediaLocation = mediaLocation;
    }

    public LabelValueBean<Integer> getFullRights() {
        return fullRights;
    }

    public void setFullRights(LabelValueBean<Integer> fullRights) {
        this.fullRights = fullRights;
    }

    public LabelValueBean<String> getMediaUsage() {
        return mediaUsage;
    }

    public void setMediaUsage(LabelValueBean<String> mediaUsage) {
        this.mediaUsage = mediaUsage;
    }

    public Date getRightsEndDate() {
        return rightsEndDate;
    }

    public void setRightsEndDate(Date rightsEndDate) {
        this.rightsEndDate = rightsEndDate;
    }

    public String getGeographicRights() {
        return geographicRights;
    }

    public void setGeographicRights(String geographicRights) {
        this.geographicRights = geographicRights;
    }

    public LabelValueBean<Integer> getEvinConformity() {
        return evinConformity;
    }

    public void setEvinConformity(LabelValueBean<Integer> evinConformity) {
        this.evinConformity = evinConformity;
    }

    public String getContactReference() {
        return contactReference;
    }

    public void setContactReference(String contactReference) {
        this.contactReference = contactReference;
    }

    public LabelValueBean<String> getPublicationScope() {
        return publicationScope;
    }

    public void setPublicationScope(LabelValueBean<String> publicationScope) {
        this.publicationScope = publicationScope;
    }

    public String getRightsComment() {
        return rightsComment;
    }

    public void setRightsComment(String rightsComment) {
        this.rightsComment = rightsComment;
    }
}

I am trying to copy properties from SearchContent to Content as:

Content content = new Content();        
Converter converter = new DateConverter(null);
BeanUtilsBean beanUtilsBean = BeanUtilsBean.getInstance();
beanUtilsBean.getConvertUtils().register(converter, Date.class);        
BeanUtils.copyProperties(searchContent, content);

System.out.println(searchContent);
System.out.println(content);

The Sysout is printing:

com.mhis.dam.service.search.bean.SearchContent[id=52906,docName=MHIS043570,docType=Images,docTitle=preview_1_8,docAuthor=sysadmin,securityGroup=Internal,docAccount=WF/017/DAM/000,revLabel=1,profile=DAMMedia,workflowStage=com.mhis.dam.generic.bean.LabelValueBean[label=Published,value=published],createDate=Fri Oct 18 15:30:35 IST 2013,inDate=Fri Oct 18 15:30:35 IST 2013,originalName=Vintage 2004 Gift Box & Bottle Black - hires.jpg,format=image/jpeg,extension=jpg,fileSize=2106898,author=Arjan,entity=com.mhis.dam.generic.bean.LabelValueBean[label=Dom Perignon,value=WF/017/DAM],brand=com.mhis.dam.generic.bean.LabelValueBean[label=Dom Perignon,value=WF/017/DAM/001],product=com.mhis.dam.generic.bean.LabelValueBean[label=Blanc,value=17_1_blanc],collection=com.mhis.dam.generic.bean.LabelValueBean[label=Pack shot,value=pack_shot_dp],subCollection=com.mhis.dam.generic.bean.LabelValueBean[label=Bottle shot,value=ps_bottle_dp],description=preview_1,program=com.mhis.dam.generic.bean.LabelValueBean[label=<null>,value=],vintage=,model=,restrictedZone=,event=com.mhis.dam.generic.bean.LabelValueBean[label=<null>,value=],language=com.mhis.dam.generic.bean.LabelValueBean[label=<null>,value=],geographicLocation=,watermark=,pageNumber=0,summary=,agentName=,commissionedByName=Nicolas,commissionedByDepartment=,bestOf=com.mhis.dam.generic.bean.LabelValueBean[label=<null>,value=0],mediaLocation=,fullRights=com.mhis.dam.generic.bean.LabelValueBean[label=<null>,value=1],mediaUsage=com.mhis.dam.generic.bean.LabelValueBean[label=<null>,value=],rightsEndDate=<null>,geographicRights=,evinConformity=com.mhis.dam.generic.bean.LabelValueBean[label=<null>,value=2],contactReference=,publicationScope=com.mhis.dam.generic.bean.LabelValueBean[label=Full public usage,value=fullPublic],rightsComment=]
com.mhis.dam.web.model.Content[selected=<null>,renditionInfoFetched=<null>,searchPageImageRendition=<null>,detailPageImageRendition=<null>,videoRendition=<null>,id=<null>,docName=<null>,docType=<null>,docTitle=<null>,docAuthor=<null>,securityGroup=<null>,docAccount=<null>,revLabel=<null>,profile=<null>,createDate=<null>,inDate=<null>,originalName=<null>,format=<null>,extension=<null>,fileSize=<null>,author=<null>,entity=<null>,brand=<null>,product=<null>,collection=<null>,subCollection=<null>,description=<null>,program=<null>,vintage=<null>,model=<null>,restrictedZone=<null>,event=<null>,language=<null>,geographicLocation=<null>,watermark=<null>,pageNumber=<null>,summary=<null>,agentName=<null>,commissionedByName=<null>,commissionedByDepartment=<null>,bestOf=<null>,mediaLocation=<null>,fullRights=<null>,mediaUsage=<null>,rightsEndDate=<null>,geographicRights=<null>,evinConformity=<null>,contactReference=<null>,publicationScope=<null>,rightsComment=<null>]

It is obvious to have null values for selected and renditionInfoFetched fields of the class Content, since they are not present in SearchContent but you can see all the other properties of Content is null. I am unable to find what I am doing wrong!

Any pointer would be very helpful.

This question is related to java properties apache-commons-beanutils

The answer is


As you can see in the below source code, BeanUtils.copyProperties internally uses reflection and there's additional internal cache lookup steps as well which is going to add cost wrt performance

 private static void copyProperties(Object source, Object target, @Nullable Class<?> editable,
                @Nullable String... ignoreProperties) throws BeansException {

            Assert.notNull(source, "Source must not be null");
            Assert.notNull(target, "Target must not be null");

            Class<?> actualEditable = target.getClass();
            if (editable != null) {
                if (!editable.isInstance(target)) {
                    throw new IllegalArgumentException("Target class [" + target.getClass().getName() +
                            "] not assignable to Editable class [" + editable.getName() + "]");
                }
                actualEditable = editable;
            }
            **PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);**
            List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);

            for (PropertyDescriptor targetPd : targetPds) {
                Method writeMethod = targetPd.getWriteMethod();
                if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
                    PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
                    if (sourcePd != null) {
                        Method readMethod = sourcePd.getReadMethod();
                        if (readMethod != null &&
                                ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
                            try {
                                if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                                    readMethod.setAccessible(true);
                                }
                                Object value = readMethod.invoke(source);
                                if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                                    writeMethod.setAccessible(true);
                                }
                                writeMethod.invoke(target, value);
                            }
                            catch (Throwable ex) {
                                throw new FatalBeanException(
                                        "Could not copy property '" + targetPd.getName() + "' from source to target", ex);
                            }
                        }
                    }
                }
            }
        }

So it's better to use plain setters given the cost reflection


There are two BeanUtils.copyProperties(parameter1, parameter2) in Java.

One is

org.apache.commons.beanutils.BeanUtils.copyProperties(Object dest, Object orig)

Another is

org.springframework.beans.BeanUtils.copyProperties(Object source, Object target)

Pay attention to the opposite position of parameters.