2017-07-05 2 views
0

J'utilise Spring avec Spring Data JPA, j'ai rencontré un problème avec la copie en profondeur d'une entité complexe. L'entité A a 10 relations un-à-plusieurs (une seule est montrée ici pour la brièveté), je veux copier en profondeur cette entité sans les champs id des objets imbriqués B.Comment copier en profondeur une entité excluant l'identifiant de ses relations?

Je veux éviter d'utiliser la réflexion en raison de la performance. En utilisant Orika, j'ai réussi à exclure l'ID de A mais je n'ai pas réussi à exclure les ID des objets imbriqués.

@Entity 
public class A { 

    @Id 
    @GeneratedValue 
    private Long id; 
    //... 

    @OneToMany() 
    @JoinColumn(name = "a_id") 
    private Set<B> items; 

    // getters and setters 
} 

@Entity 
public class B { 

    @Id 
    @GeneratedValue 
    private Long id; 
    //... 

    public B() {} 

    // getters and setters 
} 

Comme vous pouvez le voir, je l'ai essayé d'exclure l'id de B en vous inscrivant une coutume MapperFactory mais il ne fonctionne pas comme prévu. Seul l'identifiant de A est exclu mais les éléments de la collection items ont toujours leurs identifiants.

A source = fetchFromDb(); 
MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build(); 
     mapperFactory.classMap(A.class, A.class) 
       .mapNulls(true) 
       .exclude("id") 
       .exclude("items['id']") 
       .byDefault() 
       .register(); 
     MapperFacade mapperFacade = mapperFactory.getMapperFacade(); 

     A dest = mapperFacade.map(source, A.class); 

Comment atteindre mon objectif? note - Je ne suis pas enfermé à Orika, toute autre solution est la bienvenue.

+1

« Je veux éviter d'utiliser la réflexion en raison d'une pénalité de performance », vous utilisez printemps, mise en veille prolongée ... c'est la réflexion. avec spring util ou apache vous pouvez le faire si vous ne voulez pas avec la réflexion directement – xyz

+0

si vous étiez vraiment préoccupé par la * performance de la réflexion * vous ne seriez pas en utilisant Spring ou Hibernate ou Orika qui comptent 100% sur la réflexion pour tout ce qu'ils faire. –

Répondre

0

J'ai réussi à résoudre le problème en implementing a custom ClassMapBuilder pour le mappeur Orika et en remplaçant sa méthode byDefault(). Maintenant, lorsque le mappeur est utilisé pour copier la classe de conteneur, tous les champs qui ont l'annotation Id sont exclus - il affecte tous les éléments imbriqués et multi-occurrences.

Pour faire le mappeur utiliser une coutume ClassMapBuilder:

MapperFactory mapperFactory = new DefaultMapperFactory 
      .Builder() 
      .classMapBuilderFactory(new IdExclusionClassMapBuilder.Factory()) 
      .build();