[RESOLVIDO]Problema ao popular ArrayList

Tenho aqui um método do meu PessoaService chamado listar que deveria iterar pelo repositório de Pessoas e popular um novo ArrayList contendo PessoaDto para requisições GET.

public List<PessoaDto> listar() {
		List<PessoaDto> listaPessoas = new ArrayList<>();
		
		pessoaRepository.findAll().forEach(x->{
			PessoaDto pessoa = PessoaDtoBuilder.builder()
					.setNome(x.getNome())
					.setData(x.getDataDeNascimento())
					.setLogradouro(x.getEndereco().getLogradouro())
					.setCep(x.getEndereco().getCEP())
					.setNumero(x.getEndereco().getNumero())
					.setCidade(x.getEndereco().getCidade())
					.build();
			listaPessoas.add(pessoa);
		});
		
		listaPessoas.forEach(System.out::println);
		
		return listaPessoas;
	}

O problema é que quando chamada, esse código altera todos os objetos PessoaDto dentro do array, para a ultima iteração do forEach, e exibe todos os itens repetidos no postman. Porém consultando o banco de dados, os dados estão corretos. Alguém sabe me dizer o que pode estar acontecendo?

Saída do Postman:
Captura de tela de 2023-01-27 15-29-42

SELECT no dataBase:
Captura de tela de 2023-01-27 15-42-03

Este é o método que é usado no GET ou ha alguma outra camada com transformação de dados?

Este print imprime corretamente ou errado?

pessoaRepository.findAll() é um método “automatico” do Spring ou tem codigo teu?

é uma classe que herda do JPARepository. Tem métodos próprios.
O print imprime errado também, pois a lista está cheia de objetos com os dados do ultimo objeto. entende?

Mostra o método findAll e a classe PessoaDtoBuilder

O método findAll é um dos métodos presentes no SpringDataJPA. O JPA disponibiliza em tempo de execução uma implementação para a interface.

Este é o código do método não implementado:

List<T> findAll();

	/**
	 * Returns all instances of the type {@code T} with the given IDs.
	 * <p>
	 * If some or all ids are not found, no entities are returned for these IDs.
	 * <p>
	 * Note that the order of elements in the result is not guaranteed.
	 *
	 * @param ids must not be {@literal null} nor contain any {@literal null} values.
	 * @return guaranteed to be not {@literal null}. The size can be equal or less than the number of given
	 *         {@literal ids}.
	 * @throws IllegalArgumentException in case the given {@link Iterable ids} or one of its items is {@literal null}.
	 */

E este é o código do meu PessoaDtoBuilder:

package br.com.dev.domain.model.DTO;

public class PessoaDtoBuilder {
	private PessoaDto pessoa = new PessoaDto();
	private EnderecoDto endereco = new EnderecoDto();

	private static PessoaDtoBuilder instancia = null;
	
	private PessoaDtoBuilder() {
	}

	public static PessoaDtoBuilder builder() {
		if(instancia == null) {
			instancia = new PessoaDtoBuilder();
			return instancia;
		}
			
		return instancia;
	}
	
	public PessoaDtoBuilder setNome(String nome) {
		pessoa.setNome(nome);
		return this;
	}
	public PessoaDtoBuilder setData(String data) {
		pessoa.setDataDeNascimento(data);
		return this;
	}
	public PessoaDtoBuilder setLogradouro(String logradouro) {
		endereco.setLogradouro(logradouro);
		return this;
	}
	
	public PessoaDtoBuilder setCep(String cep) {
		endereco.setCep(cep);
		return this;
	}
	
	public PessoaDtoBuilder setNumero(Integer numero) {
		endereco.setNumero(numero);
		return this;
	}
	
	public PessoaDtoBuilder setCidade(String cidade) {
		endereco.setCidade(cidade);
		return this;
	}
	
	public PessoaDto build() {
		pessoa.setEnderecoDto(endereco);
		return pessoa;
	}
}

O erro estava na minha classe PessoaDtoBuilder. Estava usando o design pattern singleton pra garantir uma única instancia de builder. Só que todos os objetos do ArrayList apontavam pra essa mesma instancia, o que fazia com que na ultima iteração do forEach, o builder recebesse os dados do último objeto de pessoaRepository.findAll(), e por consequência todos os objetos PessoaDto dentro do array que apontavam para a unica instancia de builder.

Então foi só remover esse design pattern como abaixo:

package br.com.dev.domain.model.DTO;

public class PessoaDtoBuilder {
	private PessoaDto pessoa = new PessoaDto();
	private EnderecoDto endereco = new EnderecoDto();

	private static PessoaDtoBuilder instancia = null;
	
	private PessoaDtoBuilder() {
	}

	public static PessoaDtoBuilder builder() {
//		if(instancia == null) {
//			instancia = new PessoaDtoBuilder();
//			return instancia;
//		}
		instancia = new PessoaDtoBuilder();	
		return instancia;
	}
	
...

Que funcionou como esperado

Não precisas disto private static PessoaDtoBuilder instancia = null; nem do método statico builder, podes simplesmente tornal public o construtor da classe.