У меня есть проект Java EE, а база данных MySQL управляется с помощью ORM. Я много работал с Hibernate, чтобы узнать, что я делаю неправильно, и я думаю, что понимаю сессию/транзакцию, но я не знаю, как я могу это решить в своем случае/архитектуре.JPA (Hibernate) - Session/Transaction и lazy loading
У меня есть проект и лицо, которые находятся в двунаправленном соотношении n: m с таблицей соединений. Проект является владельцем карт. Теперь я хочу удалить Лицо, которое связано с проектом.
Так что я подумал, что я могу сделать это:
Person person = findPersonById(personId);
Set<Project> projects = person.getProjects();
Iterator<Project> iterator = projects.iterator();
while (iterator.hasNext()) {
Project project = iterator.next();
if (project.getPersons().contains(person)) {
project.getPersons().remove(person);
projectDao.updateProject(project);
}
}
personDao.removePerson(personId);
Но я получаю ошибку в этой строке:
Iterator<Project> iterator = projects.iterator();
Но мне кажется, что это связано с:
Person person = findPersonById(personId);
и:
public Person findPersonById(int personId) {
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session sess = sessionFactory.getCurrentSession();
Transaction tx = sess.beginTransaction();
try {
Person person = (Person)sess.createQuery("from Person where id = "+personId).list().get(0);
tx.commit();
return person;
}
catch (IndexOutOfBoundsException ex) {
return null;
}
}
Здесь я делаю транзакцию и получаю только объект person, но не соответствующие проекты. Итератор попытается их получить, но не может, потому что моя транзакция/сессия закрыта. Это из-за моей архитектуры:
у меня есть: IPersonService -> IPersonImplementation -> IPersonDao -> IPersonDaoImplementation и только метод в IPersonDaoImplementation открывает и закрывает сделку. Поэтому в моей службе ServicePersonImplementation я не могу выполнять некоторые связанные с DB вещи (я не хочу иметь FetchType.EAGER в моей аннотации @ManyToMany, потому что это загрузится в ненужные вещи). Поскольку, как только он возвращается из моей DaoImplementation, я не могу выполнять другие действия с возвращенным человеком (в моем случае получить все проекты, которые объединены с этим человеком).
Итак, что я могу сделать в моем случае?
С наилучшими пожеланиями Тим.
Update: PersonDaoImpl, удалить метод:
public void removePerson(int personId){
Person p = findPersonById(personId);
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session sess = sessionFactory.getCurrentSession();
Transaction tx = sess.beginTransaction();
sess.delete(p);
sess.flush();
tx.commit();
}
Трассировка ошибки:
ОШИБКА: org.hibernate.LazyInitializationException - не удалось инициализировать лениво коллекцию роли: ком .testdomain.testproject.domain.Person.projects, сеанс или сеанс закрыты. org.hibernate.LazyInitializationException: не удалось лениво инициализировать коллекцию роли: com.testdomain.testproj ect.domain.Person.projects, ни одна сессия или сеанс был закрыт на org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException (AbstractPersistentCollection.java:383) в org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected (AbstractPersistentCollection.java:375) на org.hibernate.collection.AbstractPersistentCollection.initialize (AbstractPersistentCollection.java:368) в org.hibernate.collection.AbstractPersistentCollection.read (AbstractPersistentCollection.java:111) в org.hibernate.collection.PersistentSet.iterator (PersistentSet. java: 186) at com.testdomain.testproject.dao.impl.PersonDaoImplHibernate.removePerson (PersonDaoImplHibernate.java:71) at com.testdomain.testproject.service.impl.PersonServiceImpl.removePerson (PersonServiceImpl.java:88) at com.testdomain.testproject.service.PersonTest.testRemovePerson (PersonTest.java:180) на sun.reflect.NativeMethodAccessorImpl.invoke0 (нативный метод) на sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) в sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) в java.lang .reflect.Method.invoke (Method.java:597) на org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall (FrameworkMethod.java:44) на org.junit.internal.runners.model.ReflectiveCallable.run (ReflectiveCallable.java:15) at org.jun it.runners.model.FrameworkMethod.invokeExplosively (FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate (InvokeMethod.java:20) at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored (BlockJUnit4ClassRunner.java:79) на org.junit.runners.BlockJUnit4ClassRunner.runChild (BlockJUnit4ClassRunner.java:71) на org.junit.runners.BlockJUnit4ClassRunner.runChild (BlockJUnit4ClassRunner.java:49) в org.junit.runners. ParentRunner $ 3.run (ParentRunner.java:193) at org.junit.runners.ParentRunner $ 1.schedule (ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren (ParentRunner.java:191) at org.junit.runners.ParentRunner.access $ 000 (ParentRunner.java:42) на org.junit.run ners.ParentRunner $ 2.оценить (ParentRunner.java:184) на org.junit.internal.runners.statements.RunBefores.evaluate (RunBefores.java:28) на org.junit.runners.ParentRunner.run (ParentRunner.java : 236) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run (JUnit4TestReference.java:46) at org.eclipse.jdt.internal.junit.runner.TestExecution.run (TestExecution.java:38) на org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:467) на org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:683) на org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run (RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main (RemoteTestRunner.java:197)) Не удалось удалить пользователя: не удалось лениво инициализировать коллекцию роли: com.testdomain.testproject.domain.Person.projects, сеанс или сеанс закрыты
Какая ошибка? – willcodejavaforfood
Ленивая инициализация или если я делаю некоторые изменения, я получаю ошибку, что ее нельзя удалить из-за ограничений внешнего ключа, но теперь я понимаю, почему проблема возникает, но как я могу решить эту элегантность? Если итерация будет внутри транзакции, у меня не будет этой проблемы ?! – Tim
Правильно, вы хотите удалить Личность из любых проектов внутри метода удаления PersonDao – Ophidian