As imagens BLOB são exibidas apenas na atualização de uma página após uma atualização via p: dataTable ser feita no PrimeFaces

Estou exibindo imagens armazenadas na forma de BLOB no MySQL em um<p:graphicImage> do seguinte modo.

<p:dataTable var="row" value="#{testManagedBean}" lazy="true" editable="true" rows="10">
    <p:column headerText="id">
        <h:outputText value="#{row.brandId}"/>
    </p:column>

    <p:column headerText="Image">
        <p:cellEditor>
            <f:facet name="output">
                <p:graphicImage value="#{brandBean.image}" height="100" width="100">
                    <f:param name="id" value="#{row.brandId}"/>
                </p:graphicImage>
            </f:facet>
            <f:facet name="input">
                <p:graphicImage id="image" value="#{brandBean.image}" height="100" width="100">
                    <f:param name="id" value="#{row.brandId}"/>
                </p:graphicImage>
            </f:facet>
        </p:cellEditor>
    </p:column>

    <p:column headerText="Edit" width="50">
        <p:rowEditor/>
    </p:column>
</p:dataTable>

Durante a edição de uma linha, um<p:fileUpload> é exibido em um<p:overlayPanel>. Isso e muitas outras coisas são omitidas neste exemplo por uma questão de simplicidade, pois não estão relacionadas ao problema concreto.

O bean gerenciado JSF associado:

@ManagedBean
@ViewScoped
public final class TestManagedBean extends LazyDataModel<Brand> implements Serializable
{
    @EJB
    private final TestBeanLocal service=null;
    private static final long serialVersionUID = 1L;

    @Override
    public List<Brand> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
        setRowCount(3);
        return service.getList();
    }
}

O bean que recupera imagens do banco de dados com base em um identificador de linha exclusivo -BrandBean.

@ManagedBean
@ApplicationScoped
public final class BrandBean
{
    @EJB
    private final BrandBeanLocal service=null;
    public BrandBean() {}

    public StreamedContent getImage() throws IOException {
        FacesContext context = FacesContext.getCurrentInstance();

        if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
            return new DefaultStreamedContent();
        }
        else {
            String id = context.getExternalContext().getRequestParameterMap().get("id");
            System.out.println("id = "+id);
            byte[] bytes = service.findImageById(Long.parseLong(id));
            return bytes==null? new DefaultStreamedContent(new ByteArrayInputStream(new byte[0])):new DefaultStreamedContent(new ByteArrayInputStream(bytes));
        }
    }
}

Quando uma linha é atualizada (depois de editada), clique em um visto localizado (indicado por<p:rowEditor>) na última coluna da tabela de dados, ogetImage() método noBrandBean é invocado como deveria.

Isso acontece corretamente em um aplicativo em execução no servidor GlassFish 4.0 usando o PrimeFaces 5.0 e o JSF 2.2.6.

Uma nova imagem será exibida na tabela de dados imediatamente após a atualização de uma linha na tabela de dados (e consequentemente no banco de dados).

Há outro aplicativo em execução no servidor Tomcat 8.0.5 usando o Spring 4.0.0 GA no qualagetImage() método não é chamado depois que uma linha mantida pela tabela de dados é atualizada, resultando na exibição doimagem antiga (não a recém-atualizada) na tabela de dados (mesmo que as alterações sejam propagadas corretamente no banco de dados).

A imagem recém-atualizada é exibida apenas quando a página é atualizada pressionandoF5 (na maioria dos navegadores). Ele ainda não é exibido no carregamento da página (insira um URL na barra de endereços e pressione o botãoentrar chave).

Em outras palavras, quando uma linha de uma tabela de dados é atualizada, clique no visto indicado por<p:rowEditor>, agetImage() O método não é chamado (portanto, a nova imagem não é buscada no banco de dados para ser exibida no<p:graphicImage>) Esse método é chamado apenas quando a página é atualizada / recarregada pressionando o botãoF5 tecla de atalho.

Por que isso acontece? Como mostrar uma imagem recém-atualizada imediatamente após a atualização de uma linha?

Superficialmente, isso não deve estar relacionado ao Spring nem ao JPA (a operação de atualização é propagada corretamente no banco de dados após clicar no tique). Isso deve estar relacionado ao servidor Tomcat.

questionAnswers(2)

yourAnswerToTheQuestion