您好,欢迎来到12图资源库!分享精神,快乐你我!我们只是素材的搬运工!!
  • 首 页
  • 当前位置:首页 > 开发 > WEB开发 >
    扼杀功用的10个常见Hibernate错误
    时间:2018-01-11 21:07 来源:网络整理 作者:网络 浏览:收藏 挑错 推荐 打印

    我在很多运用顺序中修复过功用成绩,其中大部分都是由异样的错误惹起的。修复之后,功用变得更溜,而且其中的大部分红绩都很复杂。所以,假设你想改良运用顺序,那么能够也是小菜一碟。

    这里列出了招致Hibernate功用成绩的10个最常见的错误,以及如何修复它们。

    扼杀功用的10个常见Hibernate错误

    错误1:运用Eager Fetching

    FetchType.EAGER的启示曾经讨论了好几年了,而且有很多文章对它停止了详细的解释。我本人也写了一篇。但不幸的是,它依然是功用成绩最常见的两个缘由之一。

    FetchType定义了Hibernate何时初始化关联。你可以运用@OneToMany,@ManyToOne,@ManyToMany和@OneToOneannotation注释的fetch属性停止指定。

    @Entity 

    public class Author{ 

     

        @ManyToMany(mappedBy="authors"fetch=FetchType.LAZY) 

        private List<Book> books = new ArrayList<Book>(); 

     

        ... 

     

    当Hibernate加载一个实体的时分,它也会即时加载获取的关联。例如,当Hibernate加载Author实体时,它也提取相关的Book实体。这需求对每个Author停止额外的查询,因此常常需求几十甚至数百个额外的查询。

    这种办法是十分低效的,由于Hibernate不管你是不是要运用关联都会这样做。最好改用FetchType.LAZY替代。它会延迟关系的初始化,直到在业务代码中运用它。这可以避免少量不必要的查询,并提高运用顺序的功用。

    幸运的是,JPA标准将FetchType.LAZY定义为一切对多关联的默许值。所以,你只需求确保你不改动这个默许值即可。但不幸的是,一对一关系并非如此。

    错误2:疏忽一对一关联的默许FetchType

    接上去,为了避免立刻抓取(eager fetching),你需求做的是对一切的一对一关联更改默许的FetchType。不幸的是,这些关系在默许状况下会被即时抓取。在一些用例中,那并非一个大成绩,由于你只是加载了一个额外的数据库记载。但是,假设你加载多个实体,并且每个实体都指定了几个这样的关联,那么很快就聚集腋成裘,水滴石穿。

    所以,最好确保一切的一对一关联设置FetchType为LAZY。

    @Entity 

    public class Review { 

     

        @ManyToOne(fetch = FetchType.LAZY) 

        @JoinColumn(name = "fk_book"

        private Book book; 

     

        ... 

     

    错误3:不要初始化所需的关联

    当你对一切关联运用FetchType.LAZY以避免错误1和错误2时,你会在代码中发现若干n+1选择成绩。当Hibernate执行1个查询来选择n个实体,然后必须为每个实体执行一个额外的查询来初始化一个延迟的获取关联时,就会发作这个成绩。

    Hibernate透明地获取惰性关系,因此在代码中很难找到这种成绩。你只需调用关联的getter办法,我想我们大家都不希望Hibernate执行任何额外的查询吧。

    List<Author> authors = em.createQuery("SELECT a FROM Author a", Author.class).getResultList(); 

    for (Author a : authors) { 

        log.info(a.getFirstName() + " " + a.getLastName() + " wrote " 

                + a.getBooks().size() + " books."); 

    假设你运用开发配置激活Hibernate的统计组件并监视已执行的SQL语句的数量,n+1选择成绩就会更容易被发现。

    15:06:48,362 INFO [org.hibernate.engine.internal.StatisticalLoggingSessionEventListener] - Session Metrics { 

      28925 nanoseconds spent acquiring 1 JDBC connections; 

      24726 nanoseconds spent releasing 1 JDBC connections; 

      1115946 nanoseconds spent preparing 13 JDBC statements; 

      8974211 nanoseconds spent executing 13 JDBC statements; 

      0 nanoseconds spent executing 0 JDBC batches; 

      0 nanoseconds spent performing 0 L2C puts; 

      0 nanoseconds spent performing 0 L2C hits; 

      0 nanoseconds spent performing 0 L2C misses; 

    (责任编辑:admin)