Как использовать диспетчер персистентности JDO? - PullRequest
5 голосов
/ 15 ноября 2010

У меня есть два вопроса относительно того, как создать / использовать диспетчер персистентности JDO (далее - «PM»).

Скажем, в веб-приложении Java, если у меня есть 10 сущностей, которые можно логически сгруппировать в 2 группы (например, 5 сущностей, связанных с пользователем, и 5 сущностей, связанных с бизнесом)

  1. Нужно ли мне два разных руководителя для управления этими двумя группами или достаточно одного?
  2. Что касается инициализации, должен ли я использовать одноэлементный экземпляр PM (который будет совместно использоваться всеми пользователями, использующими приложение в данный момент времени) или я должен создать PM для каждого сеанса?

1 Ответ

14 голосов
/ 15 ноября 2010

Согласно документации JDO вы создаете один PersistenceManagerFactory для каждого хранилища данных.Если вы используете JDO для доступа к базам данных через SQL и у вас более одной базы данных, вам понадобится один PersistenceManagerFactory для каждой базы данных (поскольку при создании PersistenceManagerFactory необходимо указать URL-адрес JDBC, имя пользователя и пароль)..

Для простых случаев использования вы можете просто создать PersistenceManager, когда вам это нужно, и закрыть его в предложении finally (см. документация менеджера постоянства ).

Если вы используете транзакции, и код для обновления сущностей может быть распределен по нескольким методам или объектам, я рекомендую создать PersistenceManager по требованию и сохранить его в ThreadLocal (или объекте области запроса, если вы используете Guiceили весна).Это обеспечит участие любого кода, который выполняет обновления, в текущей транзакции.Обязательно закройте PersistenceManager в конце запроса.

Если вам нужна только одна фабрика диспетчера персистентности, вы можете сделать:

public class Datastore {
  private static PersistenceManagerFactory PMF;
  private static final ThreadLocal<PersistenceManager> PER_THREAD_PM
      = new ThreadLocal<PersistenceManager>();

  public static void initialize() {
     if (PMF != null) {
       throw new IllegalStateException("initialize() already called");
     }
     PMF = JDOHelper.getPersistenceManagerFactory("jdo.properties");
  }

  public static PersistenceManager getPersistenceManager() {
    PersistenceManager pm = PER_THREAD_PM.get();
    if (pm == null) {
      pm = PMF.getPersistenceManager();
      PER_THREAD_PM.set(pm);
    }
    return pm;
  }

  public static void finishRequest() {
    PersistenceManager pm = PER_THREAD_PM.get();
    if (pm != null) {
      PER_THREAD_PM.remove();
      Transaction tx = pm.currentTransaction();
      if (tx.isActive()) {
         tx.rollback();
      }
      pm.close();
    }
  }
}

Любой код, для которого требуется диспетчер персистентности.можете позвонить Datastore.getPersistenceManager()

Примечание. Я использовал все статические методы, чтобы упростить ответ на ваш вопрос.Если бы я использовал инфраструктуру внедрения зависимостей, такую ​​как Guice, я бы сделал методы нестатичными и связал бы Datastore как синглтон.

Вы можете вызвать finishRequest в фильтре сервлетов:

public class PersistenceManagerFilter implements javax.servlet.Filter {

  public init(FilterConfig filterConfig) {
    Datastore.initialize();
  }

  public void doFilter(ServletRequest request, 
      ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    try {
      chain.doFilter(request, response);
    } finally {
      Datastore.finishRequest();
    }    
  }
}
...