我正在增强旧的 Spring/Hibernate 应用程序,但我陷入困境。我有一种方法可以读取 3000 多行长的文件,每行都有一条记录,必须与数据库中的某些内容进行比较,然后必须将寄存器添加到数据库(多对多表)。
表和关系是
Branch have 多种产品 , Product are in 许多分行.
Products have 许多产品, and a Category has 许多产品
还有更多的桌子在那里并且工作正常。
The new我创建的表/对象是分支、产品、分支到产品.
产品有一组 BranchToProduct对象,有 3 个字段
我需要将 BranchToProduct 对象添加到 Product 集合中,并根据从文件每一行获取的信息填充 3 个字段。
我添加了一行简单的行,应用程序抛出:
产品=
ProductDAO.findByModel(stringModel);
未能延迟初始化
角色集合:
com.bamboo.catW3.domain.Product.products,
没有会话或会话已关闭
如果我进入休眠映射(hbm 文件)并设置关系product_to_products 懒惰 = false,该行单独运行良好,但如果我尝试将其放在文件周期中,应用程序始终挂在正在处理的第 18 行,不会无论我使用哪个文件或内容的顺序,控制台都会停止工作,必须关闭 java 杀死进程。
不管怎样,在调试中,我得到了很多 HQL 来进行简单的查找,13 行 HQL 直到我在lazy = true时得到错误,以及当我使用lazy = false并将其放入循环中时得到很多行。
我想我应该尝试用lazy=true来解决这个问题。
这种情况让我不禁思考:
1.- 当lazy=true时。为什么我无法在该方法中运行该命令的一行,但它在该类的其他方法上运行良好?
顺便说一句,这是一个名为 CatalogFacade 的类,它实现了其他类的方法: (CategoryFacade,ContainerFacade,ProductFacade,ProductOptionFacade,ProductStatusFacade,UserFacade,EmailFacade,FileFacade,BranchOfficeFacade)
这是代码
产品Dao.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}无法计算表达式方法抛出“org.hibernate.LazyInitializationException”异常。
不过其他属性还是可以的。该产品在数据库中甚至没有其他产品。
UPDATE
深入挖掘内部情况
产品.find(int)
在收到异常之前的行中,我们可以在调试中看到product.products数组有错误,而不是您可以看到的值lazyInitialitationException。How ever,如果我从另一个方法调用它,则找到该数组。所以它不可能在里面虽然该方法仅接收一个整数。
此外,我们发现这种情况在应用程序的整个生命周期中都发生过,有时工作人员复制了类似的方法,但将其更改为将此损坏的数组设置为 null。所以我 100% 确定这个应用程序消耗的资源比它应该消耗的资源多。
它有 Flex 中的视图,以及后来创建的 JSTL 中的视图,并且根据调用方法的人,对于相同的方法以不同的方式抛出异常。
添加更多信息。这就是在抽象 DAOImpl 中实现 Product.find 的方式:
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>