openjpa-2.4.2-r422266: 1777108 org.apache.openjpa.persistence.InvalidStateException: эта операция не может быть выполнена, пока транзакция активна - PullRequest
0 голосов
/ 14 января 2019

Вышеуказанное исключение происходит для операции закрытия в менеджере сущностей. Я пытаюсь запустить сервер Джеймса, который использует OpenJPA. У меня есть 4 объекта, которые я создал и добавил в xml Persistence, который использует james. Я также использую Liquibase для создания схемы для этих 4 таблиц. Все работает нормально, если используется с базой данных H2, но при запуске с сервером James все идет не так.

Я бился головой об этой проблеме, но я не могу найти причину и, следовательно, ее решение.

Я попробовал следующее, но кроме этого я не мог придумать ничего, что могло бы помочь:

  1. Прокомментировал часть синхронизированного отображения в файле persistence.xml, поскольку я не хочу, чтобы JPA создавал таблицы, если их еще нет.

Кто-нибудь знает, что может быть основной причиной? Ценю ваши ответы.

Вот мой подходящий код:

persistence.xml

    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">

<persistence-unit name="James" transaction-type="RESOURCE_LOCAL">
    <!-- Mailbox stuff-->
    <class>org.apache.james.mailbox.jpa.mail.model.JPAMailbox</class>
    <class>org.apache.james.mailbox.jpa.mail.model.JPAUserFlag</class>
   <class>org.apache.james.mailbox.jpa.mail.model.openjpa
.AbstractJPAMailboxMessage</class>

 <class>org.apache.james.mailbox.jpa.mail.
 model.openjpa.JPAMailboxMessage</class>
    <class>org.apache.james.mailbox.jpa.mail.model.JPAProperty</class>
    <class>org.apache.james.mailbox.jpa.mail.
 model.JPAMailboxAnnotation</class>
    <class>org.apache.james.mailbox.jpa.user.model.JPASubscription</class>
    <class>org.apache.james.domainlist.jpa.model.JPADomain</class>
    <class>org.apache.james.mailrepository.jpa.JPAUrl</class>
    <class>org.apache.james.user.jpa.model.JPAUser</class>
    <class>org.apache.james.rrt.jpa.model.JPARecipientRewrite</class>
    <class>org.apache.james.mailbox.jpa.quota.model.
 MaxDomainMessageCount</class>
    <class>org.apache.james.mailbox.jpa.quota.model.
 MaxDomainStorage</class>
    <class>org.apache.james.mailbox.jpa.quota.model.
 MaxGlobalMessageCount</class>
    <class>org.apache.james.mailbox.jpa.quota.model.
 MaxGlobalStorage</class>
    <class>org.apache.james.mailbox.jpa.quota.model.
 MaxUserMessageCount</class>
    <class>org.apache.james.mailbox.jpa.quota.model.
 MaxUserStorage</class>
    <class>org.apache.james.mailbox.jpa.quota.model.
 MaxDomainStorage</class>
    <class>org.apache.james.mailbox.jpa.quota.model. 
 MaxDomainMessageCount</class>
    <class>org.apache.james.mailbox.jpa.quota.model.  
 JpaCurrentQuota</class>

    <class>com.xxxx.xxxx.model.xxxUser</class>
    <class>com.xxxx.xxxx.model.BlockedEmail</class>
    <class>com.xxxx.xxxx.model.xxxx</class>
    <class>com.xxxx.xxxx.model.xxxxEmail</class>

    <properties>
        <!-- <property name="openjpa.jdbc.SynchronizeMappings" 
    value="buildSchema(ForeignKeys=true)"/> -->
        <property name="openjpa.jdbc.MappingDefaults" 
 value="ForeignKeyDeleteAction=cascade, 
  JoinForeignKeyDeleteAction=cascade"/>
        <property name="openjpa.jdbc.SchemaFactory" 
 value="native(ForeignKeys=true)"/>
        <property name="openjpa.jdbc.QuerySQLCache" value="false"/>
    </properties>

</persistence-unit>

</persistence>

У меня есть соответствующие Модель / Хранилище и классы обслуживания.

Пример репозитория:

import java.util.Locale;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceException;
import javax.persistence.PersistenceUnit;
import org.apache.james.user.api.UsersRepositoryException;
import org.apache.james.user.api.model.User;  
import org.apache.james.user.jpa.model.JPAUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class JPAUsersRepository {
private static final Logger LOGGER = 
LoggerFactory.getLogger(JPAUsersRepository.class);
private EntityManagerFactory entityManagerFactory;
private String algo;
/**
 * Sets entity manager.
 * 
 * @param entityManagerFactory
 *            the entityManager to set
 */
@Autowired
@PersistenceUnit(unitName = "James")
public final void setEntityManagerFactory(EntityManagerFactory 
 entityManagerFactory) {
    this.entityManagerFactory = entityManagerFactory;
}
@PostConstruct
public void init() {
    createEntityManager().close();
}
/**
 * Get the user object with the specified user name. Return null if no such
 * user.
 * 
 * @param name
 *            the name of the user to retrieve
 * @return the user being retrieved, null if the user doesn't exist
 * 
 * @since James 1.2.2
 */
public User getUserByName(String name) throws UsersRepositoryException {
    EntityManager entityManager = 
entityManagerFactory.createEntityManager();
    try {
        return (JPAUser) 
 entityManager.createNamedQuery("findUserByName").setParameter("name", 
 name).getSingleResult();
    } catch (NoResultException e) {
        return null;
    } catch (PersistenceException e) {
        LOGGER.debug("Failed to find user", e);
        throw new UsersRepositoryException("Unable to search user", e);
    } finally {
        entityManager.close();
    }
}
/**
 * Returns whether or not this user is in the repository
 * 
 * @param name
 *            the name to check in the repository
 * @return whether the user is in the repository
 * @throws UsersRepositoryException
 */
public boolean contains(String name) throws UsersRepositoryException {
    EntityManager entityManager = 
entityManagerFactory.createEntityManager();
    try {
        return (Long) entityManager.createNamedQuery("containsUser")
            .setParameter("name", name.toLowerCase(Locale.US))
            .getSingleResult() > 0;
    } catch (PersistenceException e) {
        LOGGER.debug("Failed to find user", e);
        throw new UsersRepositoryException("Failed to find user" + name, e);
    } finally {
        entityManager.close();
    }
}
/**
 * Return a new {@link EntityManager} instance
 * 
 * @return manager
 */
private EntityManager createEntityManager() {
    return entityManagerFactory.createEntityManager();
}
}

Большое спасибо, Banyan Bat

...