#java #hibernate #jpa
#java #переход в спящий режим #jpa
Вопрос:
Я новичок в JPA и гибернации. Я пытаюсь вставить Thing
в мою Thing
таблицу в моей базе данных, используя entityManager.persist()
. Когда я делаю это внутри сервлета, Thing
добавляется, но когда я делаю это из отдельного класса и вызываю метод из сервлета, Thing
не добавляется.
Это работает:
// servlet
@PersistenceContext
EntityManager em;
@Resource
UserTransaction utx;
protected void processRequest(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
try {
Thing thing = new Thing("word");
utx.begin();
em.persist(thing);
utx.commit();
} catch (Exception ex) { }
}
Но это не:
// servlet
protected void processRequest(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
Thing thing = new Thing("word");
ThingDao thingDao = new ThingDao();
thingDao.add(thing);
}
Учитывая,
// ThingDao
public class ThingDao {
@PersistenceContext
EntityManager em;
@Resource
UserTransaction utx;
public void add(Thing thing) {
try {
utx.begin();
em.persist(thing);
utx.commit();
} catch (Exception ex) { }
}
}
Почему второй метод не работает? Как мне заставить это работать?
Комментарии:
1.
new ThingDao()
— создание подобного экземпляра приводит к тому, что контейнер не знает о его существовании, и, следовательно, внедрение не может произойти. Либо позвольте контейнеру внедрить экземпляр в ваш сервлет, либо выполните поиск (конечно, это должен быть вводимый компонент, и вам, вероятно, не нужна зависимая область CDI)2. Кроме того, вы должны понимать, что
catch (Exception ex) { }
это очень опасно. Скорее всего, вы получитеNullPointerException
но поскольку вы даже не регистрируете исключение, вы его никогда не видите и, следовательно, должны задаться вопросом «почему эта вещь не сохраняется» — регистрация исключения должна была привести к тому, что вы поняли, чтоutx
иem
вThingDao
равны null, и это соответствующим образом повлияло бы на ваш вопрос. — Удаление: не используйте пустые блоки catch!3. попробуйте отправить в ThingDao em тоже подобное
class ThingDao { public ThingDao(EntityManager em){ this.em=em;}
и в ProcessRequest сделайтеThingDao thingDao = new ThingDao(em); thingDao.add(thing);
4. @Dred попробовал то, что вы предложили, не сработало. Однако я изменил
add
метод внутриThingDao
и вызвал его с помощьюthingDao.add(thing, em, utx)
, передав EntityManager и UserTransaction при вызове метода, и теперь он добавляет запись просто отлично! Но приходится передаватьem
иutx
в дополнение кthing
… Интересно, есть ли другой способ добиться этого без необходимости делатьem.persist(thing)
внутри самого сервлета.5. Spring поможет вам с этим или другим DI). Я видел ответ по этому поводу
Ответ №1:
Аннотируйте с помощью @Component и автоматически подключайте его, потому что нет DI.
// ThingDao
@Compoenent
public class ThingDao {
@PersistenceContext
EntityManager em;
@Resource
UserTransaction utx;
public void add(Thing thing) {
try {
utx.begin();
em.persist(thing);
utx.commit();
} catch (Exception ex) { }
}
}
//В сервлете
@Autowired
ThingDao td;
protected void processRequest(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
Thing thing = new Thing("word");
td.add(thing);
}
Ответ №2:
Изучая код, я предполагаю, что вы используете Spring, если да, то вам не хватает следующего :
-
класс ThingDao
@Транзакционный @Общедоступный класс репозитория ThingDao {
-
serverlet: вам нужно автоматически подключить ThingDao туда
@Autowired ThingDao td;
Надеюсь, это поможет
Комментарии:
1. На самом деле я заранее не использовал Spring, только Hibernate. Но я добавил библиотеку Spring Framework 4.0.1 в свой проект (в NetBeans) и попробовал то, что вы предложили. Все тот же результат.
2. вы пробовали установить EntityManager em; и UserTransaction utx; из serverlet? т.Е. вам нужно создать setter для em и utx в ThingDao, а затем установить их в serverlet