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();
}
}
答案 0 :(得分:1)
这是因为Hibernate正在尝试执行乐观锁定。
如果您添加version
列,则可以执行更高效的UPDATE ... WHERE ...
操作。