Parfois, je reçois une exception mal formée dans mon application. Les exceptions arrivent l'une après l'autre comme suit:
@SuppressWarnings("unchecked")
public Iterator findByCriteria(Criteria criteria, int first, int count) {
LOGGER.debug("findByCriteria {}", criteria);
setEntityManager(criteria.getDatabase());
StringBuffer queryString = new StringBuffer();
Query query;
queryString.append("SELECT MAX(a.code), MIN(a.logTime), MAX(a.logTime), "
+ "a.transactionId as transactionId, a.sender as sender, a.receiver as receiver ");
//Add the common where clause
queryString.append(" FROM Audit a where a.logTime BETWEEN :from AND :to");
// Append the appropriate addition where clauses depending on what
// values are set
if (criteria.getSender() != null
|| criteria.getFilter().getSender() != null) {
queryString.append(" AND a.sender = :sender");
}
if (criteria.getReceiver() != null
|| criteria.getFilter().getReceiver() != null) {
queryString.append(" AND a.receiver = :receiver");
}
if (criteria.getMessageType() != null
|| criteria.getFilter().getMessageType() != null) {
queryString.append(" AND a.messageType = :messageType");
}
if (criteria.getTransactionId() != null
|| criteria.getFilter().getTransactionId() != null) {
queryString
.append(" AND a.transactionId = :transactionId");
}
if (criteria.getKeyFieldValue() != null
|| criteria.getFilter().getKeyFieldValue() != null) {
queryString
.append(" AND UPPER(a.keyFieldValue) LIKE :keyFieldValue");
}
// We want a summary so lets group by the common ids
queryString.append(" GROUP BY a.transactionId, a.sender, a.receiver ");
// Add order by clause
if (criteria.getOrderBy() != null) {
queryString.append(" ORDER BY ");
queryString.append(criteria.getOrderBy());
queryString.append(criteria.isAscending() ? " ASC" : " DESC");
}
Session session = ((Session) em.getDelegate()).getSessionFactory().openSession();
query = session.createQuery(queryString.toString());
query.setReadOnly(true);
query.setFetchSize(Integer.valueOf(1000));
query.setCacheable(true);
query.setCacheMode(CacheMode.NORMAL);
// Will always have from and to dates
query.setParameter("from", criteria.getFromDate());
query.setParameter("to", criteria.getToDate());
// Set remaining parameters depending on what is set
if (criteria.getSender() != null) {
query.setParameter("sender", criteria.getSenderValue());
}
// Override the search criteria with the filter if set
if (criteria.getFilter().getSender() != null) {
query.setParameter("sender", criteria.getFilter().getSender());
}
if (criteria.getReceiver() != null) {
query.setParameter("receiver", criteria.getReceiverValue());
}
if (criteria.getFilter().getReceiver() != null) {
query.setParameter("receiver", criteria.getFilter().getReceiver());
}
if (criteria.getMessageType() != null) {
query.setParameter("messageType", criteria.getMessageTypeValue());
}
if (criteria.getFilter().getMessageType() != null) {
query.setParameter("messageType", criteria.getFilter()
.getMessageType());
}
if (criteria.getTransactionId() != null) {
query.setParameter("transactionId", criteria.getTransactionId());
}
if (criteria.getFilter().getTransactionId() != null) {
query.setParameter("transactionId", criteria.getFilter()
.getTransactionId());
}
if (criteria.getKeyFieldValue() != null) {
query.setParameter("keyFieldValue", "%"
+ criteria.getKeyFieldValue().toUpperCase() + "%");
}
if (criteria.getFilter().getKeyFieldValue() != null) {
query.setParameter("keyFieldValue", "%"
+ criteria.getFilter().getKeyFieldValue().toUpperCase()
+ "%");
}
// Set the limits
query.setFirstResult(first);
query.setMaxResults(PAGE_SIZE);
Iterator iterator = query.list().iterator();
session.close();
return iterator;
}
3 Réponses :
Le problème est le problème avec la sécurité du fil: J'ai eu cette erreur lorsque j'essayais d'accéder aux tables à partir de deux threads distincts parallèlement à partir de la même session d'utilisateur (la même page de navigateur présentait deux demandes AJAX en parallèle). p>
Enlevé de cela lorsque j'ai changé l'accès à la série. Je ne sais pas si c'est le même problème avec vous, vaut la peine d'essayer. p>
Pouvez-vous élaborer à ce sujet: "a changé l'accès à la série"? Je ne sais pas ce que cela signifie.
J'ai simplement eu deux demandes parallèles à la ressource d'appels d'async jQuery, j'ai fait ensuite synchroniser. Ce n'est pas une solution idéale BTW, utilisez-le uniquement pour diagnostiquer et réduire votre problème particulier.
Habituellement, une session d'utilisateur doit être liée à un fil à un moment donné. C'est comme si vous ne devriez pas obtenir une connexion JDBC et partager entre 2 threads. Pourquoi le fais-tu?
J'ai recherché un problème similaire pendant quelques jours. La réponse de Supra me pointe vers la bonne direction: Sécurité du fil. P>
Le fait est que Session dans Hibernate n'est pas le fil de protection et nous ne devrions pas autoriser 2 threads accéder à la même session. C'est l'une des causes possibles de l'erreur "Flush lorsque la cascade est dangereuse". Deux threads Accès La même session peut causer beaucoup de comportements inattendus, car Hibernate n'est pas conçu pour cela. P>
Habituellement j'utiliserais un cadre pour faire ce genre de choses, mais si vous avez besoin de le faire vous-même, vous pouvez faire une statique ThreadLocal variable. P>
tl; dr fort>: SéanceFactory code> est thread-coffre-fort, session code> n'est pas. Fournissez une nouvelle session pour chaque fil (soit par le faire vous-même, soit utiliser un cadre DI) P>
Je crois que c'est presque les connaissances les plus fondamentales lorsque vous utilisez JDBC / Hibernate / JPA que la connexion / Session / EntityManager n'est censée être utilisée que sous un seul fil. Ne peut pas imaginer qu'il y a vraiment des cas qui violent cette
Oui, le cas existe. Pour moi, c'est parce que je gâche la gestion de mode de vie dans le château Windsor (je suis passée à C # Stack récemment), résultant de la session n'est pas un fil de discussion comme je le pensais. Mais je peux dire de 3 jours de recherche, ce n'est pas le seul cas
J'ai vu une question similaire dans le passé, mais principalement pour ces applications de niveau de jouet ou d'auto-apprentissage. Heureusement, je n'ai pas rencontré de tels cas dans ma vie de développement pour les applications réelles: P Utilisation correcte des cadres économise vraiment beaucoup de problèmes :)
Ne peut pas être plus d'accord. Jamais rencontré cette erreur lorsque je fais du printemps: un cadre bien établi aident vraiment beaucoup.
J'ai eu la même erreur lors de l'utilisation de JPA EntityListeners dans une application Spring.
Résolu en utilisant transactionsynchronizationmanager.registersynchronisation () code>, mais je ne sais pas si c'est la meilleure pratique (code à Kotlin):
quelle est la question? "Peut-il se reproduire" -> dépend du code