Resolução de Problemas de Aplicativos JPA
Use estas informações para localizar vários problemas conhecidos com aplicativos Java™ Persistence API (JPA).
Procedimento
- Resolva problemas NoClassDefFoundError para as classes org.apache.openjpa.* ou com.ibm.websphere.persistence.* ao usar o JAR thinclient do JPA.
A partir do WebSphere Application Server Versão 9.0, há dois arquivos JAR thinclient do JPA disponíveis. com.ibm.ws.jpa-2.1.thinclient_9.0.jar: inclui interfaces de especificação JPA 2.1, bem como classes e interfaces do EclipseLink. com.ibm.ws.jpa-2.0.thinclient_9.0.jar: inclui interfaces de especificação JPA 2.0, bem como classes e interfaces do WSJPA e OpenJPA. Antes da versão 9, esse JAR era nomeado com.ibm.ws.jpa_X.X.jar.
Evitar Problemas:
Se o aplicativo depender das classes ou do comportamento específicos do OpenJPA ou WSJPA e você incluiu com.ibm.ws.jpa-2.1.thinclient_9.0.jar no caminho da classe, em vez disso, deverá usar o com.ibm.ws.jpa-2.0.thinclient_9.0.jar no caminho da classe thinclient.
gotcha - Resolva problemas NoClassDefFoundError para as classes org.apache.openjpa.* ou com.ibm.websphere.persistence.* a partir de um aplicativo em execução em um WebSphere Application Server. No WebSphere Application Server Versão 9.0, o provedor de persistência padrão para novos perfis foi mudado de OpenJPA para EclipseLink. Se você executar um aplicativo OpenJPA quando o WebSphere estiver configurado para usar o EclipseLink, resultará em NoClassDefFoundError, porque as classes OpenJPA não estarão disponíveis para o tempo de execução do servidor quando estiverem configuradas para usar o JPA 2.1.Nota: Se você usar o conjunto de ferramentas de migração do WebSphere Application Server Versão 8.5.5 para migrar para o WebSphere Application Server Versão 9.0, o nível do JPA será configurado para 2.0 automaticamente, que usará o mesmo provedor JPA que no WebSphere Application Server Versão 8.5.5.
Para resolver o problema, reconfigure o servidor ou o cluster para usar o JPA 2.0. Isso configura o OpenJPA como o provedor de persistência padrão.
- Resolva problemas de NoClassDefFoundError: org.apache.openjpa.enhance.PersistenceCapable. Os aplicativos que usam o OpenJPA podem executar ferramentas de aprimoramento no momento da criação nas classes de entidades. O uso de aprimoramento do OpenJPA inclui referências nas classes, como org.apache.openjpa.enhance.PersistenceCapable para classes compiladas. No WebSphere Application Server Versão 9.0, o provedor de persistência padrão para novos perfis foi mudado de OpenJPA para EclipseLink. Se você tentar executar um aplicativo aprimorado OpenJPA quando o WebSphere Application Server estiver configurado para usar o EclipseLink, resultará em NoClassDefFoundError, porque as classes OpenJPA não estarão disponíveis para o tempo de execução do servidor quando estiverem configuradas para usar o JPA 2.1.Nota: Se você usar o conjunto de ferramentas de migração do WebSphere Application Server Versão 8.5.5 para migrar para o WebSphere Application Server Versão 9.0, o nível do JPA será configurado para 2.0 automaticamente, que usará o mesmo provedor JPA que no WebSphere Application Server Versão 8.5.5.Para resolver o problema, é possível:
- Reconfigurar o servidor ou o cluster para usar o JPA 2.0. Isso configura o OpenJPA como o provedor de persistência padrão.
- Recompile o aplicativo e aprimore as entidades usando o aprimoramento do EclipseLink, em vez de o aprimoramento do OpenJPA.
- Reveja as mensagens que estão relacionadas às transações.
Sob determinadas condições, uma mensagem como a seguinte pode ser registrada: Não é possível executar {0} em uma transação gerenciada do WebSphere. O WebSphere não suporta manipulação direta de transações gerenciadas.
Este erro provavelmente seja causado por uma origem de dados que não está configurada corretamente como <non-jta-data-source>. Consulte o tópico do centro de informações, Associando Provedores e Origens de Dados, sobre como configurar uma origem de dados para ser usada como um <non-jta-data-source>.
- Resolva os problemas de classe que não foram aprimoradas por tempo de execução.
É difícil diagnosticar estas situações. Muitas vezes, você pode rastrear o problema novamente para uma falta de aprimoramento de OpenJPA das classes de entidade. Exemplos dessas situações podem ser detectar quando entidades não forem aptas para persistência. Procure por uma mensagem como a seguinte no log: Essa configuração não permite a otimização do tempo de execução, porém, os seguintes tipos listados não foram aprimorados no tempo de construção ou no tempo de carregamento da classe com um agente Java: "{0}".
Essa mensagem indica que o aprimoramento de tempo de execução esperado não ocorreu nos tipos de entidade listados. Na maioria dos casos, esse erro é apenas uma falha de tempo de construção e o PCEnhancer deve ser executado nas classes listadas. Isso também pode indicar um problema mais envolvido, especialmente se for esperado que a transformação do carregador de classe do contêiner faça o aprimoramento da entidade.
- Resolva problemas com cursores fechados. A seguir está uma exceção doDB2 localizada no log org.apache.openjpa.persistence.PersistenceException:
[ibm][db2][jcc][10120][10898] Invalid operation: result set is closed can be a problema de configuração do WebSphere Application Server.
Por padrão, o servidor de aplicativos configura a propriedade customizada resultSetHoldability com um valor 2 (CLOSE_CURSORS_AT_COMMIT) . Essa propriedade faz com que o DB2 feche seu resultSet/cursor nos limites da transação. Apesar do valor 1 (HOLD_CURSORS_OVER_COMMIT) do resultSetHoldability do DB2, o servidor de aplicativos retém o valor padrão 2 para evitar quebrar a compatibilidade com liberações anteriores do servidor de aplicativos. O padrão pode ser alterado.Atenção: Se origem de dados for uma origem de dados XA, defina uma nova propriedade customizada na origem de dados na qual nome_da_propriedade = downgradeHoldCursorsUnderXa e valor booleano = true.Evitar Problemas: Na Versão 8.0, se uma origem de dados DB2 XA for usada, a seguinte configuração será necessária para resolver o problema conjunto de resultados fechado:
- Use o FP4 do DB2 Versão 9.1 (para APAR IZ18072) ou uma versão superior.
- Inclua a propriedade customizada name="downgradeHoldCursorsUnderXa", value="true" e type="java.lang.Boolean"
- Inclua a propriedade customizada name="resultSetHoldability", value="1" e type="java.lang.Integer"
- Evite o uso de EntityManager multiencadeado. Se uma exceção ocorrer com o seguintes texto de mensagem, você pode estar suportando acidentalmente o uso de uma EntityManager em diversos encadeamentos.De acordo com a especificação de JPA, os EntityManagers devem ser utilizados por um encadeamento único. Você pode receber uma mensagem de exceção parecida com a seguinte (nesse contexto, brokers e EntityManagers são essencialmente a mesma coisa):Há algumas maneiras de tratar este problema:
Diversos encadeamentos simultâneos tentaram acessar um broker único. Por padrão, os brokers não são thread safe. Se precisar e desejar que um broker seja acessado por mais de um encadeamento, configure a propriedade openjpa.Multithreaded para true para substituir o comportamento padrão.
Boas Práticas: Use o padrão obter-usar-fechar ao usar contextos de persistência (estendida) gerenciados por aplicativo. Lembre-se de fechar o EntityManager antes de sair do método que utilizou o EntityManager. Deixar o EntityManager aberto pode fazer com que outros encadeamentos usem acidentalmente a mesma instância EntityManager ao mesmo tempo, o que pode consumir recursos do sistema.bprac
- Altere o aplicativo para usar contextos de persistência gerenciados por contêiner, injetando a instância EntityManager por meio da anotação @PersistenceContext, se o modelo de programação do aplicativo for acessível para essa mudança. Essencialmente, isso impinge o padrão obter-usar-fechar ao dar suporte ao contêiner para fazer o gerenciamento.
- Conforme documentado nesse texto de exceção, uma solução alternativa rápida
é configurar o OpenJPA para requerer acesso multiencadeado aos EntityManagers
na propriedade openjpa.Multithreaded. Ativar essa propriedade pode introduzir
sobrecarga desnecessária.
Evitar Problemas: As variáveis de instância para servlets são compartilhadas automaticamente por todas as instâncias do servlet. Usar a anotação @PersistenceContext em uma variável de instância de servlet pode resultar em um acesso multiencadeado não intencional ao mesmo EntityManager. Além disso, quaisquer EntityManagers injetados dessa maneira não são limpos pelo contêiner até o aplicativo ser parado. Para os servlets, a melhor opção é usar a anotação @PersistenceUnit para injetar um EntityManagerFactory. gotcha
- Se estiver usando um bloqueio otimista, lembre-se das condições
de versão.
Na arquitetura da JPA, o provedor de persistência usa a propriedade de versão
para executar bloqueio otimista e semânticas de simultaneidade para uma entidade de
persistência, por exemplo:
@Entity public class VersionedTimestampEntity { @Id private int id; @Version private java.sql.Timestamp version; .... }
O provedor atualiza a propriedade de versão para um novo valor quando uma entidade for gravada no banco de dados. Durante uma operação de mesclagem de entidade, o provedor de persistência examina se a entidade que está sendo mesclada é uma cópia vencida da entidade. Se a operação falhou devido a uma condição de versão antiga, uma OptimisticLockException ocorrerá. A propriedade da versão pode ser um desses tipos:- int
- Número Inteiro
- short
- Short
- long
- Comprido
- Timestamp.
Se uma entidade é persistida, e a entidade é então buscada e atualizado em um contexto de persistência separado que está dentro da janela de precisa da plataforma, o fornecedor de persistência não pode detectar o bloqueio otimista e a condição simultânea. Como resultado, uma OptimisticLockException pode não ser lançada e a integridade dos dados é comprometida.Evitar Problemas: Se usar o tipo Timestamp para a propriedade da versão, o aplicativo deverá estar ciente do comportamento que pode ser exibido devido à precisão da implementação que é usada para criar o objeto Timestamp. A implementação típica usa o método System.currentTimeMills. A precisão de tempo desse método é específica da plataforma. Por exemplo, a precisão é 15 ms para Windows de 32 bits e 2 ms para z/OS.gotcha
- Resolva os problemas de violação de restrição do banco de dados ao
trabalhar com entidades.
Os provedores JPA incluídos com o WebSphere Application Server usam um gerenciador de atualização de restrição para determinar a ordem das solicitações SQL para o banco de dados com base em cada configuração de entidade. Esse gerenciador de atualização pode reorganizar a ordem das solicitações SQL para o banco de dados. Isso evita que um aplicativo tenha de saber a ordem das operações do gerenciador de entidade necessárias para executar sua lógica de negócios e otimiza o desempenho do banco de dados utilizando o suporte de lote subjacente.
Como o provedor JPA não assume que há restrições de banco de dados implícitas nos relacionamentos entre as entidades, se houver restrições no banco de dados, por exemplo, uma restrição de chave estrangeira, o provedor JPA poderá não emitir as instruções SQL na ordem desejada. Sob essas condições, a exceção seguinte ou similar pode ocorrer:com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -530, SQLSTATE: 23503, SQLERRMC: xxxxxx
Há algumas maneiras de tratar este problema:- O provedor OpenJPA pode ser configurado para ler informações sobre restrição a partir do banco de dados e aplicá-las ao gerenciador de atualização no tempo de execução incluindo a seguinte propriedade de configuração na unidade de persistência.
<property name="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)" />
- O aplicativo pode aprimorar a entidade para usar a anotação @ForeignKey para
indicar ao provedor JPA quais relacionamentos têm restrições de chave externa.
public class Person { @ManyToOne @ForeignKey private Address address; .... }
- Para aplicativos OpenJPA, o aplicativo pode assumir a responsabilidade de ordenar as instruções SQL incluindo a propriedades de configuração a seguir na unidade de persistência.
<property name="openjpa.jdbc.UpdateManager" value="operation-order" />
Com essa opção de configuração presente, o provedor JPA inicia as instruções SQL na mesma ordem que as operações de entidade foram solicitadas. O aplicativo deve estar ciente de quaisquer interdependências entre entidades.
Evitar Problemas: Mesmo que possa estar inclinado a usar uma combinação dessas propriedades, você deve usar somente a que melhor se ajuste à sua situação. Se houver uma situação em que você ache necessário usar uma combinação dessas propriedades, lembre-se de que usar ambas as propriedades, openjpa.jdbc.UpdateManager e openjpa.jdbc.SchemaFactory, pode não resultar na ordenação de solicitações SQL necessária para corrigir a exceção. A configuração operation-order para a propriedade openjpa.jdbc.UpdateManager indica ao provedor JPA que você deseja que as solicitações SQL sejam executadas na ordem em que são especificadas em um aplicativo. Mesmo se você especificar a propriedade openjpa.jdbc.SchemaFactory, juntamente com o comando openjpa.jdbc.UpdateManager, o provedor JPA respeitará a ordem de solicitações SQL especificada em um aplicativo em vez de ordenar automaticamente as solicitações SQL para respeitar uma restrição detectada, como uma restrição de Chave Estrangeira. Sempre que a propriedade openjpa.jdbc.UpdateManager é especificada, é responsabilidade do desenvolvedor de aplicativos assegurar que as solicitações SQL sejam especificadas na ordem adequada em um aplicativo.gotcha
- Remova as restrições do banco de dados.
- O provedor OpenJPA pode ser configurado para ler informações sobre restrição a partir do banco de dados e aplicá-las ao gerenciador de atualização no tempo de execução incluindo a seguinte propriedade de configuração na unidade de persistência.
- Resolva problemas utilizando a tarefa ANT MappingTool da OpenJPA.
A tarefa Ant MappingTool fornecida pelo OpenJPA usa um carregador de classes temporário para carregar as classes do driver JDBC. Esse carregador de classes temporário pode ter problemas ao carregar alguns drivers JDBC como oDB2.
Quando executar a tarefa MappingTool ANT, um erro semelhante ao seguinte será exibido:
[mappingtool] java.lang.UnsatisfiedLinkError: com/ibm/jvm/Trace.initTrace([Ljava/lang/String;[Ljava/lang/String;)V [mappingtool] at com.ibm.jvm.Trace.initializeTrace(Trace.java:94) [mappingtool] at com.ibm.jvm.Trace.<clinit>(Trace.java:59) [mappingtool] at java.lang.J9VMInternals.initializeImpl(Native Method) [mappingtool] at java.lang.J9VMInternals.initialize(J9VMInternals.java:200) [mappingtool] at java.lang.Class.forNameImpl(Native Method) [mappingtool] at java.lang.Class.forName(Class.java:136) [mappingtool] at com.ibm.db2.jcc.a.o.n(o.java:577) [mappingtool] at com.ibm.db2.jcc.a.o.<clinit>(o.java:329)Para usar a ferramenta de mapeamento, é possível desativar um carregador de classes temporário incluindo o argumento tmpClassLoader=false na tarefa ANT. Dois scripts ANT de exemplo a seguir:
Esse exemplo exibe o problema:
<taskdef name="mapping" classname="org.apache.openjpa.jdbc.ant.MappingToolTask" classpathref="jpa.cp"/> . . . <target name="map.broken"> <mapping> <!-- isso exibe o problema --> . . . </mapping> </target>
Esse exemplo evita o problema:
<taskdef name="mapping" classname="org.apache.openjpa.jdbc.ant.MappingToolTask" classpathref="jpa.cp"/> . . . <target name="map.fixed"> <mapping tmpClassLoader="false"> <!-- isso funcionará --> . . . </mapping> </target>
- Impacto do Cache de Dados sobre modelos de domínio inconsistentes
Quando um aplicativo persiste um modelo de domínio inconsistente e posteriormente recupera as entidades em um contexto de persistência separado, as entidades recuperadas são diferentes dependendo se o DataCache estiver ativo ou não.
Por exemplo, considere um relacionamento bidirecional um-para-um entre duas entidades mapeadas por uma única coluna de chave estrangeira no banco de dados. É possível que um aplicativo configure os campos de relação nas entidades inconsistentemente. Entretanto, quando tais valores inconsistentes são mapeados para o banco de dados, os registros do banco de dados tornam-se consistentes somente porque uma única coluna de chave estrangeira expressa que o DataCache de relacionamentos bidirecionais está ativo, em seguida, o DataCache captura os estados de entidade na memória inconsistentes. Portanto, quando um aplicativo persiste um par de entidades relacionadas em uma relação bidirecional mas seus campos de relação são configurados para valores inconsistente e, posteriormente, recupera as entidades em um contexto de persistência diferente, o relacionamento bidirecional permanece inconsistente ou torna-se consistente dependendo se o DataCache for usado.
Quando vários campos estão mapeados para a mesma coluna, mas definidos com valores diferentes, é outro exemplo em que um estado de entidade inconsistente é persistido, mas recuperado como consistente em um contexto de persistência separado. Nesse caso, a introdução do DataCache também faz uma entidade realizada em um contexto de persistência separado reter valores diferentes e inconsistentes, enquanto sem um DataCache, uma entidade mantém o mesmo valor para ambos os campos.
Boas Práticas: Evite preencher o modelo de domínio de aplicativo inconsistentemente. Para o OpenJPA, também é possível configurar a propriedade openjpa.InverseManager para detectar determinadas inconsistências, como por exemplo, o relacionamento bidirecional.bprac
- Problemas de resolução de problemas cm anotação MappingTool
e @ForeignKey com Sybase.
A ferramenta de mapeamento OpenJPA não pode criar restrições de ForeignKey quando usada com o Sybase Adaptive Server. Como resultado, as restrições de chave estrangeira devem ser criadas manualmente.
- Resolução de problemas das opções de configuração do DB2 Optim pureQuery Runtime. Se estiver usando o DB2 Optim pureQuery Runtime com o provedor WebSphere Application Server JPA (WSJPA), você deverá configurar a seguinte propriedade no arquivo persistence.xml:
<property name="openjpa.Compatibility" value="StrictIdentityValues=true"/>
Caso precise configurar uma opção de compatibilidade diferente, por exemplo, ReloadOnDetach=false, você deverá especificar ambas as opções como parâmetros da mesma instrução de propriedade no arquivo persistence.xml. Por exemplo:
<property name="openjpa.Compatibility" value="StrictIdentityValues=true,ReloadOnDetach=false"/>
Evitar Problemas: A propriedade de compatibilidade de OpenJPA não remove tipos de proxy que o OpenJPA gera para determinados tipos de dados, especialmente tipos de dados como GregorianCalendar. Essa omissão pode causar problemas com a desserialização. Se ocorrer um problema de desserialização, uma mensagem de erro semelhante à mensagem a seguir será emitida:gotcha
Mensagem de erro é: org.codehaus.jackson.map.JsonMappingException: Não é possível construir a instância de org.apache.openjpa.util.java$util$GregorianCalendar$proxy, problema: nenhum método de criador adequado localizado em [Origem: org.apache.http.conn.EofSensorInputStream@d83fbd5; linha: 1, coluna: 4094]
- Resolva os problemas com os atributos de tipo relacionados a tempo em uma
entidade ou quando estiver usando um banco de dados com o DB2 para z/OS. Se uma entidade possuir um
atributo de tipo relacionado a tempo e se a coluna mapeada correspondente
destinada ao banco de dados não estiver compatível, a seguinte
exceção poderá ser observada em determinadas situações:
Essa exceção poderá ser exibida se:org.apache.openjpa.lib.jdbc.ReportingSQLException: THE DATE, TIME, OR TIMESTAMP VALUE 1 IS INVALID. SQLCODE=-18x, SQLSTATE=22007
- Seu banco de dados está executando o DB2 para z/OS.
- Você está usando uma consulta nomeada e acessando o banco de dados com o SQL nativo.
- A consulta nativa usa o campo relacionado a tempo como um parâmetro do SQL, mas a consulta não é compatível com a definição de coluna para a tabela de banco de dados. Consulte o tópico Conversões de Dados Suportadas no Centro de Informações do DB2 9.7 para obter mais informações sobre compatibilidade.
Subtópicos
Aplicativos de Criação de Logs com o JPA
A criação de log suporta visualização, rastreio e resolução de problemas no comportamento de tempo de execução de um aplicativo. O Java™ Persistence API (JPA) fornece um sistema de criação de log flexível que é integrado ao servidor de aplicativos para ajudar na resolução de problemas.Resolvendo Problemas de Conflitos do JPA e de Tempos Limite da Transação
Os conflitos de banco de dados e os tempos limites de transação são resultados de contenção entre dois ou mais clientes que tentam acessar o mesmo recurso de banco de dados. O conflito é um caso especial em que há uma condição de bloqueio circular entre dois ou mais clientes, cada um bloqueado por outros, mas um pode continuar. Geralmente estes fenômenos não vêm a ser um erro de programação. Eles são causados pela lógica de negócios que acessa os recursos de banco de dados de modo complexo e interdependente.Aplicativos de Criação de Logs com o JPA
A criação de log suporta visualização, rastreio e resolução de problemas no comportamento de tempo de execução de um aplicativo. O Java™ Persistence API (JPA) fornece um sistema de criação de log flexível que é integrado ao servidor de aplicativos para ajudar na resolução de problemas.Resolvendo Problemas de Conflitos do JPA e de Tempos Limite da Transação
Os conflitos de banco de dados e os tempos limites de transação são resultados de contenção entre dois ou mais clientes que tentam acessar o mesmo recurso de banco de dados. O conflito é um caso especial em que há uma condição de bloqueio circular entre dois ou mais clientes, cada um bloqueado por outros, mas um pode continuar. Geralmente estes fenômenos não vêm a ser um erro de programação. Eles são causados pela lógica de negócios que acessa os recursos de banco de dados de modo complexo e interdependente.


http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tejb_jpatroubleshoot
Nome do arquivo: tejb_jpatroubleshoot.html