2015-02-10 10 views
6

Non voglio esporre le mie classi modello (entità jpa), sottoinsieme piuttosto diverso dei loro attributi con diversi oggetti di trasporto dati (DTO). L'idea è DTO CrudRepository <-> JpaRepository <-> entities e desidero esporre tramite Spring Data REST lo DTO CrudRepository.Come esporre il repository crudele DTO personalizzato con Spring data REST?

Esempio:

Entity:

@Entity 
@Table(name = "groups") 
public class Group { 

    private Long id; 
    private String name; 
    private Set<User> users; 
    // other attributes 

    @Id 
    @GeneratedValue 
    @Column(name = "group_id") 
    public Long getId() { 
     return id; 
    } 

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

    @Column(name = "name", nullable = false) 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @OneToMany(mappedBy = "group") 
    public Set<User> getUsers() { 
     return users; 
    } 

    public void setUsers(Set<User> users) { 
     this.users = users; 
    } 

    // other getters and setters 

} 

JpaRepository:

@RepositoryRestResource(exported = false) 
public interface GroupDao extends JpaRepository<Group, Long> { 
} 

DTO:

public class GroupWithoutRelationsDto { 

    private Long id; 
    private String name; 

    public Long getId() { 
     return id; 
    } 

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

    @NotBlank 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

} 

DTO CrudRepository:

public interface GroupDtoDao extends CrudRepository<GroupWithoutRelationsDto, Long> { 
} 

Implementazione:

@Repository 
public class GroupDtoDaoImpl extends GenericDtoDao<GroupWithoutRelationsDto, Group, Long> implements GroupDtoDao { 

    @Autowired 
    private GroupDao groupDao; 

    @Override 
    protected CrudRepository<Group, Long> getModelDao() { 
     return groupDao; 
    } 

    @Override 
    protected <S extends GroupWithoutRelationsDto> Long getDtoId(S dto) { 
     return dto.getId(); 
    } 

    @Override 
    protected Long getModelId(Group model) { 
     return model.getId(); 
    } 

    @Override 
    protected <S extends GroupWithoutRelationsDto> S modelToDto(Group model, S dto) { 
     dto.setId(model.getId()); 
     dto.setName(model.getName()); 
     return dto; 
    } 

    @Override 
    protected <S extends GroupWithoutRelationsDto> Group dtoToModel(S dto, Group model) { 
     model.setId(dto.getId()); 
     model.setName(dto.getName()); 
     return model; 
    } 

    @Override 
    protected Group newModel() { 
     return new Group(); 
    } 

    @Override 
    protected GroupWithoutRelationsDto newDto() { 
     return new GroupWithoutRelationsDto(); 
    } 

} 

GenericDtoDao:

@NoRepositoryBean 
public abstract class GenericDtoDao<D, M, ID extends Serializable> implements CrudRepository<D, ID> { 

    protected abstract CrudRepository<M, ID> getModelDao(); 

    protected abstract <S extends D> ID getDtoId(S dto); 

    protected abstract ID getModelId(M model); 

    protected abstract <S extends D> S modelToDto(M model, S dto); 

    protected abstract <S extends D> M dtoToModel(S dto, M model); 

    protected abstract M newModel(); 

    protected abstract D newDto(); 

    @Override 
    public D findOne(ID id) { 
     return modelToDto(getModelDao().findOne(id), newDto()); 
    } 

    @Override 
    public <S extends D> S save(S entity) { 
     Assert.notNull(entity, "The entity must not be null!"); 
     if (getDtoId(entity) == null) { 
      return create(entity); 
     } 
     return update(entity); 
    } 

    protected <S extends D> S create(S entity) { 
     Assert.notNull(entity, "The entity must not be null!"); 
     if (getDtoId(entity) != null) { 
      Assert.isTrue(!exists(getDtoId(entity)), "The entity ID must be null or not exist!"); 
     } 
     return modelToDto(getModelDao().save(dtoToModel(entity, newModel())), entity); 
    } 

    protected <S extends D> S update(S entity) { 
     Assert.notNull(entity, "The entity must not be null!"); 
     M model = getModelDao().findOne(getDtoId(entity)); 
     Assert.notNull(model, "The entity must exist!"); 
     return modelToDto(getModelDao().save(dtoToModel(entity, model)), entity); 
    } 

    // other CrudRepository methods 

} 

In questo esempio voglio esporre GroupDtoDao con il riposo dei dati di primavera.

In altri fagioli posso autorizzare sia GrouperDao che GroupDtoDao, quindi entrambi sono gestiti dal contesto di Spring. Se non annoto GroupDao con @RepositoryRestResource(exported = false), JpaRepository è esposto come servizio REST, quindi suppongo che i dati di Spring REST siano ben configurati.

Come posso dire di esporre il mio CrudRepository personalizzato?

+0

Lo hai mai capito? Sono interessato anche alla risposta, ma non ho una soluzione pulita. La mia migliore idea era quella di fornire un ObjectMapper JSON personalizzato e, all'interno del mappatore, eseguire la mappatura su DTO e scrivere invece il DTO. – Jay

+0

Non ho ancora trovato una soluzione automatica, ho ancora un CrudRestController personalizzato che avvolge i miei metodi DtoDaos –

risposta

2

C'è a JIRA issue per chiarire come procedere.

Per ora, il team SDR dice "In generale, consigliamo di utilizzare solo mixini Jackson per collegare serializzatori personalizzati, personalizzare l'output, ecc. Vedere lo Spring RESTBucks per un esempio."

Problemi correlati