Невозможно сохранить данные в RDS MySQL с использованием JPA / Hibernate и TomEE Plume - PullRequest
0 голосов
/ 11 февраля 2020

Я пытаюсь сохранить данные в базе данных MySQL на AWS RDS, но он зависает при вызове метода Java EE entityManager.flu sh ().

Симптомы Я испытываю, что вызов entityManager.persist (entity), за которым следует entityManager.flu sh (), успешно выполняется на локальном хосте, но не удается сохранить данные при вызове AWS RDS с моей локальной машины. Вызов INSERT INTO из MySQL Workbench на моей локальной машине успешно сохраняет данные как на localhost, так и на RDS. Вот сценарий в форме таблицы:

            MySQL Workbench  |  JPA/Hibernate/TomEE Plume
            -----------------+---------------------------
Localhost      succeeds      |          succeeds
AWS RDS        succeeds      |          fails

Нет ошибок или предупреждений в выводе консоли. Мои операторы System.err.println показывают, что мое приложение думает, что оно хранит данные, но затем зависает при попытке выполнить грипп sh. После некоторого зависания мое приложение пытается сохранить следующую серию данных. На самом деле данные не сохраняются в базе данных. В конце концов Netbeans открывает диалоговое окно с сообщением «Ошибка: запуск Tomcat не выполнен».

Я не могу сказать, является ли источник моей проблемы неправильно настроенным JPA / Hibernate, неадекватными MySQL разрешениями, навязанными Amazon RDS ограничения или что-то еще. Кто-нибудь знает, что я могу делать неправильно?

Вот мой Java исходный код. Поведение одинаково независимо от того, комментируются ли @Lock (LockType.WRITE) и @Transactional или нет.

@Singleton
@Startup
@LocalBean
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
@Lock(LockType.READ)
public class AsyncFredUpdateSingletonEJB {
    @PersistenceUnit(unitName="hibernateJtaPU")
    private EntityManagerFactory entityManagerFactory;

    @PostConstruct
    public void initialize() {
        // Eventually calls persistObservations(series);
    }

    …

    //@Lock(LockType.WRITE)
    //@Transactional
    protected void persistObservations(Series series) {
        try {
            if (series != null) {
                System.err.println("  *** Getting EntityManager for series " + series.getId());
                EntityManager entityManager = this.entityManagerFactory.createEntityManager();
                if (entityManager == null) {
                    return;
                }

                System.err.println("  *** Deleting series " + series.getId());
                // Remove all old observations for this series before persisting new observations.
                Query query = entityManager.createNamedQuery("deleteObservations");
                query.setParameter("seriesId", series.getId());
                query.executeUpdate();

                System.err.println("  *** Persisting series " + series.getId());
                // Persist all new observations for this series to the database.
                LocalDate today = LocalDate.now();
                int count = 0;
                for (Observation observation : series.getObservations()) {
                    if (observation.getDate().compareTo(today) <= 0) {
                        ObservationEntity entity = new ObservationEntity(series.getId(), observation.getDate());
                        entity.setValue(observation.getValue());
                        entityManager.persist(entity);
                        System.err.println(" **** " + series.getId() + " persisted. (" + ++count + ")");
                    }
                }
                System.err.println("  *** Flushing...");
                entityManager.flush();

                System.err.println("  *** Series " + series.getId() + " successfully persisted.\n");
            }
        } catch (Exception e) {
            System.err.println("***** Exception caught: " + e.getMessage() + ". \nCause: " + e.getCause().getMessage());
        }
    }
}

Вот мое постоянство. xml file:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
             xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="hibernateJtaPU" transaction-type="JTA">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <jta-data-source>jdbc/rdsInstanceNameJtaJNDI</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <shared-cache-mode>DISABLE_SELECTIVE</shared-cache-mode>
    <validation-mode>NONE</validation-mode>
    <properties>
      <property name="javax.persistence.jdbc.user" value="rdsInstanceName_limited"/>
      <property name="javax.persistence.jdbc.password" value="weak_password"/>
      <property name="javax.persistence.jdbc.url" 
        value="jdbc:mysql://rdsInstanceName.rds_account_id.us-east-1.rds.amazonaws.com:3306/database_name?zeroDateTimeBehavior=convertToNull"/>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="javax.persistence.schema-generation.database.action" value="none"/>
      <property name="javax.persistence.schema-generation.scripts.action" value="none"/>
      <property name="javax.persistence.schema-generation.create-source" value="script"/>
      <property name="javax.persistence.schema-generation.create-script-source" value="META-INF/sql/create.sql" />
      <property name="javax.persistence.schema-generation.drop-source" value="script"/>
      <property name="javax.persistence.schema-generation.drop-script-source" value="META-INF/sql/drop.sql" />

      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
      <property name="hibernate.generate_statistics" value="true"/>
      <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
      <property name="hibernate.cache.use_second_level_cache" value="false"/>
      <property name="hibernate.cache.provider_configuration_file_resource_path" value="META-INF/ehcache.xml"/>
      <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory"/>
    </properties>
  </persistence-unit>
</persistence>

Вот мои ресурсы. xml file:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <Resource id="jdbc/rdsInstanceNameJtaJNDI" type="DataSource">
        JtaManaged = true
        JdbcDriver = com.mysql.jdbc.Driver
        JdbcUrl = jdbc:mysql://rdsInstanceName.rds_account_id.us-east-1.rds.amazonaws.com:3306/database_name?zeroDateTimeBehavior=convertToNull
        UserName = rdsInstanceName_limited
        Password = weak_password
        InitialSize = 4
        MaxActive = 64
        MinIdle = 16
        MaxIdle = 32
        MaxWait = 15000
        LogAbandoned = true
        RemoveAbandoned = true
        RemoveAbandonedTimeout = 180
        SuspectTimeout = 60
        JdbcInterceptors = ResetAbandonedTimer
    </Resource>
    <Resource id="jdbc/rdsInstanceNameNonJtaJNDI" type="DataSource">
        JtaManaged = true
        JdbcDriver = com.mysql.jdbc.Driver
        JdbcUrl = jdbc:mysql://rdsInstanceName.rds_account_id.us-east-1.rds.amazonaws.com:3306/database_name?zeroDateTimeBehavior=convertToNull
        UserName = rdsInstanceName_limited
        Password = weak_password
        InitialSize = 4
        MaxActive = 64
        MinIdle = 16
        MaxIdle = 32
        MaxWait = 15000
        LogAbandoned = true
        RemoveAbandoned = true
        RemoveAbandonedTimeout = 180
        SuspectTimeout = 60
        JdbcInterceptors = ResetAbandonedTimer
    </Resource>
</resources>

Вот мой файл hibernate.cfg. xml:

<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://rdsInstanceName.rds_account_id.us-east-1.rds.amazonaws.com:3306/database_name?zeroDateTimeBehavior=convertToNull</property>
    <property name="hibernate.connection.username">rdsInstanceName_limited</property>
    <property name="hibernate.connection.password">weak_password</property>
  </session-factory>
</hibernate-configuration>

Вот мои настройки:

  • MariaDB 10.4.8 (XAMPP Windows x64 7.3.11) с использованием InnoDB на локальном хосте
  • MySQL 5.6.40 с использованием InnoDB на AWS RDS (также пробовали с MySQL 5.7.x)
  • JDK 8 (1.8.0_201)
  • Apache TomEE 7.1.1 Plume (Java EE 7)
  • Hibernate 4.3 (JPA 2.1)
  • Netbeans 8.2
  • MySQL Верстак 6.3 CE
...