HibernateException: proxy poignée n'est plus valide après la base de données erreur de violation d'
J'ai de la boucle pour enregistrer quelques objets. Dans la boucle d'un appel de la méthode du service et de capturer des exceptions. Service enregistrer méthode annotée @Transactionnelle et à l'intérieur ne hibernate saveOrUpdate appel.
Le Service est fourni par la méthode getBean de ApplicationContext objet. J'appelle ça une seule fois avant la boucle.
Dans la boucle, après j'attrape exception de l'oracle de violation de contrainte :
org.mise en veille prolongée.exception à la règle.constraintviolationexception: ora-00001: contrainte unique (ccb.sys_c0017085) a violé
J'journal problème et d'essayer de sauver un autre objet. L'exception suivante je reçois est:
org.mise en veille prolongée.HibernateException: proxy poignée n'est plus valide
Parfois, il se produit seulement une fois après chaque erreur ora, mais parfois, il se répète pour les objets (itérations).
Comment gérer cette exception & comment sauver opération possible?
Je suis en utilisant
Printemps 3.1.3 et Hibernate 4.1.7.
[modifier]
Quelques exemple de code:
@Service
public class ServiceForRecord {
@Transactional
public Record saveRecord(Record record, String user) {
Record obj = record;
//some validation & seting internal values
getHibernateTemplate().saveOrUpdate(obj)
return obj;
}
...
et dans ma boucle je fais:
//in params:
serviceClass = ServiceForRecord.class;
entityClass = Record.class;
saveMethod = "saveRecord";
//loop prepare
service = getApplicationContext().getBean(serviceClass);
serviceSave = serviceClass.getMethod("saveRecord", Record.class, String.class);
while (condition) {
entity = BeanUtils.instantiate(entityClass);
//setup entity
serviceSave.invoke(service, entity, "testUser");
//catch error
} //end while
[modifier]
La trace de pile:
PreparedStatementProxyHandler(AbstractProxyHandler).errorIfInvalid() line: 63
PreparedStatementProxyHandler(AbstractStatementProxyHandler).continueInvocation(Object, Method, Object[]) line: 100
PreparedStatementProxyHandler(AbstractProxyHandler).invoke(Object, Method, Object[]) line: 81
$Proxy100.clearBatch() line: not available
NonBatchingBatch(AbstractBatchImpl).releaseStatements() line: 163
NonBatchingBatch(AbstractBatchImpl).execute() line: 152
JdbcCoordinatorImpl.getBatch(BatchKey) line: 151
SingleTableEntityPersister(AbstractEntityPersister).insert(Serializable, Object[], boolean[], int, String, Object, SessionImplementor) line: 2940
SingleTableEntityPersister(AbstractEntityPersister).insert(Serializable, Object[], Object, SessionImplementor) line: 3403
EntityInsertAction.execute() line: 88
ActionQueue.execute(Executable) line: 362
ActionQueue.executeActions(List) line: 354
ActionQueue.executeActions() line: 275
DefaultFlushEventListener(AbstractFlushingEventListener).performExecutions(EventSource) line: 326
DefaultFlushEventListener.onFlush(FlushEvent) line: 52
SessionImpl.flush() line: 1210
SessionImpl.managedFlush() line: 399
JdbcTransaction.beforeTransactionCommit() line: 101
JdbcTransaction(AbstractTransactionImpl).commit() line: 175
HibernateTransactionManager.doCommit(DefaultTransactionStatus) line: 480
HibernateTransactionManager(AbstractPlatformTransactionManager).processCommit(DefaultTransactionStatus) line: 754
HibernateTransactionManager(AbstractPlatformTransactionManager).commit(TransactionStatus) line: 723
TransactionInterceptor(TransactionAspectSupport).commitTransactionAfterReturning(TransactionAspectSupport$TransactionInfo) line: 392
TransactionInterceptor.invoke(MethodInvocation) line: 120
ReflectiveMethodInvocation.proceed() line: 172
AfterReturningAdviceInterceptor.invoke(MethodInvocation) line: 50
ReflectiveMethodInvocation.proceed() line: 172
JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 202
$Proxy71.save(Account, String) line: not available
GeneratedMethodAccessor115.invoke(Object, Object[]) line: not available
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available
Method.invoke(Object, Object...) line: not available
ImportServiceProvider.save(Object, String) line: 380
[modifier]
la dernière chose que j'ai remarqué, c'est qu'il ne se produit pas sur MS SQL Server, uniquement sur Oracle
service.saveRecord(entity,"testUser")
Je prépare solution générique pour enregistrer les enregistrements de donnée de fichier. service de la classe et de la classe d'entité est donnée par param. Je vais re-générer l'erreur et la poster.
OriginalL'auteur Saram | 2013-01-31
Vous devez vous connecter pour publier un commentaire.
J'ai différentes suggestions au sujet de votre problème.
Suggestion 1 : vous êtes à tort la réutilisation de la même session, dans toutes les transactions.
Pour vérifier cela : mettre un point d'arrêt dans
saveRecord
et vérifiez que la référence à laSessionImpl
est différente dans les 2 appels successifs.Honnêtement, il y a peu de chances, c'est votre problème parce que votre code est en cours d'exécution avec MS SQL Server. Donc la seule chance pour cette suggestion correcte est que les contraintes dans MS SQL Server ne sont pas les mêmes que les contraintes dans Oracle. En outre, je pense que hibernate va jeter un plus explicite exception dans ce cas.
Suggestion 2 : vous frapper un bug dans hibernate 4
Il y a quelques rapports de bogues dans hibernate JIRA dans ce domaine. (sans votre code, il est difficile de dire quelle est votre situation exacte). Il y a de bonnes chances que le comportement que vous avez est lié à l'un de ces bugs:
https://hibernate.onjira.com/browse/HHH-7688 (celui-ci est très proche de la vôtre, mais il existe quelques autres)
Est-il une des solutions de contournement pour ce bug ?
J'ai quelques suggestions à essayer :
jeu de mise en veille prolongée.jdbc.batch_size à quelque chose au-dessus de 1 . Cette solution de contournement a été suggéré ici par Michale Wyraz et semble fonctionner.
Ne pas utiliser la réflexion : pas sûr que ça va aider, mais la transaction est gérée par l'aop-proxy, et en utilisant la réflexion peut causer de contourner certains de la transaction gestionnaire de code (il ne devrait pas, mais c'est une hypothèse à vérifier).
Modifier la connexion en mode release : tous ceux qui ont des bugs (en veille prolongée JIRA) sont plus ou moins liées à JdbcConnection de gestion, la modification du connexion en mode release peut, à somepoint vous aider à identifier le problème. (Je ne dis pas que changer c'est la solution, si vous êtes vraiment frapper un bug en mode veille prolongée: votre meilleur choix est probablement attendre/contribuer pour la correction)
La rétrogradation à hibernate 3.X : encore une Fois je ne dis pas que c'est une solution, mais il peut indiquer que vous êtes vraiment face à un bug dans hibernate 4.
La mise à niveau vers hibernate 4.2+ : Comme suggéré dans d'autres réponse et concernant récente changements dans hibernate code de base: tout simplement en mettant hibernate peut résoudre le problème.
J'ai aussi résolu le problème par la mise en veille prolongée.jdbc.batch_size de grand que 1.
J'ai eu le même problème avec WS 7.0. J'ai mis à jour la version de tous les hibernate dépendances de 4.1.9.En finale, 4.2.20.Final et l'exception a disparu. Merci beaucoup.
OriginalL'auteur ben75
J'ai perdu des heures avec le même problème lorsque vous essayez de fermer la Session et, malheureusement, aucun de ben75 suggestions travaillé. C'était mon environnement:
org.hibernate.HibernateException: proxy handle is no longer valid ...
donc, juste dans le cas que quelqu'un d'autre tombe sur cette erreur, la solution qui a fonctionné pour moi a été la mise à niveau vers Hibernate 4.2. Requis pots sont:
HTH.
Certainement un très étrange erreur. Quelles sont les différences entre ces deux versions?
honnêtement, je ne sais pas, je dois vérifier. Je ne sais pas pourquoi je ne peux pas définir la notification de votre nom d'utilisateur, j'ai essayé '@MiljenMikic", mais n'a pas fonctionné.
Probablement parce que lorsque vous êtes en laissant un commentaire ci-dessous quelqu'un à la réponse, il/elle reçoit toujours une notification. J'ai reçu la notification sans mentionner le nom d'utilisateur 🙂
OriginalL'auteur Miljen Mikic
Juste une supposition.
@Transactional
ferme de transaction sur une Exception par la restauration. Afin de voir les objets devient genre de détaché.Je voudrais supprimer le
@Transactional
de la méthode principale où vous parcourez les objets à sauvegarder et à faire @Transactional un separet méthode qui enregistre uniquement les objets.Et quels résultats? Tous les succès/des erreurs?
Je veux dire, que j'ai utilisé de cette façon auparavant. Pas de succès.
OriginalL'auteur StanislavL
Hibernate 4.1.3 n'est pas de fermer des instructions groupées si ils ont jeté une exception (dans org.mise en veille prolongée.moteur.jdbc.lot.interne.NonBatchingBatch.addToBatch()).
Vous intercepter l'exception, le rollback de la transaction en cours, commencer une nouvelle et espère que tout est parfait.
Mais si vous exécutez un natif script de mise à jour (par exemple), après la course, les enfin veut fermer les états. Et ici, il s'agit, le (désormais détaché en raison de la restauration) déclaration de lance de cette exception et votre nouvelle transaction se passe mal. Heureusement, avant que la nouvelle exception des états obtenir effacée, de sorte que seule la première mise à jour se trompe...
J'ai créé une méthode de gestionnaire que j'appelle tous les rollback (ce cas, il est appelé après que l'exception initiale), et après la restauration et pour commencer j'ai créer un mannequin (et rapide) de mise à jour (update [tablename] set [colonne]=[colonne] où 1=2) et de l'exécuter. Il déclenche l'erreur ci-dessus, je peux l'attraper, l'annulation de la transaction une fois de plus et en créer un nouveau, j'ai donc sortie de la méthode avec une bonne session hibernate et d'un salon de transaction.
C'est un vilain solution de contournement, mais je ne peut pas mettre à niveau hibernate version maintenant...
OriginalL'auteur Pittmann György