воскресенье, 28 февраля 2010 г.

Do not use InterceptorsFactory with a ManagedObjectAdvisor, InterceptorRegistry should be used via the bean container

Неприятный WARN при вызове методов в EJB-бина (в частности, stateless-бинах) лечится 2мя способами:

1) Плохой - настроить Log4J в Jboss-е так, чтобы WARN в лог не падал. Пример:

<category name="org.jboss.ejb3.interceptors">
<priority value="ERROR" />
</category>

2) Хороший вариант - убрать то, что больше не нужно, из файла server/default/deploy/ejb3-interceptors-aop.xml, а именно:

а - Закомментировать:
<!-- <aspect name="InterceptorsFactory" factory="org.jboss.ejb3.interceptors.aop.InterceptorsFactory" scope="PER_INSTANCE"/> -->

б - Закомментировать:

<bind pointcut="construction(@org.jboss.ejb3.interceptors.ManagedObject->new(..))">
<!-- interceptor-ref name="LoggingInterceptor"/> -->
<!-- TODO: we don't need invocation context here -->
<!-- TODO: we do until we've seperated the post constructs -->
<advice name="setup" aspect="InvocationContextInterceptor"/>
<!--<advice name="invoke" aspect="InterceptorsFactory"/>-->
</bind>

вторник, 16 февраля 2010 г.

Cannot simultaneously fetch multiple bags

А вот это исключение просто как гром среди ясного неба было:

Cannot simultaneously fetch multiple bags

Причина - в одной сущности не может быть более одной коллекции (Collection), заполняемой сразу (FechType.EAGER). Коллекция называется bag. Вот таблица о том, как правильно мапить коллекции, списки и т.п. http://docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity.html

Решение проблемы "по-английски" описано тут: http://community.jboss.org/message/361474#4045327

Repeated column in mapping for entity

Словил такую вещь: Repeated column in mapping for entity

Классы такие:

@Entity
@Table(name = "TOPICS")
public class Topic {
...
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "TO_ID", referencedColumnName = "TO_ID", nullable = false)
@OrderBy
private Collection<accelerator> accelerators;
...}


@Entity
@Table(name = "ACCELERATORS")
public class Accelerator {
...
@ManyToOne
@JoinColumn(name = "TO_ID")
private Topic topic;
}

Лечится очень просто - убираем nullable = false для коллекции, и все будет ОК.
Еще пример: http://www.laliluna.de/256.html

пятница, 12 февраля 2010 г.

Could not enlist in transaction on entering meta-aware object

Словил это исключение. Решение было быстрым и простым. Самописный ResourceAdapter, который я использовал, не поддерживал работу с транзакциями. LocalSettingsFactory инжектировался корректно, но при попытке выполнить метод getContextName() у EJB-бина выскакивало это исключение.
Причина в том, что по умолчанию используется управление транзакциями на уровне контейнера (CMT), а аттрибут транзакции - REQUIRES_NEW. Получается, что getContextName вызывался в рамках транзакции новой транзакции, но при это объект factory.getConnection() не поддерживал транзакции. Решение на данный момент было простым - добавил аннотацию @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) для метода, чтобы изменить аттрибут транзакции.

@Stateless
public class TestingEJB implements Testing {

@Resource(name = "LocalSettingsFactory", mappedName = "java:LocalSettingsFactory")
private LocalSettingsFactory factory;


@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public String getContextName() {
try {
return factory.getConnection().getContextName();
} catch (NamingException e) {
return e.getMessage();
}
}
}

Насколько я понял, подобные проблемы могут быть и с DataSource-ами, которые используются некорректно (например, сконфигурованы для локальных транзакций, а используются в рамках XA-транзакций).