Безопасно ли хранить ссылку на Entity Bean после окончания сеанса? - PullRequest
1 голос
/ 09 июля 2010

Это довольно новый вопрос - пожалуйста, знайте, что я об этом знаю.

У меня есть сессионный компонент без сохранения состояния, который должен загрузить некоторые данные один раз и локально кэшировать их в статической переменной длявсе экземпляры этого боба.Доступ к данным можно получить через объектный компонент.Я задаюсь вопросом, безопасно ли кешировать экземпляр сущности или мне следует его клонировать.Кроме того, этот объект также имеет дочерние объекты.

Вызовите объект Foo.У Foo есть бар.В моем сессионном компоненте я хотел бы сделать что-то вроде этого:

private static final FOO_ID = 123L;

private static Foo foo;

private static Foo getFoo(EntityManager em) {
    if (foo != null)
        return foo;
    return foo = (Foo) em.find(Foo.class, FOO_ID);
}

public void someBusinessMethod() {
    EntityManager em = Container.getInstance().getEntityManager();
    Foo foo = getFoo(em);
    Bar bar = foo.getBar();
    // do some stuff with foo and bar
}

Мои вопросы:

  1. Это плохая идея?Будет ли это вообще работать?

  2. Есть ли лучший способ загрузить данные Foo один раз, возможно, без необходимости использования метода getFoo ()?Делать это статически при загрузке класса Session казалось бы идеальным.

Новый (точный) пример кода, по комментариям:

public class Foo {   // entity
    private Long id;
    private String name;
    // getters and setters
}

public class Bar {   // entity
    private Long id;
    private String name;
    // getters and setters
}

public class FooHelper implements Helper {
    private static final long FOO_ID = 123L;
    private Foo foo;
    public FooHelper() {
       // use FOO_ID to look up a Foo & cache it locally
    }
    @Override
    public void addBar(EntityManager em) {
        Bar bar = new Bar();
        bar.setName(foo.getName());
        em.persist(bar);
    }

public class StatelesSessionBean {
    private static final Helper helper = new FooHelper();
    public void someBusinessMethod() {
        @PersistenceContext
        EntityManager em;
        helper.addBar(em);
    }
}

1 Ответ

2 голосов
/ 09 июля 2010

Не финальные статические поля недопустимы в Сессионных компонентах без состояния (SLSB).Из спецификации EJB3, раздел 21.1.2:

Компонент EJB не должен использовать статические поля для чтения / записи.Использование статических полей только для чтения разрешено.Поэтому рекомендуется объявлять все статические поля в классе корпоративного компонента как окончательные.

Это правило необходимо для обеспечения согласованности при распределении экземпляров по нескольким JVM.

Так что недействительно хорошая идея.Мое предложение было бы полагаться на кэш второго уровня, который может поддерживать ваш провайдер JPA, и позволить ему прозрачно с ним справиться.

В качестве примечания, я действительно задаюсь вопросом, почему у вас эта строка вваш бин:

EntityManager em = Container.getInstance().getEntityManager();

В управляемой среде вы должны использовать менеджер сущностей , управляемый контейнером, и вставить его в SLSB (используя аннотацию @PersistenceContext).

...