Maneira correta ou boas praticas ao utilizar JAVA, JPA

Sou novo em java e estou com uma duvida com devo seguir com a implementação do meu projeto.

Tenho uma classe que é a cotação e outra que são itens dessa cotação.
Preciso criar um JSON dessa cotação.

Ai vem minha duvida da melhor forma de implementar, utilizo a própria classe da entidade usando Construtores, ou Factory Method, ou builder, ou crio uma nova classe só para a criação do JSON.

Talvez seja uma pergunta bem abrangente, mas como disse estou começando em java.

Exemplo das duas classes, só postei um pedaço delas.

@Entity
@NamedQuery(name = "Cotacao.findAll", query = "SELECT c FROM Cotacao c")
public class Cotacao {
	
	@Id
	private Integer idcotacao;

	@OneToMany(mappedBy = "cotacao")
	private List<DetalheCotacao> detalhecotacaos;
}
@Entity
@NamedQuery(name = "DetalheCotacao.findAll", query = "SELECT d FROM DetalheCotacao d")
public class DetalheCotacao implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	private Integer iddetalhecotacao;

	@ManyToOne
	@JoinColumn(name = "IDCOTACAO")
	private Cotacao cotacao;
}

Eu prefiro sempre utilizar DTO’s para expor informações, dependendo de como o projeto cresce e se comporta, utilizar as entidades para fazer esse trabalho pode se tornar algo custoso de manutenção ou para implementação de novas features.

Mas neste caso todas as consultar JPA que não retorne todos os campos, vai retornar objetos, certo?

ex: SELECT c.idcotacao, c.descricao FROM Cotacao c

Nesse caso vou ter que percorrer com um for e inserir na classe DTO?
Se sim, não teria uma perca de desempenho, ou seria insignificante?

Muito obrigado pela responta.

Sim, você faria a consulta JPA, ela te retornaria a entidade, e com a entidade você mapearia isso para um DTO, não é um trabalho custoso pois tem API’s que fazem isso como o modelMapper por exemplo!
Eu acho insignificante, nunca tive problemas com isso, mas tudo deve ser pensado e testado, cada caso é um caso, sempre temos que analizar o que chamamos de “trade-off”, se ganha de um lado porém se perde de outro.

Nos projetos que trabalho, sempre usamos classes (tipo DTO, mas com outra nomenclatura) para retornar os objetos. Geralmente gosto de criar uma classe que recebe a entidade como parâmetro no construtor e saio setando os atributos que quero retornar. E deixo essa classe somente com métodos de acesso (métodos get). E a criação desses DTOs sempre faço na camada de apresentação.

Também sugiro usar “DTO”, pra ter melhor controle e otimizar pra cada resultado (json). “Entidade” já está no banco, faz o SQL nas tabelas desejadas e joga o resultado diretamente no DTO. De preferência com JDBC Template por ser mais leve.

O foreach vai existir sempre, seja na mao ou por baixo dos panos com alguma ferramenta de persistência.