Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.
Например, ниже - класс ученика, который будет использовать его в нашем коде.
public class Student {
private int id;
public int getId() {
return this.id;
}
public setId(int newId) {
this.id = newId;
}
}
Приведенный ниже код дает вам исключение с нулевым указателем.
public class School {
Student obj_Student;
public School() {
try {
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Поскольку вы используете Obj_Student
, но вы забыли инициализировать его, как в правильном коде, показанном ниже:
public class School {
Student obj_Student;
public School() {
try {
obj_Student = new Student();
obj_Student.setId(12);
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Другой способ сделать это на самом деле имеет оба метода на том же бобе - и имеет @EJB
ссылка на себя! Что-то как этот:
// supposing processObjects defined on MyStatelessRemote1 and process defined on MyStatelessLocal1
@Stateless
@TransationAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class MyStatelessBean1 implements MyStatelessLocal1, MyStatelessRemote1 {
@EJB
private MyStatelessLocal1 myBean2;
public void processObjects(List<Object> objs) {
// this method just processes the data; no need for a transaction
for(Object obj : objs) {
this.myBean2.process(obj);
}
}
@TransationAttribute(TransactionAttributeType.REQUIRES_NEW)
public void process(Object obj) {
// do some work with obj that must be in the scope of a transaction
this.mgr.merge(obj);
// ...
this.mgr.merge(obj);
// ...
this.mgr.flush();
}
}
Этот путь Вы на самом деле 'вынуждаете' process()
метод быть полученными доступ через ejb стопку прокси, поэтому беря @TransactionAttribute
в действительности - и все еще сохраняя только один класс. Уф!
Я думаю, что вещью является каждый боб, обертывается в прокси, который управляет транзакционным поведением. Когда Вы звоните от одного боба до другого, Вы идете через прокси того боба, и поведение транзакции может быть изменено прокси.
, Но когда боб называет метод на себе с различным атрибутом транзакции, вызов не идет через прокси, таким образом, поведение не изменяется.
Матовый, если это имеет значение я пришел к точно тому же заключению как Вы.
TransactionAttributeTypes только учтены при пересечении Бобовых границ. Когда вызывающие методы в том же бобе, TransactionAttributeTypes не имеют никакого эффекта, неважно, какие Типы помещаются в методы.
, Насколько я вижу, нет ничего в Спецификации Персистентности EJB, которая определяет то, что поведение должно произойти при этих обстоятельствах.
я также испытал это в Jboss. Я также дам ему попытку в Glassfish и сообщу результаты.
Я думаю, имеет отношение @TransationAttribute (TransactionAttributeType. Никогда) на методе processObjects.
TransactionAttributeType. Никогда
http://docs.sun.com/app/docs/doc/819-3669/6n5sg7cm3?a=view
, Если клиент работает в транзакции и вызывает предприятие bean’s метод, контейнер не бросает RemoteException. Если клиент не связан с транзакцией, контейнер не запускает новую транзакцию прежде, чем выполнить метод.
я предполагаю, что Вы - клиент метод processObjects от клиентского кода. Поскольку, вероятно, Ваш клиент не связан с транзакцией вызов метода с [1 112] TransactionAttributeType. Никогда не счастливо во-первых. Тогда Вы звоните процесс метод от [1 114] processObjects это, хотя имея TransactionAttributeType. Требуемый аннотация не была бобовым вызовом метода, и политика транзакции не осуществляется. Когда Вы звоните слияние , Вы получаете исключение, потому что Вы все еще не связаны с транзакцией.
Попытка с помощью [1 117] TransactionAttributeType. Требуемый для обоих бобовых методов, чтобы видеть, добивается ли это цели.
Мэтт, вопрос, который вы задаете, является довольно классическим. Я думаю, что решение для саморекламы от Herval / Pascal неплохо. Здесь не упоминается более общее решение.
Это случай «пользовательских» транзакций EJB. Поскольку вы находитесь в сессионном компоненте, вы можете получить пользовательскую транзакцию из контекста сеанса. Вот как ваш код будет выглядеть с пользовательскими транзакциями:
// supposing processObjects defined on MyStatelessRemote1 and process defined on MyStatelessLocal1
@Stateless
@TransationAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class MyStatelessBean1 implements MyStatelessLocal1, MyStatelessRemote1 {
@Resource
private SessionContext ctx;
@EJB
private MyStatelessLocal1 myBean2;
public void processObjects(List<Object> objs) {
// this method just processes the data; no need for a transaction
for(Object obj : objs) {
this.myBean2.process(obj);
}
}
public void process(Object obj) {
UserTransaction tx = ctx.getUserTransaction();
tx.begin();
// do some work with obj that must be in the scope of a transaction
this.mgr.merge(obj);
// ...
this.mgr.merge(obj);
// ...
this.mgr.flush();
tx.commit();
}
}
На случай, если кто-то однажды столкнется с этим:
чтобы избежать круговых зависимостей (например, разрешить ссылки на себя) в JBoss, используйте аннотацию 'IgnoreDependency', например:
@IgnoreDependency @EJB MySelf myselfRef;