繁体   English   中英

JPA 2.0 / Hibernate:为什么LAZY使用“@OneToOne”开箱即用?

[英]JPA 2.0 / Hibernate: Why does LAZY fetching with “@OneToOne” work out of the box?

我的问题是关于JPA 2.0与Hibernate,@ OneToOne关系和延迟加载。

首先我的设置:

  • Spring 3.0.5.RELEASE
  • SprnigData JPA 1.0.1.RELEASE
  • Hibernate 3.5.2-最终版
  • DBMS:PostgreSQL 9.0

我最近发现这样一个事实:@OneToOne关系不能以懒惰的方式(FetchType.LAZY)获取,至少没有字节代码检测,编译时间编织等。 许多网站都说这个,例如:

事情是,在我的设置中,@OneToOne实体的延迟加载似乎“开箱即用”,我真的想了解原因。 请看看我的单元测试:

@Test
@Transactional
public void testAvatarImageLazyFetching()
{
    User user = new User();
    user.setAvatarImage( new AvatarImage() );

    User = userRepository.save( user );

    entityManager.flush();
    entityManager.clear();

    User loadedUser = userRepository.findOne( user.getId() );
    assertNotNull( loadedUser );

    PersistenceUtil persistenceUtil = Persistence.getPersistenceUtil();

    assertTrue( persistenceUtil.isLoaded( loadedUser ) );
    assertFalse( persistenceUtil.isLoaded( loadedUser, "avatarImage" ) );
}

这个测试用例是成功的,在Hibernates SQL日志输出中,我可以清楚地看到,“avatarImage”不会被提取,只是“用户”(只有一个SELECT,没有JOIN,没有访问“AvatarImage”表)等等。)

User类中的单向@OneToOne关系服务如下所示:

@OneToOne( cascade = CascadeType.ALL, fetch = FetchType.LAZY )
private AvatarImage    avatarImage;

所以,一切都很简单 - 它似乎工作。

重复我的问题:为什么它可以工作,为什么可以懒惰地取出“AvatarImage”,尽管它是用@OneToOne关联引用的?

我非常感谢您提供的任何帮助

非常感谢!

延迟加载OneToOne关系的问题仅在于它的反向部分(用mappedBy属性标记的那个)。 它在关系的拥有方面运作良好。 这些之间的差异在数据库级别上是明确的。 在您的情况下,问题是用户数据库表是否将ID为AvatarImage作为其中一列或反之。 如果User表有一个id为AvatarImage的列,那么延迟加载将像你说的“开箱即用”一样工作,但它不会反过来工作。

当执行某种形式的字节码检测时,使用Hibernate JPA提供程序进行@OneToOne注释关系的延迟提取工作开箱即用。 在您的情况下,我们可以排除构建时间工具(从您的评论中推断出它是开箱即用的)。 这使您有可能进行运行时编织,这在Hibernate和Spring中是很有可能的。 在最近的Hibernate版本中,Javassist被用作Hibernate的运行时字节码检测框架,而不是CGLIB的另一种选择( 自Hibernate 3.5.5以来已被弃用 )。

在Spring中是否启用Javassist的问题很容易回答。 Hibernate EntityManager(委托给Hibernate Core的JPA 2.0提供者)需要Javassist,因此它应该在Hibernate的类路径中,允许运行时编织类。 您可以通过设置断点(在连接到应用程序服务器的远程调试器中)来确认这一点,并且您会注意到User类的Hibernate托管实例不包含对AvatarImage实例的引用; 相反,它将包含对名为<package_name>.AvatarImage_$$_javassist_0 (允许延迟提取的代理)的增强类的引用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM