quinta-feira, 5 de junho de 2008

Broken pipe na conexão com socket no banco de dados

Bom, pra não perder o histórico do blog (já que realmente não costumo postar muito) vou deixar a solução digamos meio que "gambearristica" encontrada abaixo, mas que me resolveu o problema no momento e vou criar outro tópico sobre esse mesmo assunto, pois consegui resolver o problema de forma efetiva sem alterar qualquer configuração no banco de dados, a solução (ao meu ver mais correta) está nesse link: http://netbeando.blogspot.com/2009/03/broken-pipe-solucao-correta.html

Mas caso ela não resolva o seu problema, parta para algo mais radical como a solução abaixo:

Fiquei muito tempo tentando descobrir como resolver um problema que ocorria todos os dias em um sistema que ficava aguardando conexões de clientes através de um socket, o problema é que como as conexões eram esporádicas, ou seja, ficavam as vezes mais de 10 horas sem receber conexão alguma e no momento que algum cliente tentava se conectar depois deste período de inatividade ocorria o erro no socket com a mensagem "broken pipe", bom, tentei resolver de várias formas, mas infelizmente por uma série de motivos a única forma que resolveu efetivamente foi aumentando o timeout do próprio banco de dados. No meu caso eu estou utilizando o mysql, então se você acessar o prompt do mysql e digitar:

show variables

Serão mostradas todas as variáveis utilizadas por esse banco de dados, a que realmente interessa é a:

wait_timeout

Inicialmente essa variável está definida para 28800 , li sobre o assunto e me parece que definindo como ZERO as conexões do banco de dados ficam sem timeout, acabei não optando por essa opção, simplesmente aumentei esse timeout para que ficasse a minha conexão ativa por mais de 12h mesmo sem inatividade, resolveu 100% o problema.

Bom, agora você deve estar se perguntando como alterar o conteúdo desta variável, no meu caso, como o sistema operacional que esta instalado o sistema é um Linux, bastou acessar o arquivo /etc/mysql/my.cnf , editar com um editor de textos qualquer e trocar o valor da variável... claro tive que reiniciar o mysql depois.

T+

sábado, 31 de maio de 2008

JPA x Alterações (externas) na base de dados

Quebrei a cabeça muito tempo por um problema que estava acontecendo em um sistema que utiliza JPA para conexão com o banco de dados, o que ocorria era o seguinte, existem 2 sistemas separados que conectam na mesma base de dados e fazem alterações, o problema era que um não conseguia visualizar as alterações do outro, ou seja, digamos que um dos sistema seja para autorização de vendas e verifique o saldo de determinado cartão e o outro sistema a cada mês retornava o limite de crédito para esse cartão assim ele continuaria comprando normalmente no novo mês, o caso é que o sistema que autoriza as vendas não conseguia vizualiar a alteração de restituição do saldo feita pelo outro sistema, então o cartão embora tivesse saldo, pro sistema de autorização continuava sem... depois eu notei acontecia o mesmo problema se eu alterasse os registros diretamente no banco de dados, os sistemas não conseguiam fazer os selects e trazer os dados atualizados.... eis a solução adotada:

Nas classes das entidades mapeadas, bastou incluir um novo parâmetro nas namedqueries, coloquei em negrito esse novo parâmetro, veja como ficou um pedaço do código por exemplo:

@Entity
@Table(name = "cartoes")
@NamedQueries({@NamedQuery(name = "Cartoes.findByCodigo", query = "SELECT f FROM Cartoes c WHERE c.codigo = :codigo", hints=@QueryHint(name="toplink.refresh", value="true")), @NamedQuery(...})

public class Cartoes implements Serializable {...

Notou o "hints=@QueryHint(name="toplink.refresh", value="true")"? Simples não?

Porém, se você utilizou o createquery na "mão" poderia usar assim, por exemplo:

Query query = this.entityManager.createQuery("SELECT c FROM EmpresasProdutos c WHERE c.empresa.codigo = :empresa AND c.tipo=:produto").setHint("toplink.refresh", "true");

T+

terça-feira, 26 de fevereiro de 2008

NetBeans 6.0.1 - Herança visual

Finalmente existe a possibilidade de se conseguir fazer herança visual (dos forms) no NetBeans, não estou me referendo aos usuais templates que todos acabam mencionando... estou falando de herança mesmo, aquela que o Delphi oferece, ou seja, você cria um formulário padrão e depois herda as características deste formulário para outros, e quando você alterar o formulário padrão essas alterações são espelhadas nos seus "filhos", coisa que os templates não conseguem fazer.

Bom, segui fielmente o que contém nesse link http://wiki.netbeans.org/FaqFormExtendingForms

Mas pra tentar simplificar vou colocar os passos abaixo:

1) Crie um novo projeto
2) Crie um formulário que será o nosso padrão, pode ser um JFrame por exemplo, de o nome de BaseForm para ele e insira um método que retorne o JPanel vazio como um container, como no exemplo abaixo:

public Container getJPanel1() {
return jPanel1;
}

3) Insira os componentes que serão modelos para todos os formulários filhos
4) Insira um JPanel e deixe ele totalmente vazio
5) Você vai precisar criar uma classe chamada BaseFormBeanInfo e que o extends dela seja de SimpleBeanInfo, como no exemplo abaixo:

public class BaseFormBeanInfo extends java.beans.SimpleBeanInfo {
//public final static Class beanClass = BaseForm.class;
private BeanDescriptor beanDescriptor;

public BaseFormBeanInfo() {
super();
}

@Override
public BeanDescriptor getBeanDescriptor() {
if (beanDescriptor == null) {
// BaseForm é o formulário padrão
beanDescriptor = new BeanDescriptor(BaseForm.class);
// getJPanel1 é o nome do método que retorna o JPanel vazio que está no BaseForm
beanDescriptor.setValue("containerDelegate", "getJPanel1"); // g
}
return beanDescriptor;
}
}

ATENÇÃO: O nome BaseFormBeanInfo não é por acaso, tem que seguir esse padrão, caso o seu formulário padrão se chamasse PadraoForm a classe BeanInfo iria se chamar PadraoFormBeanInfo.

6) Compile o projeto
7) Vamos criar o formulário filho a partir do BaseForm, para isso crie um formulário do tipo "Formulário Bean" (BeanForm) e quando for solicitada qual é a superclasse informe "BaseForm" (sem as áspas é claro).
8) Pronto! Mas como nem tudo são flores, o que você vai visualizar no seu formulário filho é justamente aquele JPanel que foi inserido vazio na superclasse, é nele que você vai inserir os seus novos componentes, etc...

Agora você deve estar se perguntando... mas se eu tenho um botão de ok no BaseForm e quero mudar o seu modo de funcionamento, como poderia alterar no meu formulário herdado o código definido no BaseForm? Muito simples, no evento de click do botão no BaseForm você poderia colocar a chamada de um método seu, por exemplo:

cliqueOk();

Esse método você deve declarar como sendo protected dessa forma você redefine ele na sua classe herdada e ele passa a executar o código novo, caso contrário ele executa o código que foi definido na superclasse.

Se preferir faça download do projeto de exemplo aqui.

[]´s

terça-feira, 8 de janeiro de 2008

DropDown List com lista fixa não edita registro

Bom, acredito ter encontrado um bug no NetBeans 6.0, ou então não consegui configurar corretamente o meu dropdown em um projeto web, ao utiliza-lo com uma lista fixa de opção (não como FK de outra tabela) como por exemplo para controle de status de registros (A - Ativo, B - Bloqueado, etc...), ao se alterar a opção de um registro que já está cadastrado ele não cria o evento de alteração/edição do registro que está posicionado na tabela, ou seja, mesmo executando o código para salvar o registro o mesmo não é atualizado. Para resolver esse problema cliquei com o botão direito sobre o dropdown do meu formulário e selecionei a opção "Edit Event Handler" e inseri o código abaixo:

getSession1().getClientesDataProvider().setValue("status", getSession1().getClientesDataProvider().getCursorRow(), event.getNewValue().toString());

Esse código força a alteração do registro inserindo no campo status o valor selecionado no dropdown.

T+

sábado, 5 de janeiro de 2008

Selecionando um item em um dropDown List em uma página JSP

Digamos que você esteja querendo adicionar com dropDown com algumas opções para que o usuário selecione em alguma página de cadastro, por exemplo para controlar o status de um determinado cliente, então após criar a página JSP e inserir os objetos de acesso ao banco de dados, basta inserir o dropdown na página, clicar com o botão da direita sobre ele e configurar as opções default, feito isso clique novamente com o botão direito sobre o dropdown e selecione a opção Property Bindings..., nessa opção deverá ser selecionado 2 itens, o primeiro é o "items" que deve ser relacionado com a propriedade options do dropdown e a outra é a "selected" que deverá ser relacionada com o campo do rowset que deverá fazer o relacionamento.

Pronto, assim quando você estiver utilizando a página JSP para editar um cadastro já inserido no banco de dados, o dropdown estará com o item corretamente selecionado.