JPA / Hibernate не выдает UPDATE при фиксации в среде EJB / Seam - PullRequest
5 голосов
/ 03 февраля 2012

У меня есть песочница Seam 3, использующая JBoss 7, Hibernate в качестве реализации JPA по умолчанию и JSF в качестве веб-интерфейса.

У меня проблема в том, что SQL UPDATE по умолчанию проглатывается.

Мой EJB с состоянием в режиме разговора поддерживает расширенный объект EntityManager и одну сущность, управляемые контейнером транзакции (требуется новый)

  1. EntityManager вводится
  2. EJB использует EM длязагрузить объект и сохранить его в поле
  3. Приложение JSF обращается к EJB и его объекту, изменяет поле String
  4. Приложение JSF вызывает метод "Сохранить" в EJB
  5. Вsave () Я проверяю, было ли изменено поле Entities -> оно было изменено правильно
  6. Я больше ничего не делаю, контейнер завершает транзакцию после завершения save ().
  7. Проблема: НетОбновление SQL выполняется для БД.

Если я расширяю save () на:

a) entityManager.contains (entity), UPDATE выполняется должным образом (result "true")

ИЛИ

b) entityManager.persist (entity) ОБНОВЛЕНИЕ выполняется должным образом

Q: Насколько я понимаю, спецификации ниа) или б) должны быть обязательными, поскольку сущность остается управляемой в течение всего процесса.Я не понимаю, почему а) влияет на сохранение.Я могу представить себе, что б) влияет на сохранение, но это не нужно, не так ли?

Любое объяснение приветствуется.

Вот мой EJB:

@Named
@ConversationScoped
@Stateful
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class LanguageBean {

    @PersistenceContext(type = PersistenceContextType.EXTENDED)
    private EntityManager em;
    @Inject
    private UserTransaction transaction;

    private Language value;

    @Inject
    Conversation conversation;

    public LanguageBean() {
        super();
    }

    @Begin
    public void selectLanguage(Long anId) {
        conversation.setTimeout(10 * 60 * 1000);
        if (anId != null) {
            value = em.find(Language.class, anId);
        }
    }

    @BeforeCompletion
    public void transactionComplete(){
        System.out.println("transactionComplete");
    }

    public Language getValue() {
        return value;
    }

    @Produces
    @Named
    @ConversationScoped
    public Language getLanguage() {
        return getValue();
    }

    public void setValue(Language aValue) {
        value = aValue;
    }

    @End
    public String save() {
//      displays the changed attribute:
        System.out.println("save code: "+value.getCode());

//      why is either this required:
//      boolean tempContains = em.contains(value);
//      System.out.println("managed: "+tempContains);

//      or: why is persist required:
        em.persist(value);
        return "languages?faces-redirect=true";
    }

    @End
    public String cancel() throws SystemException {
        transaction.setRollbackOnly();
        return "languages?faces-redirect=true";
    }

}

Ответы [ 2 ]

1 голос
/ 18 октября 2012

Мой опыт в основном связан со швом-2, но здесь он должен быть в равной степени применим.

Разговор и сеанс JPA разделены в шве по той простой причине, что окончание разговора может не привести к сохранению сущности.

Например, действие отмены в длительном диалоге завершит разговор (так как больше нет необходимости поддерживать разговор)

Учитывая, что вы выполняете откат для отмены вваш пример, также может показаться логичным, что вам нужно будет вызвать сброс, как предложено @ user1187037 (теоретически коммит, но я не думаю, что это разрешено)

Я думаю, что, возможно, была конфигурация, которую вы могли быустановить так, чтобы он заканчивался в конце разговора, но я могу ошибаться.

В любом случае http://javalangblog.blogspot.co.uk/2010/04/flush-mode-conversation.html, кажется, предлагает решение

Надеюсь, что поможет.

РЕДАКТИРОВАТЬ: вы можете настроить режим сброса на разговор, используя xml

<begin-conversation join="true" flush-mode="COMMIT" />

и используя аннотации

@Begin(flushMode=COMMIT)

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

Ссылки:

http://docs.jboss.org/seam/3/persistence/3.0.0.Alpha1/reference/en-US/html_single/#d0e249 http://docs.jboss.org/seam/3/latest/api/org/jboss/seam/persistence/FlushModeType.html

0 голосов
/ 16 марта 2012

Попробуйте добавить @Remove аннотацию к методам, аннотированным @End.

На мой взгляд, аннотация @End не приводит к уничтожению бобов.Таким образом, контекст постоянства активен даже после выполнения save(), и его содержимое не может быть сброшено в базу данных.

...