Я улучшаю старое приложение Spring / Hibernate, и я застрял. У меня есть метод, который читает файл длиной более 3000 строк, в каждой строке есть запись, которую нужно сравнить с чем-то в базе данных, а затем добавить в базу данных регистр (таблица «многие ко многим»).
Таблицы и отношения
Филиал имеет много Продукт , Продукт находится в много филиалов .
Продукты имеют много продуктов , а Категория имеет много продуктов
И есть еще таблицы, которые были там и работают нормально.
Созданные мной новые таблицы / объекты: Branch, Product, BranchToProduct .
Продукты имеют набор объектов BranchToProduct , которые имеют 3 поля
Мне нужно добавить объекты BranchToProduct в набор Product с 3 полями, заполненными информацией, которую я получаю из каждой строки файла.
Я добавляю простую строку и приложение выдает:
product =
productDAO.findByModel (stringModel);
не удалось лениво инициализировать
Коллекция ролей:
com.bamboo.catW3.domain.Product.products,
ни один сеанс или сеанс не был закрыт
Если я перехожу к отображению гибернации (файл hbm) и устанавливаю отношение product_to_products lazy = false, строка работает нормально, но если я пытаюсь поместить ее в файловый цикл, приложение всегда зависает на 18-й строке, обрабатываемой , не имеет значения, какой файл я использую или порядок содержимого, консоль перестает работать, приходится закрывать Java, убивая процесс.
В любом случае, при отладке я получаю много HQL для простого поиска, 13 строк HQL, пока не получу ошибку, когда lazy = true, и МНОГО строк, когда я использую lazy = false и положу его на цикл.
Думаю, мне следует попытаться исправить проблему с помощью lazy = true.
Эта ситуация заставляет меня задуматься:
1.- Когда ленивый = правда. Почему я не могу запустить одну строку этой команды этого метода, но он отлично работает на других методах класса?
кстати, это класс с именем CatalogFacade, который реализует методы других классов: (CategoryFacade, ContainerFacade, ProductFacade, ProductOptionFacade, ProductStatusFacade, UserFacade, EmailFacade, FileFacade, BranchOfficeFacade)
Это код для
productDao.find ():
public Product find(Integer id) throws DataAccessException {
Product product= (Product) super.find(Product.class, id);
if(product!=null){
product.setProductAttributes(new TreeSet<ProductAttribute>(product.getProductAttributes()));
for (Product ptp : product.getProducts()){
ptp.setProductAttributes(new TreeSet<ProductAttribute>(ptp.getProductAttributes()));
}
}
Исключение было выброшено прямо в этой строке, в конце концов для:
pptp.setProductAttributes(new TreeSet<ProductAttribute>(ptp.getProductAttributes()))
в отладчике Intelij я вижу объект, неправильно сформированный из запроса:
product.getProducts () = {org.hibernate.collection.PersistentSet@4312 Eventunable для оценки метода выражения, вызвавшего исключение org.hibernate.LazyInitializationException.
Как бы то ни было, другие атрибуты в порядке. У этого продукта даже нет других продуктов в базе данных.
UPDATE
Глубоко копаясь в ситуации, внутри
product.find (INT)
В строке перед тем, как я получу исключение, мы можем увидеть в отладке, что в массиве product.products есть ошибка, вместо значения, которое вы видите в lazyInitialitationException. Как бы то ни было , если я вызову его из другого метода, массив будет находить. Так что он не может быть внутри него ДАЖЕ, хотя метод получает только целое число.
Кроме того, мы обнаружили, что это происходило на протяжении всего жизненного цикла приложения, иногда сотрудники повторяли метод, подобный ему, но изменяя его, устанавливая значение NULL для этих поврежденных массивов. Поэтому я на 100% уверен, что это приложение потребляет больше ресурсов, чем должно.
У него есть представления во Flex и более поздние представления в JSTL, где они были созданы, и в зависимости от того, кто вызывает методы, исключения вызываются по-разному для одних и тех же методов.
Добавление дополнительной информации. Вот как produt.find реализован в AbstractDAOImpl:
public final Object find(Class clazz, Integer id) throws DataAccessException{
return getHibernateTemplate().get(clazz,id);
}
и это моя конфигурация диспетчера транзакций, метод аннотации, описанный в первом ответе по fillip, не работал:
<bean id="catalogFacade" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager"/>
</property>
<property name="target">
<ref local="catalogFacadeTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="contains*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="login*">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</bean>