有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用Spring在Hibernate中处理java会话

我不是冬眠的初学者,但我是春天冬眠的初学者。我读了《春天在行动》一书。所以我写了一个小应用程序来理解书中的例子。这里是我申请的摘录。如果你愿意,我可以给你更多

@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public void runQuery()
{
    final BuildingDAO buildingDAO = ( BuildingDAO ) applContext.getBean( "buildingDAO" );
    final Building building = buildingDAO.getBuildingById( "HQ" );
    logger.debug( "Loaded building: " + building.getId() );
    logger.debug( "Loaded building: " + building.getName() );
}

加载对象时没有任何问题。主键的日志也没有问题。但是字符串属性的日志会导致LazyInitializationException。 我明白为什么会这样。Hibernate返回了一个带有代理atributes的代理。当我想要访问延迟加载的属性时,Hibernate试图加载该值,但会话已关闭。惰性加载是Hibernate的一个重要特性,我不想错过它

Spring为我管理会话处理。Spring在Hibernate模板的load方法中打开Hibernate会话,并在该方法完成后关闭会话

但现在我想建议Spring,会话应该在整个方法(runQuery())中打开,如上图所示。我想显示对象的一些属性。我提到我可以使用Spring的Transaction manager来实现这一点。所以我使用Spring的事务性注释。但它不起作用。也许我使用事务管理器的假设是错误的

有人建议Spring为整个方法举行一次公开会议吗


共 (3) 个答案

  1. # 1 楼答案

    如果希望RunQuery在Spring事务中运行,则必须从容器中获取类的对象,将其定义为Spring bean。这样,Spring就可以围绕bean(以及它定义的任何方法)包装事务逻辑
    将该类定义为Springbean还可以避免调用(BuildingDAO)applContext.getBean("buildingDAO"),因为spring会将dao连接到类中(如果在上下文xml或属性中正确定义它)

  2. # 2 楼答案

    更改为“必需”或将其留空,将解决您的问题。传播支持并不会真正启动事务。。。 见http://www.ibm.com/developerworks/java/library/j-ts2.html

    您可能没有禁用非事务性读取(默认为启用),因此读取是成功的,但该读取的事务仅用于读取本身(不用于返回的对象上的后续读取)

    登录交易活动的类别为组织。springframework。事务IIRC——如果你把它转到DEBUG,你会看到事务启动和提交的细节

  3. # 3 楼答案

    你确定Propagation.SUPPORTS是你真正需要的吗?这并不强制执行事务的存在,它只是在事务存在时使用它。系统的其他部分需要启动并提交事务。如果不存在,则会话可能无法像日志语句那样维护,从而导致延迟加载错误

    尝试使用其他隔离级别(比如REQUIRED,或者更好,不要全部指定,依赖默认设置),看看这是否能解决问题