Spring/Hibernate 延迟加载需要帮助

2024-01-05

我知道这个问题已经讨论过很多次了。我只是不明白这是如何工作的或者我的错误在哪里。
我认为给你一个简化的例子是向你展示我正在尝试做的事情以及我正在采取的假设的最佳方式......

我有一个带有名称的产品类。该名称是一个惰性的 String 属性。

My DAO:

public abstract class HibernateProductDAO extends HibernateDaoSupport implements ProductDAO
{
    public List getAll()
    {
        return this.getHibernateTemplate().find("from " + this.getDomainClass().getSimpleName());
    }
}

我的服务接口:

public interface ProductService {
    //This methods are Transactional, but same exception error is thrown if there weren't
    @Transactional
    public Product getProduct();
    @Transactional
    public String getName(Product tp);
}

我的服务实施:

public class ProductServiceImpl implements ProductService  {
    private ProductDAO productDAO;
    public Product getProduct() {
        List ps = this.productDAO.getAll();
        return (Product) ps.get(0);
    }
    public String getName(Product p){
        return p.getName();
    }
}

我的主要课程:

public class Main {
    private ProductService productService;
    public static void main(String[] args) {
        Main main= new Main();          
        main.productService= (ProductService)(new ClassPathXmlApplicationContext("applicationContext.xml")).getBean("productProxy");
        //load the product without the name
        Product p = main.productService.getProduct();
        //load the lazy name
        System.out.println(main.productService.getName(p));  //EXCEPTION IS THROWN IN THIS LINE
    }
    public void setProductService(ProductService productService) {
        this.productService= productService;
    }

    public ProductService getProductService() {
        return productService;
    }

我的applicationContext.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:util="http://www.springframework.org/schema/util"
   xmlns:jee="http://www.springframework.org/schema/jee"
   xmlns:lang="http://www.springframework.org/schema/lang"
   xmlns:aop="http://www.springframework.org/schema/aop"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xmlns:sca="http://xmlns.oracle.com/weblogic/weblogic-sca">

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
        <property name="url"><value>jdbc:oracle:thin:@${hostname}:${port}:${schema}</value></property>
        <property name="username"><value>${username}</value></property>
        <property name="password"><value>${password}</value></property>
    </bean>

    <!-- Hibernate SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource"><ref local="dataSource"/></property>
        <property name="configLocation"><value>hibernate.cfg.xml</value></property>
        <property name="configurationClass"><value>org.hibernate.cfg.AnnotationConfiguration</value></property>
    </bean>

    <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory"><ref local="sessionFactory"/></property>
    </bean>

    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
        <property name="sessionFactory"><ref bean="sessionFactory"/></property>
        <property name="allowCreate" value="true"/>
    </bean> 
    <bean id="productDAO" class="product.model.data.ProductDAO" >
        <property name="sessionFactory" ref="sessionFactory"/>
</bean>
    <bean id="hibernateInterceptor"
      class="org.springframework.orm.hibernate3.HibernateInterceptor">
        <property name="sessionFactory">
            <ref bean="sessionFactory"/>
        </property>
    </bean>
    <bean id="productService"
      class="product.services.ProductServiceImpl">
        <property name="productDAO">
            <ref bean="ProductDAO"/>
        </property>
    </bean>
    <bean id="productProxy"
      class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target">
             <ref bean="productService"/>
        </property>
        <property name="proxyInterfaces">
             <value>product.services.ProductService</value>
        </property>
        <property name="interceptorNames">
            <list>
                <value>hibernateInterceptor</value>
            </list>
        </property>
    </bean>
</beans>

异常片段:

11:59:57,775 [main] DEBUG org.springframework.orm.hibernate3.SessionFactoryUtils  - Opening Hibernate Session
11:59:57,775 [main] DEBUG org.hibernate.impl.SessionImpl  - opened session at timestamp: 12749723977
11:59:57,777 [main] ERROR org.hibernate.LazyInitializationException  - could not initialize proxy - no Session 
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:108)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:150)
    at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)

如果我假设 HibernateInterceptor 在不同的调用中保持 Hibernate 会话打开,我是对的吗?如果是这样,为什么会话在加载产品对象后关闭?

我在某处读到我也可以使用 OpenSessionInViewInterceptor,但我无法使其工作。您将如何将该拦截器添加到这个小示例中?

是否存在任何代码错误或对其工作原理的误解?

你知道我可以下载什么简单的示例代码来检查它是如何工作的吗?

提前致谢, 内乌基诺


问题是 HibernateInterceptor 从返回后关闭会话ProductService getProduct()

来自API DOCs http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/orm/hibernate3/HibernateInterceptor.html:

该拦截器在方法调用之前将新的 Hibernate Session 绑定到线程,然后在出现任何方法结果时关闭并删除它。如果已经有一个预绑定的 Session(例如来自 HibernateTransactionManager 或来自周围的 Hibernate 拦截方法),则拦截器只需参与其中即可。

并为以下调用打开一个新的ProductService.getProductName()。新创建的会话不知道您在上一个会话中从数据库中获取的产品实体。

您有多种可能性来解决此问题:

1.) 添加一个急切加载名称的方法,并在特定上下文中使用它,这是显而易见的;)

2.) 您可以使用以下命令将实体重新附加到活动会话Session.update(myProductEntity)打电话之前Product.getName() in ProductService.getProductName()

3.) 您可以将其全部包装在包装方法调用的事务中ProductService.getProduct() and ProductService.getProductName()参与。参见交易传播 http://static.springsource.org/spring/docs/2.5.x/reference/transaction.html#tx-propagation

4.) 在 Web 应用程序中,只要在控制器中创建了视图,您就可以使用 OpenSessionInViewFilter 来保持会话打开

5.)我认为你也可以直接使用AOP。您可以让会话在任意连接点上保持打开状态,但我在那里没有真正的经验,无法更具体;)

希望有帮助...

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring/Hibernate 延迟加载需要帮助 的相关文章

随机推荐

  • 如何将字节值转换为小数?

    我正在尝试从文件中加载一些十进制值 但我无法找出获取原始值并将其转换为小数的正确方法 我已将文件读入字节数组 每个四个字节块应该代表一个十进制值 为了帮助解决这个问题 我构建了一个表格 其中说明十进制值 1 到 46 如何表示为四个字节块
  • Visual Studio 调试器跳过断点

    在调试单元测试时 我的 Visual Studio 2008 IDE 的行为非常奇怪 我有一个断点 当我点击它并尝试使用 F10 单步执行时 测试就会结束 如果我在被测试方法内的每一行上设置断点 我最终会得到一个随机断点 而不是下一行的下一
  • 切割频谱图 matplotlib 中未使用的频率

    我有一个采样率为 16e3 的信号 其频率范围为 125 到 1000 Hz 因此 如果我绘制一个频谱图 由于所有未使用的频率 我会得到一个非常小的颜色范围 我尝试通过设置 x 限制来修复它 但这不起作用 有没有办法切断未使用的频率或用 N
  • 达到虚拟实时时间限制(178/120秒)

    我使用的是ubuntu 16版本并运行Odoo erp系统12 0版本 在我的应用程序日志文件中 我看到信息显示 已达到虚拟实时时间限制 178 120 秒 它到底意味着什么以及它会对我的应用程序造成什么损害 另外我如何增加虚拟实时限制 它
  • 无法加载本机 TensorFlow 运行时。原因:未找到图像。我究竟做错了什么?

    在配备四核 I7 和 NVIDIA GeForce GT 650M 的 Macbook Pro 上运行 从 virtualenv 运行 Tensorflow 时收到此错误消息 我做错了什么 我使用的是 protobuf 版本 3 2 0 t
  • 在没有 BindingSource 的情况下使用 BindingNavigator

    我有一个在数据库中完成分页的应用程序 也就是说 检索项目列表的调用包括页码 页面大小 并且将仅返回该页面的数据 例如 ItemCollection items ListAllItems 1 20 page 1 show 20 items p
  • Visual Studio 2010 RC 中的 IntelliSense 冻结

    每次我尝试编写一些内容时 IntelliSense 都会冻结 Visual Studio 我必须等待大约 2 分钟才能显示代码完成列表 我能使用的唯一方法就是完全关闭它 我已经安装了 Microsoft 的最后一个 IntelliSense
  • 如何在 Django 中为(基于类的)通用对象列表创建过滤器表单?

    我正在使用 Django 1 3 的基于类的通用视图来显示图像列表 但我想添加一个过滤器 使用户能够缩小显示结果的范围 我目前的方法有效 但感觉很黑客 class ImageFilterForm ModelForm class Meta m
  • 如何:优化 Symfony 表单的性能?

    我有一个表单 它是我的 ajax 请求的瓶颈 order this gt getDoctrine gt getRepository AcmeMyBundle Order gt find id order order order new Or
  • 在 data.table 中添加具有条件的虚拟对象?

    抱歉问了这么长的问题 我会尽力明确我的目标 我想使用 update 方法在 data table 中添加虚拟对象 就像这已经在此链接中得到回答 https stackoverflow com questions 18881073 creat
  • 如何将字节字符串转换为int?

    如何在Python中将字节字符串转换为int 像这样说 y xcc xa6 xbb 我想出了一个聪明 愚蠢的方法 sum ord c lt lt i 8 for i c in enumerate y xcc xa6 xbb 1 我知道必须有
  • UIScrollView 中缩放核心图形

    当我使用 UIScrollView 中的 UIView 子类进行放大时 我想知道哪种方法是缩放 Core Graphics 绘图的最佳方法 目前 当我放大时 绘图变得有点模糊 我知道这是正确的功能 我只是想知道开发人员如何覆盖它以保持图像清
  • android:textColor 实际上不起作用

    I have an Edittext in my application I have set it s default color to black in the following manner in the XML android t
  • .o、.a 和 .so 文件之间有什么区别?

    I know o是目标文件 a是静态库和 so是动态库吗 它们的物理意义是什么 我什么时候可以使用一些 什么时候不能使用 a是一个 档案 尽管存档可以包含任何类型的文件 但在 GNU 工具链的上下文中 它是一个目标文件库 其他工具链 特别是
  • 将整数数组编码为唯一的 int

    我有固定数量的 int 数组 其形式为 a b c d e 例如 2 2 1 1 2 where a and b可以是 0 到 2 之间的整数 c and d可以是 0 或 1 并且e可以是 0 到 2 之间的整数 因此有 3 3 2 2
  • 如何在远程unix服务器上查看html文件?

    我目前在远程 unix 服务器上有一个 html 文件 我可以通过 ssh 连接到该服务器 我一直在使用 SFTP 不断地将其传输到本地计算机以在编辑后查看它 但我对此感到厌倦 Mac 用户获得存储在远程 unix 服务器中的 html 文
  • 如何在 Ubuntu 21.10 上安装 python 3.6?

    由于 Ubuntu 21 10 和通常的版本不再支持 python 3 6deadsnakes方法也行不通 它给出以下错误 E The repository http ppa launchpad net deadsnakes ppa ubu
  • 如何使用反射 (Java) 调用私有静态方法?

    我想调用一个私有静态方法 我有它的名字 我听说可以使用Java反射机制来完成 我该怎么做 EDIT 我在尝试调用该方法时遇到的一个问题是如何指定其参数的类型 我的方法接收一个参数 其类型是 Map 因此我不能做Map
  • 设计限制每个用户一次只能进行一个会话

    我的应用程序使用 Rails 3 0 4 和 Devise 1 1 7 我正在寻找一种方法来阻止用户共享帐户 因为该应用程序是基于订阅的服务 我已经寻找了一个多星期了 但我仍然不知道如何实施解决方案 我希望有人已经实施了解决方案并能为我指明
  • Spring/Hibernate 延迟加载需要帮助

    我知道这个问题已经讨论过很多次了 我只是不明白这是如何工作的或者我的错误在哪里 我认为给你一个简化的例子是向你展示我正在尝试做的事情以及我正在采取的假设的最佳方式 我有一个带有名称的产品类 该名称是一个惰性的 String 属性 My DA