Играть! рамки немедленного сохранения?

В игре! если вы вызываете это:

void method()
{
User u = User();
u.name = "bob";
u.save();
while(true){/* endless loop */}
}

Ничего не будет фактически сохранено в db (класс Play! должен вернуть руку, чтобы сбросить сохраненные значения.)

Как мне нужно действовать, чтобы либо принудительно сбросить флажок, либо сделать его автоматически сбрасыванием при сохранении?

Ответ 1

Причина, по которой ваши изменения не видны в базе данных, заключается в том, что транзакция еще не совершена, и поэтому другие транзакции не могут видеть ваши изменения (по крайней мере, в хорошей базе данных, такой как PostgreSQL, Oracle, MSSQL, DB2). Чтобы ваши изменения были замечены, вам нужно будет совершить транзакцию до того, как она войдет в бесконечный цикл, например:

void method()
{
    User u = User();
    u.name = "bob";
    u.save();
    JPA.em().flush();
    JPA.em().getTransaction().commit();

    while(true){/* endless loop */}

}

Если вы хотите получить доступ к своей базе данных в бесконечном цикле или после нее (если у вас есть условие прерывания), вам нужно будет начать новую транзакцию или вы получите исключения из спящего режима, Сделайте это так:

void method()
{
    User u = User();
    u.name = "bob";
    u.save();
    JPA.em().flush();
    JPA.em().getTransaction().commit();

    while(true){
      // do some stuff

      /* TRANSACTIONAL BLOCK BEGINS */
      JPA.em().getTransaction().begin();
      try{
          // do some stuff
          // fetching, updating, deleting, whatever

          JPA.em().getTransaction().commit();
      }
      catch (Exception e)
      {
          // if an error occurs, rollback the transaction
          JPA.em().getTransaction().rollback();
      }
      /* TRANSACTIONAL BLOCK ENDS */
      // do some other stuff
    }
   // copy the TRANSACTIONAL BLOCK from above, if you want to do stuff after the "infinite loop" as well.
}

Важно, чтобы вы либо совершили, либо откат транзакции в цикле, если вы ее запустили, так как иначе вы столкнетесь с проблемами со слишком большим количеством открытых транзакций скоро.

Ответ 2

Как уже говорил Андрей Боднареску, вы можете использовать JPA.em().flush() или User.em().flush() для скрытого контекста персистентности.

Обратите внимание, однако, что это не сделает сохраненную сущность немедленно доступной для других транзакций, так как текущая транзакция должна быть выполнена первыми. Вы можете зафиксировать текущую транзакцию как JPA.em().getTransaction().commit().

Ответ 3

Try

User.em().flush();

Если я не ошибаюсь, игра по умолчанию! модель имеет право на обращение к EntityManager, к которому можно получить доступ.