Статьи

Arquillian с NetBeans, встроенным GlassFish, JPA и источником данных MySQL — Часть II

Это сообщение о том, что я сделал вчера, Оказывается, даже если это была более сложная демонстрация, я упустил большую проблему с настройкой. Все работает хорошо до того момента, когда вы начинаете внедрять расширенные функции для ваших сущностей. Чтобы назвать только несколько: ленивая загрузка, отслеживание изменений, выборка групп и так далее. Провайдеры JPA любят называть это «улучшением», и это чаще всего называют «ткачеством». Ткачество — это метод манипулирования байт-кодом скомпилированных классов Java. Поставщик персистентности EclipseLink JPA использует ткачество для улучшения сущностей JPA для упомянутых вещей и для внутренней оптимизации. Плетение может выполняться либо динамически во время выполнения, когда загружаются сущности, либо статически во время компиляции путем последующей обработки файлов .class сущности.Динамическое переплетение в основном рекомендуется, так как оно легко настраивается и не требует каких-либо изменений в процессе сборки проекта. Возможно, вы видели более точный вывод журнала из EclipseLink, например:

[...]--Begin weaver class transformer processing class [com/mycompany/simpleweb/entities/AuditLog].
[...]--Weaved persistence (PersistenceEntity) [com/mycompany/simpleweb/entities/AuditLog].
[...]--Weaved change tracking (ChangeTracker) [com/mycompany/simpleweb/entities/AuditLog].
[...]--Weaved lazy (ValueHolder indirection) [com/mycompany/simpleweb/entities/AuditLog].
[...]--Weaved fetch groups (FetchGroupTracker) [com/mycompany/simpleweb/entities/AuditLog].
[...]--End weaver class transformer processing class [com/mycompany/simpleweb/entities/AuditLog].

Проблема с Arquillian и Embedded GlassFish

Представьте, что вы взяли пример из вчерашнего поста в блоге и изменили свойство простой учетной записи String на что-то вроде этого:

@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
   private Person person;

Это как раз один из упомянутых случаев, когда вашему JPA-провайдеру необходимо выполнить некоторые улучшения в ваших файлах классов перед выполнением. Без изменения проекта это приведет к некоторым очень неприятным исключениям:

Exception Description: A NullPointerException would have occurred accessing a non-existent weaved _vh_ method [_persistence_get_person_vh].  The class was not weaved properly - for EE deployments, check the module order in the application.xml deployment descriptor and verify that the module containing the persistence unit is ahead of any other module that uses it.
[...]
Internal Exception: java.lang.NoSuchMethodException: com.mycompany.simpleweb.entities.AuditLog._persistence_get_person_vh()
Mapping: org.eclipse.persistence.mappings.ManyToOneMapping[person]
Descriptor: RelationalDescriptor(com.mycompany.simpleweb.entities.AuditLog --> [DatabaseTable(AUDITLOG)])
 at org.eclipse.persistence.exceptions.DescriptorException.noSuchMethodWhileInitializingAttributesInMethodAccessor(DescriptorException.java:1170)
 at org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor.initializeAttributes(MethodAttributeAccessor.java:200)
[...]

показывая, что чего-то не хватает. И этот недостающий метод вводится в процессе ткачества. Если вы декомпилируете сотканную сущность, вы можете увидеть, на что жалуется поставщик JPA. Вот как должен выглядеть ваш расширенный класс сущностей. И это только один из усовершенствованных методов, которые процесс ткачества внедряет в ваш код.

public WeavedAttributeValueHolderInterface _persistence_get_person_vh()
  {
      _persistence_initialize_person_vh();
      if(_persistence_person_vh.isCoordinatedWithProperty() || _persistence_person_vh.isNewlyWeavedValueHolder())
      {
          Person person1 = _persistence_get_person();
          if(person1 != _persistence_person_vh.getValue())
              _persistence_set_person(person1);
      }
      return _persistence_person_vh;
  }

Динамическое и статическое

переплетение Очевидно, что динамическое переплетение по умолчанию не работает с описанной установкой. Зачем? Ткачество — испорченный ребенок. Это работает только тогда, когда классы сущностей, которые нужно сплести, существуют только в загрузчике классов приложения. Комбинация встроенных GlassFish, Arquillian и maven sure-fire-plugin немного смешивает это, и конец истории в том, что ни одна из ваших сущностей вообще не улучшена. Сравните это
хорошее обсуждение для более подробного объяснения. Если динамическое колебание не работает, мы должны использовать запасной вариант, называемый статическим переплетением. Статические средства: постобработка сущностей во время сборки. Имея проект Maven под рукой, это звучит как довольно легкая работа. Давайте посмотрим на что-то вроде этого. Первое, что вы, вероятно, найдете, это
StaticWeaveAntTask, Вторым может быть плагин Крэйга
eclipselink-staticweave-maven-plugin . Давайте начнем с StaticWeaveAntTask. Вы должны будете использовать maven-antrunner-plugin, чтобы представить это. Скопируйте классы слева направо и сделайте невероятные споры, чтобы добиться нужного уровня. Лейрд Нельсон проделал большую работу по
созданию примера конфигурации для всех трех крупных поставщиков JPA (EclipseLink, OpenJPA, Hibernate), и вы могли бы попробовать. Подробное объяснение происходящего
можно найти в его блоге., Спасибо Laird за указатели! Не поймите меня неправильно: это правильный подход, но он мне просто не нравится. Главным образом потому, что это создает огромную сложность для сборки и слишком большого количества проектов, в которых нет необходимых навыков для управления даже обычными проектами maven, это просто не решение для меня. Я попробовал плагин статического плетения, созданный Крейгом Дэй.

Добавление статического плетения в simpleweb

Итак, давайте откроем pom.xml из проекта вчерашнего дня и представим новый плагин:

	
<plugin>
    <artifactId>eclipselink-staticweave-maven-plugin</artifactId>
    <groupId>au.com.alderaan</groupId>
    <version>1.0.1</version>
         <executions>
            <execution>
                 <goals>
                   <goal>weave</goal>
                 </goals>
                 <phase>process-classes</phase>
            </execution>
          </executions>
     </plugin>

Готово. Теперь ваши классы переплетены, и если вы введете некоторую регистрацию через конфигурацию плагина, вы действительно сможете увидеть, что происходит с вашими классами сущностей. Плагин доступен через repo1.maven.org. Единственная проблема, с которой я столкнулся, заключается в том, что введенная зависимость от EclipseLink 2.2.0 недоступна (или, конечно, недоступна) через тот же репозиторий, поэтому вам, вероятно, потребуется создать ее для себя с правильными репозиториями и зависимостями. Вы можете получить исходный код через
кодовую страницу Google плагина .

Не забудьте добавить свойство weaving в ваш test-persistance.xml:

<property name="eclipselink.weaving" value="static" />

 

От http://blog.eisele.net/2012/01/arquillian-with-netbeans-glassfish_18.html