Hibernate在保存关联对象的同时触发大量选择查询

时间:2014-09-18 00:19:11

标签: hibernate hibernate-mapping

Hibernate为它试图保留的每个关联对象触发一个选择查询。如果有5000个关联对象,那么5000个选择后跟5000个插入!!!

这导致了性能问题。任何人都可以了解为什么hibernate正在这样做,或者下面的配置导致了这一点。感谢。

以下是在保存FighterjetDO对象时由hibernate触发的sqls,请注意,在此示例中,有5个插入的5个选择查询,hibernate为关联的对象集FighterjetMissionsDO触发:

Hibernate: select max(jet_id) from fighterjet
Hibernate: select fighterjet_.mission_id, fighterjet_.JET_ID, fighterjet_.name as name1_ from fighterjetmissions fighterjet_ where fighterjet_.mission_id=? and fighterjet_.JET_ID=?
Hibernate: select fighterjet_.mission_id, fighterjet_.JET_ID, fighterjet_.name as name1_ from fighterjetmissions fighterjet_ where fighterjet_.mission_id=? and fighterjet_.JET_ID=?
Hibernate: select fighterjet_.mission_id, fighterjet_.JET_ID, fighterjet_.name as name1_ from fighterjetmissions fighterjet_ where fighterjet_.mission_id=? and fighterjet_.JET_ID=?
Hibernate: select fighterjet_.mission_id, fighterjet_.JET_ID, fighterjet_.name as name1_ from fighterjetmissions fighterjet_ where fighterjet_.mission_id=? and fighterjet_.JET_ID=?
Hibernate: select fighterjet_.mission_id, fighterjet_.JET_ID, fighterjet_.name as name1_ from fighterjetmissions fighterjet_ where fighterjet_.mission_id=? and fighterjet_.JET_ID=?
Hibernate: insert into fighterjet (name, max_speed, country, jet_id) values (?, ?, ?, ?)
Hibernate: insert into fighterjetmissions (name, mission_id, JET_ID) values (?, ?, ?)
Hibernate: insert into fighterjetmissions (name, mission_id, JET_ID) values (?, ?, ?)
Hibernate: insert into fighterjetmissions (name, mission_id, JET_ID) values (?, ?, ?)
Hibernate: insert into fighterjetmissions (name, mission_id, JET_ID) values (?, ?, ?)
Hibernate: insert into fighterjetmissions (name, mission_id, JET_ID) values (?, ?, ?)

以下是域对象及其hbms:

FighterjetDO:

public class FighterjetDO implements Serializable
{
    private static final long serialVersionUID = 1L;

    private Integer jetId;

    private String name;

    private Integer maxSpeed;

    private String country;

    private Set<FighterjetMissionsDO> fighterjetMissionsDOSet;

   // Setters and getters.


}

FighterjetDO HBM:

<hibernate-mapping>
    <class name="com.man.fighterjet.FighterjetDO" table="fighterjet">
        <id name="jetId" type="int" column="jet_id">
            <generator class="increment" />
        </id>
        <property name="name">
            <column name="name" />
        </property>
        <property name="maxSpeed">
            <column name="max_speed" />
        </property>
        <property name="country">
            <column name="country" />
        </property>

        <set name="fighterjetMissionsDOSet" lazy="true" table="fighterjetmissions" fetch="join" cascade="save-update" sort="unsorted" inverse="true">
            <key column="JET_ID" />
            <one-to-many class="com.man.fighterjet.FighterjetMissionsDO" />
        </set>
    </class>
</hibernate-mapping>

FighterjetMissionsDO:

public class FighterjetMissionsDO implements Serializable
{

    private static final long serialVersionUID = 1L;

    private Integer missionId;

    private String name;

    private FighterjetDO fighterjetDO;

    // Setters and getters.

}

FighterjetMissionsDO HBM:

<hibernate-mapping>
    <class name="com.man.fighterjet.FighterjetMissionsDO" table="fighterjetmissions">
        <composite-id>
            <key-property name="missionId" column="mission_id" type="integer" />

            <key-many-to-one name="fighterjetDO" class="com.man.fighterjet.FighterjetDO">
               <column name="JET_ID"/>
            </key-many-to-one>
       </composite-id>

        <property name="name">
            <column name="name"/>
        </property>
    </class>
</hibernate-mapping>

填写并保留测试代码:

        FighterjetDAO fighterjetDAO = new FighterjetDAO();


        Set<FighterjetMissionsDO> fighterjetMissionsDOSet = new HashSet<FighterjetMissionsDO>();

        FighterjetDO newFighterjetDO = new FighterjetDO();
        newFighterjetDO.setName("F22");
        newFighterjetDO.setMaxSpeed(1000);
        newFighterjetDO.setCountry("USA");

        FighterjetMissionsDO fighterjetMissionsDO1 = new FighterjetMissionsDO();
        fighterjetMissionsDO1.setMissionId(101);
        fighterjetMissionsDO1.setName("HIbernate");
        fighterjetMissionsDO1.setFighterjetDO(newFighterjetDO);
        fighterjetMissionsDOSet.add(fighterjetMissionsDO1);


        FighterjetMissionsDO fighterjetMissionsDO2 = new FighterjetMissionsDO();
        fighterjetMissionsDO2.setMissionId(102);
        fighterjetMissionsDO2.setName("HIbernate2");
        fighterjetMissionsDO2.setFighterjetDO(newFighterjetDO);
        fighterjetMissionsDOSet.add(fighterjetMissionsDO2);


        FighterjetMissionsDO fighterjetMissionsDO3 = new FighterjetMissionsDO();
        fighterjetMissionsDO3.setMissionId(103);
        fighterjetMissionsDO3.setName("HIbernate3");
        fighterjetMissionsDO3.setFighterjetDO(newFighterjetDO);
        fighterjetMissionsDOSet.add(fighterjetMissionsDO3);


        FighterjetMissionsDO fighterjetMissionsDO4 = new FighterjetMissionsDO();
        fighterjetMissionsDO4.setMissionId(104);
        fighterjetMissionsDO4.setName("HIbernate4");
        fighterjetMissionsDO4.setFighterjetDO(newFighterjetDO);
        fighterjetMissionsDOSet.add(fighterjetMissionsDO4);


        FighterjetMissionsDO fighterjetMissionsDO5 = new FighterjetMissionsDO();
        fighterjetMissionsDO5.setMissionId(105);
        fighterjetMissionsDO5.setName("HIbernate5");
        fighterjetMissionsDO5.setFighterjetDO(newFighterjetDO);
        fighterjetMissionsDOSet.add(fighterjetMissionsDO5);



        newFighterjetDO.setFighterjetMissionsDOSet(fighterjetMissionsDOSet);

        fighterjetDAO.createJet(newFighterjetDO);

FighterjetDAO:

 public void createJet(FighterjetDO fighterjetDO) {
        Transaction trns = null;
        Session session = HibernateUtil.getSessionFactory().openSession();
        try {
            trns = session.beginTransaction();
            session.save(fighterjetDO);
            session.getTransaction().commit();
        } catch (RuntimeException e) {
            if (trns != null) {
                trns.rollback();
            }
            e.printStackTrace();
        } finally {
            session.flush();
            session.close();
        }
    }

1 个答案:

答案 0 :(得分:1)

这是因为Hibernate正在尝试执行乐观锁定。

如果您添加version列,则可以执行更高效的UPDATE ... WHERE ...操作。