7 Hidden Pitfalls of Spring BeanUtils.copyProperties You Must Avoid
This article explains seven subtle issues when using Spring's BeanUtils.copyProperties—such as type mismatches, null overwrites, wrong imports, inner‑class copying failures, shallow copy side effects, and performance drawbacks—providing code examples and recommendations to avoid them.
In real business development we often need to copy properties between objects such as VO, BO, PO, DTO. Spring’s BeanUtils.copyProperties simplifies this but has many hidden pitfalls.
1: Property type mismatch causes copy failure
When the same field has different types in source and target (e.g., Long vs String), copyProperties returns null for that field.
public class BeanUtilsTest {
public static void main(String[] args) {
SourcePoJo sourcePoJo = new SourcePoJo("jingdong", (long) 35711);
TargetPoJo targetPoJo = new TargetPoJo();
BeanUtils.copyProperties(sourcePoJo,targetPoJo);
System.out.println(targetPoJo);
}
}
@Data
@AllArgsConstructor
class SourcePoJo{
private String username;
private Long id;
}
@Data
class TargetPoJo{
private String username;
private String id;
}Result: the id field becomes null because of the type mismatch.
2: Null values overwrite existing data
If the source contains null for a field, copyProperties will overwrite a non‑null target field, causing data loss.
public class BeanUtilsTest {
public static void main(String[] args) {
SourcePoJo sourcePoJo = new SourcePoJo();
sourcePoJo.setId("35711");
TargetPoJo targetPoJo = new TargetPoJo();
targetPoJo.setUsername("Joy");
BeanUtils.copyProperties(sourcePoJo,targetPoJo);
System.out.println(targetPoJo);
}
}
@Data
class SourcePoJo{
private String username;
private String id;
}
@Data
class TargetPoJo{
private String username;
private String id;
}3: Wrong import leads to unexpected behavior
Importing Spring’s BeanUtils vs Apache Commons BeanUtils swaps source and target order, which can cause subtle bugs.
//org.springframework.beans.BeanUtils(source, target)
public static void copyProperties(Object source, Object target) throws BeansException
//org.apache.commons.beanutils.BeanUtils(dest, orig)
public static void copyProperties(Object dest, Object orig) throws IllegalAccessException, InvocationTargetException4: Field reference not found makes debugging hard
Using copyProperties hides the origin of a field’s value, making traceability difficult during debugging.
5: Inner class data cannot be copied
Even if inner‑class fields match, Spring treats them as different and skips copying.
public class BeanUtilsTest {
public static void main(String[] args) {
SourcePoJo sourcePoJo = new SourcePoJo();
sourcePoJo.setUsername("joy");
SourcePoJo.InnerClass innerClass = new SourcePoJo.InnerClass("sourceInner");
sourcePoJo.innerClass = innerClass;
System.out.println(sourcePoJo);
TargetPoJo targetPoJo = new TargetPoJo();
BeanUtils.copyProperties(sourcePoJo,targetPoJo);
System.out.println(targetPoJo);
}
}
@Data
@AllArgsConstructor
public class SourcePoJo{
private String username;
private Long id;
public InnerClass innerClass;
@Data
@AllArgsConstructor
public static class InnerClass{ public String innerName; }
}
@Data
public class TargetPoJo{
private String username;
private Long id;
public InnerClass innerClass;
@Data
public static class InnerClass{ public String innerName; }
}6: BeanUtils.copyProperties performs shallow copy
It copies object references; modifying a referenced object after the copy changes the target’s data, which can be hard to trace.
public class BeanUtilsTest {
public static void main(String[] args) {
Person sourcePerson = new Person("sunyangwei", new Card("123456"));
Person targetPerson = new Person();
BeanUtils.copyProperties(sourcePerson, targetPerson);
sourcePerson.getCard().setNum("35711");
System.out.println(targetPerson);
}
}
@Data
@AllArgsConstructor
class Card { private String num; }
@NoArgsConstructor
@AllArgsConstructor
@Data
class Person { private String name; private Card card; }7: Reflection‑based copy is inefficient
Copying via reflection is much slower than direct setter calls, as shown by a benchmark copying 10,000 objects.
public class BeanUtilsTest {
public static void main(String[] args) {
long copyStartTime = System.currentTimeMillis();
User sourceUser = new User("sunyangwei");
User targetUser = new User();
for(int i = 0; i < 10000; i++) {
BeanUtils.copyProperties(sourceUser, targetUser);
}
System.out.println("copy方式:"+(System.currentTimeMillis()-copyStartTime));
long setStartTime = System.currentTimeMillis();
for(int i = 0; i < 10000; i++) {
targetUser.setUserName(sourceUser.getUserName());
}
System.out.println("set方式:"+(System.currentTimeMillis()-setStartTime));
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class User { private String userName; }Because these pitfalls are hard to detect and can cause serious bugs, it is recommended to avoid BeanUtils.copyProperties in production code.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
JD Cloud Developers
JD Cloud Developers (Developer of JD Technology) is a JD Technology Group platform offering technical sharing and communication for AI, cloud computing, IoT and related developers. It publishes JD product technical information, industry content, and tech event news. Embrace technology and partner with developers to envision the future.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
