Reputation: 329
I have a Repository and in this interface I have a method that would like to return a ComentarioEditalDto instead of an ComentarioEdital, but when I call this method an exception is thrown, telling me that I don't have a Converter, how can I convert to return a instance of another class?.
import br.edu.ifrn.rederenova.dto.ComentarioEditalDto;
import br.edu.ifrn.rederenova.model.ComentarioEdital;
import java.util.List;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface ComentarioRepository extends CrudRepository<ComentarioEdital, Long>{
@Query(value = "SELECT c.id, c.texto, c.data_ultima_edicao, c.autor_id, " +
"c.data_criacao, c.edital_id, c.excluida FROM comentario_edital c INNER JOIN edital e ON e.id = c.edital_id " +
"WHERE (c.excluida = FALSE OR c.excluida IS NULL) AND e.numero = :numero ORDER BY c.data_criacao DESC",
nativeQuery = true)
public List<ComentarioEditalDto> findAllByEdital(@Param("numero") String nuEdital);
}
I removed Gets and Sets
import br.edu.ifrn.rederenova.model.ComentarioEdital;
import br.edu.ifrn.rederenova.model.Edital;
import br.edu.ifrn.rederenova.model.Usuario;
import java.util.Calendar;
import java.util.List;
public class ComentarioEditalDto {
private Long id;
private String texto;
private Calendar dataCriacao;
private Calendar dataUltimaEdicao;
private List<ComentarioEdital> respostasComentario;
private Usuario autor;
private Edital edital;
private Boolean excluida;
}
I removed Gets and Set
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable;
import java.util.Calendar;
import java.util.List;
import java.util.Objects;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotBlank;
import org.springframework.format.annotation.DateTimeFormat;
@Entity
@SequenceGenerator(allocationSize = 1, initialValue = 1, name = "comentario_seq", sequenceName = "comentario_seq")
public class ComentarioEdital implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "comentario_seq")
private Long id;
@NotBlank(message = "Não deve estar vazio")
private String texto;
@Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(pattern = "dd/MM/yyyy")
private Calendar dataCriacao;
@Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(pattern = "dd/MM/yyyy")
private Calendar dataUltimaEdicao;
@OneToMany(cascade = {CascadeType.REMOVE, CascadeType.REFRESH}, fetch = FetchType.EAGER)
@JoinTable(name = "respostas_comentario",
joinColumns = @JoinColumn(name = "pergunta_id"),
inverseJoinColumns = @JoinColumn(name = "resposta_id"))
private List<ComentarioEdital> respostasComentario;
@ManyToOne(fetch = FetchType.EAGER)
private Usuario autor;
@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
private Edital edital;
@JsonIgnore
private Boolean excluida;
}
A little of the exception
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [br.edu.ifrn.rederenova.dto.ComentarioEditalDto] at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:321) ~[spring-core-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:194) ~[spring-core-5.0.7.RELEASE.jar:5.0.7.RELEASE]
Upvotes: 4
Views: 27848
Reputation: 41
Just change the class ComentarioEditalDto
to an Interface, like this:
public interface ComentarioEditalDto {
BigInteger getId();
String getTexto();
Calendar getDataCriacao();
Calendar getDataUltimaEdicao();
List<ComentarioEdital> getRespostasComentario(); --> attention to this ComentarioEdital
Usuario getAutor();
Edital getEdital();
Boolean isExcluida();
}
Upvotes: 0
Reputation: 3166
You need to return a dto in your @Query
@Query(value = "SELECT new br.edu.ifrn.rederenova.dto.ComentarioEditalDto(c.id, c.texto, c.dataCriacao, c.dataUltimaEdicao, c.excluida) " +
"FROM ComentarioEdital c ....
SELECT new package.DTOClass
as SELECT new br.edu.ifrn.rederenova.dto.ComentarioEditalDto
ComentarioEditalDto
define a constructor with the same parameters you are passing to your SELECT new br.edu.ifrn.rederenova.dto.ComentarioEditalDto
Upvotes: 17
Reputation: 603
First of all do not remove getter/setters of your POJOs. Second if you want to return a custom object from your repository I recomed you to use QueryDSL. You can use it like this: Repository:
@Repository
public interface EntityRepository extends JpaRepository<Entity, Long>, EntityRepositoryCustom, QuerydslPredicateExecutor<Entity> {
}
Custom repository:
public interface EntityRepositoryCustom {
List<EntityDTO> getEntityDTOsByCriteria(String arg0, String args1);
}
Repository impl:
public class EntityRepositoryImpl implements EntityRepositoryCustom {
@Autowired
private CardHolderRepository cardHolderRepository;
@Autowired
private EntityManager entityManager;
@Override
public List<EntityDTO> getEntityDTOsByCriteria(String arg0, String args1) {
final List<EntityDTO> projections = new JPAQuery(entityManager, jpqlTemplates)
.from(entity)
.orderBy(entity.somefield.asc())
.list(ConstructorExpression.create(EntityDTO.class, entity.somefield,
entity.someOtherfield));
return projections;
}
Upvotes: 0