Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么hibernate会生成约500个SQL查询?_Java_Mysql_Hibernate - Fatal编程技术网

Java 为什么hibernate会生成约500个SQL查询?

Java 为什么hibernate会生成约500个SQL查询?,java,mysql,hibernate,Java,Mysql,Hibernate,在一个遗留项目中尝试优化Hibernate 4.2生成的MySQ慢速查询时,我发现下面的代码生成了近500个包含许多重复项的SQL查询: class MyDAO { public List<Message> findMessages() { Session session = MyHibernateUtils.openSession(); String queryStr = "SELECT DISTINCT m FROM Message m

在一个遗留项目中尝试优化Hibernate 4.2生成的MySQ慢速查询时,我发现下面的代码生成了近500个包含许多重复项的SQL查询:

class MyDAO {
    public List<Message> findMessages() {
        Session session = MyHibernateUtils.openSession();

        String queryStr = "SELECT DISTINCT m FROM Message m "
                + " LEFT JOIN fetch m.types types "
                + " LEFT JOIN fetch m.mainType mainType "
                + " LEFT JOIN fetch m.place place "
                + " LEFT JOIN fetch m.building building "
                + " LEFT JOIN fetch m.city city "
                + " LEFT JOIN fetch m.kind kind "
                + " LEFT JOIN fetch m.domain domain "
                + " LEFT JOIN fetch m.action action "
                + " LEFT JOIN fetch m.customParameterA customParameterA "
                + " LEFT JOIN fetch m.customParameterB customParameterB "
                + " LEFT JOIN fetch m.scheduleEvents scheduleEvents "
                + " LEFT JOIN fetch m.comments comments "
                + " LEFT JOIN fetch m.messageLastActivities messageLastActivities "
                + " LEFT JOIN fetch m.customListA customListA "
                + " LEFT JOIN fetch m.childEvents childEvents "
                + " LEFT JOIN fetch m.parentEvent parentEvent "
                + " WHERE ...";

        List<Message> messages;
        try {
            session.getTransaction().begin();

            Query query = session.createQuery(queryStr);
            query.setTimeout(10);

            messages = query.list();
            session.getTransaction().commit();
        } catch (RuntimeException e) {
            session.getTransaction().rollback();
            throw e;
        } finally {
            session.close();
        }

        return messages;
    }
}
如何避免出现如此多的SQL查询

我不知道这是否有帮助,但在实体之间有很多的关系


感谢您的帮助。

根据您的关系设计,Fetch in@OneToMany和@ManyToMany的默认值是惰性的,这意味着当您调用getter方法时,hibernate将在子实体中加载相关记录,并执行另一个查询来加载该记录,例如:select*from foo,其中id=,所以,若加载的实体主实体包含许多子实体,比如ManyToMany或OneToMany,那个么您将在控制台中看到许多查询。 若要取消这些查询,可以将Fetch设置为EAGER,但在优化时不建议这样做

@Entity
public class MainEntity {

@ManyToMany(Fetch = FetchType.EAGER)
public List<Foo> foos;

}

您应该检查hibernate生成的查询,以查看哪个表经常被访问

您还必须加入由相关实体关联的获取实体,请参见此处:

我个人更喜欢使用带注释的@BatchSize进行惰性加载,以保持惰性查询计数较小。仅使用2的批处理大小就可以将查询计数减半


还可以看看@Cache注释,它可以显著减少查询计数。想想所有几乎是静态的东西,比如城市/建筑/类型/领域等等

ORM框架大部分时间都是这样工作的。。。他们需要从id=1的表中触发一个额外的SELECT*,以查找相关的entiy@RaymondNijland不,他们没有。好吧,在最坏的情况下,他们会这样做,但这在大多数情况下是可以避免的,当然在Hibernate中也是可以避免的。只有非常幼稚的ORM才会这样做,因为它会破坏性能,使框架变得毫无价值。至于OP,启用Hibernate的SQL日志环顾四周,我不记得它是如何完成的,我不记得会执行什么查询。这将允许您确定原因,这可能只是您需要修复的单个N+1查询。true@Kayaman..@Kayaman是的,他们是这样做的,raymond是对的。Eagar抓取通常需要额外的操作,如添加注释或jointhank you@Moodi以获取响应!使用left join fetch是否已经强制每个*ToMany依赖项都被急切地获取?是的,它将获取属性。您可以用于子实体中的实体。正确!谢谢@dognose,在添加了一些缺失的相关实体之后,查询的数量大大减少了。