AutoComplete Primefaces + BD Como fazer?

Olá pessoal do Guj!
Estou tendo dificuldade em resolver um problema com o AutoComplete do Primefaces. Busquei no próprio site do Prime como fazer, mas nele mostra como realizar usando um ArrayList, e eu quero que busque do BD. Não tenho ideia de como posso resolver isso. Agradeço a ajuda deis de já. Ai vai o código que estou utilizando.

Parte da Pagina xhtml:

<p:dialog header="Nova Visita" widgetVar="dialogo2" draggable="true"
	width="790" height="400" resizable="false" modal="true"
	closable="false" position="center">
	<h:form id="formNovaVisita" enctype="multipart/form-data">
		<h:panelGrid columns="2" id="painel2">

			<p:outputLabel for="code2" value="Cpf/RG:" />
			<p:autoComplete id="code2" value="#{autoCompleteView.cpfAuto}"
				completeMethod="#{autoCompleteView.completeCode}" size="16"
				var="dv" itemLabel="#{dv.code}" itemValue="#{code}"
				converter="visitanteConverter" forceSelection="true"
				requiredMessage="O campo CPF/RG é obrigatorio"
				validatorMessage="O numero minimo de caracteres permitido é de 5 caracteres">
				<f:validateLength maximum="15" minimum="5" />
				<f:facet name="itemtip">
					<h:panelGrid columns="2" cellpadding="5">
						<f:facet name="header">
							<h:graphicImage width="50"
								url="http://localhost:8080/uploads/#{v.code}.png"
								style="margin-left:50px" />
						</f:facet>
						<h:outputText value="Nome:" />
						<h:outputText value="#{dv.nome}" />

						<h:outputText value="Empresa:" />
						<h:outputText value="#{dv.empresa}" />

					</h:panelGrid>
				</f:facet>
			</p:autoComplete>

			<p:outputLabel for="nome2" value="Nome:" />
			<p:inputText id="nome2" maxlength="40" size="40" type="text"
				required="true" requiredMessage="O campo Nome é obrigatorio"
				value="#{visitanteBean.visitante.nome}" forceSelection="true"/>


			<p:outputLabel for="empresa2" value="Nome da empresa:" />
			<p:autoComplete id="empresa2" maxlength="45" size="40"
				required="true"
				requiredMessage="O campo Nome da Empresa é obrigatorio"
				value="#{visitanteBean.visitante.empresa}" forceSelection="true">

			</p:autoComplete>

			<p:outputLabel for="obs" value="Observações da Visita:" />
			<p:inputTextarea id="obs" maxlength="200" size="60"
				value="#{visitanteBean.visitante.obs}" />

			<p:outputLabel for="subir" value="Foto:" />
			<h:panelGrid columns="2" id="painelFoto">
				<h:graphicImage width="150"
					url="http://localhost:8080/uploads/#{dv.code}.png" />
				<p:fileUpload id="subir" label="Procurar" mode="advanced"
					fileUploadListener="#{visitanteBean.subir}"
					invalidFileMessage="Tipo de Arquivo incorreto"
					invalidSizeMessage="Foto muito grande" update=":msg" auto="true"
					allowTypes="/(\.|\/)(gif|jpe?g|png)$/" />
			</h:panelGrid>
		</h:panelGrid>

		<h:panelGrid columns="3">
			<p:commandButton value="Salvar"
				actionListener="#{visitanteBean.salvar}"
				update=":formLista:table :msg :formNovaVisita:painel2" />
			<p:commandButton value="Limpar" ajax="true" immediate="true"
				type="reset" />
			<p:commandButton value="Fechar" oncomplete="PF('dialogo2').hide();" />
		</h:panelGrid>
	</h:form>
</p:dialog>

Visitante Converter:

@FacesConverter("visitanteConverter")
public class VisitanteConverter implements Converter {

public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
    if(value != null && value.trim().length() > 0) {
        try {
        	VisitaService service = (VisitaService) fc.getExternalContext().getApplicationMap().get("visitaService");
            return service.getVisitas().get(Integer.parseInt(value));
        } catch(NumberFormatException e) {
            throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro de conversão", "Visitante não é valido."));
        }
    }
    else {
        return null;
    }
}

public String getAsString(FacesContext fc, UIComponent uic, Object object) {
    if(object != null) {
        return String.valueOf(((Visitante) object).getCodigo());
    }
    else {
        return null;
    }
}   
}   

Visita Service:

@ManagedBean(name="visitaService", eager = true)
@ApplicationScoped
public class VisitaService {
  
private List<Visitante> visitas; 
 
@PostConstruct
public void  init() {
    try {
        visitas = new ArrayList<Visitante>();
        VisitanteDAO dao = new VisitanteDAO();
        visitas = dao.listar();
    } catch (RuntimeException e) {
        Messages.addGlobalError("Erro ao listar");
        e.printStackTrace();
    }
}
  
public List<Visitante> getVisitas() {
    return visitas;
}
}

AutoCompleteView:

@ManagedBean
public class AutoCompleteView {

private Visitante cpfAuto;

@ManagedProperty("#{visitaService}")
private VisitaService service;
 
public List<Visitante> completeCode(String query) {
    List<Visitante> allVisitas = service.getVisitas();
    List<Visitante> visitasFiltradas = new ArrayList<Visitante>();
     
    for (int i = 0; i < allVisitas.size(); i++) {
    	Visitante skin = allVisitas.get(i);
        if(skin.getCode().toLowerCase().startsWith(query)) {
        	visitasFiltradas.add(skin);
        }
    }
     
    return visitasFiltradas;
}

public void onItemSelect(SelectEvent event) {
    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Item Selected", event.getObject().toString()));
}

public Visitante getCpfAuto() {
	return cpfAuto;
}

public void setCpfAuto(Visitante cpfAuto) {
	this.cpfAuto = cpfAuto;
}
}