La librairie BeanUtils propose une solution rapide pour copier les propriétés d’un objet à un autre.
Dans un projet où vous exposez des web services il est souvent obligatoire de passer par des DTO, si vous n’utilisez pas de librairie spécifique comme Dozer, le mapping d’un Object persistant à un DTO peut être une opération fastidieuse.
Dans cet article nous allons voir un exemple et une problématique.
Voici la dépendance à ajouter au fichier pom.xml :
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.1</version> </dependency>
Soit une classe utilitaire qui utilise BeanUtils:
public class NetapsysBeanUtils { private static final Logger LOGGER = LoggerFactory.getLogger(NetapsysBeanUtils.class); public static void copyProperties(final Object dest, final Object orig) { try { BeanUtils.copyProperties(dest, orig); } catch (final Exception e) { NetapsysBeanUtils.LOGGER.error(e.getMessage(), e); throw new UnsupportedOperationException("Impossible de copier les deux beans", e); } } }
Un test unitaire permet de vérifier le bon fonctionnement de cette class :
@RunWith(MockitoJUnitRunner.class) public class NetapsysBeanUtilsTest { @Test public void testNetapsysBeanUtils() { final UtilisateurDTO dto = new UtilisateurDTO(); dto.setId(null); dto.setPrenom("Netapsys"); final Utilisateur utilisateur = new Utilisateur(); NetapsysBeanUtils.copyProperties(utilisateur, dto); Assert.assertNull(utilisateur.getId()); Assert.assertNull(utilisateur.getPrenom()); } }
On s'aperçoit que l'id de l’utilisateur ne correspond pas au résultat attendu, au lieu de null on va avoir 0.
Si on utilise un ORM du type Hibernate c'est assez problématique en effet, il va croire que l'objet existe déjà et essayer de le mettre à jour.
Heureusement il existe une astuce.
On ajoute a la fonction copyProperties de la class NetapsysBeanUtils :
final ConvertUtilsBean convertUtilsBean = BeanUtilsBean.getInstance().getConvertUtils(); convertUtilsBean.register(new LongConverter(null), Long.class);
Finalement le test unitaire passe parfaitement.