我有一个使用Hibernate的应用程序。表现非常糟糕。如果我只更改一个简单的字段,则会在session.flush()被调用后更新许多许多对象。Hibernate session.flush() - >如何只更新脏对象而不是一切?
我会告诉你一些代码片段和日志文件,也许你可以发现问题。我不是Hibernate专家。我希望这是足够的信息给我一些提示?也许,我已经学习了一本书来解决它自己...
我认为问题是,没有延迟加载或有一些错误的CASCADING?大多数hbm.xml文件具有“lazy = false”。在清除后不会调用session.clear()。但是:如果我也使用session.clear(),那么第一个更改将工作并将被保留,但以下所有更改都不会被保留。
这里有一些片段。我认为这应该是所有重要的片段?如果您需要更多信息,请告诉我。谢谢。最好的问候,启的Wahner
一映射文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="de.bea.plato.domain.Auftrag" table="AUFTRAG" lazy="false">
<id column="OID" name="oid" length="25" type="java.lang.String" unsaved-value="null">
<generator class="de.bea.plato.datastore.PlatoIdGenerator"/>
</id>
<many-to-one name="projekt" column="ProjektOID"/>
<many-to-one name="mitarbeiterLetzteAenderung" column="MitarbeiterOID"/>
<property name="day" type="de.bea.plato.hibernate.TypeDay"/>
<property name="dayLetzteAenderung" type="de.bea.plato.hibernate.TypeDay"/>
<!-- fields of type String must not be set to "" -->
<property name="bezeichnung" length="80" access="field"/>
<property name="auftragsNummer" length="40" access="field"/>
<property name="bestellNummer" length="40" access="field"/>
<!-- fields of type String must not be set to "" -->
<property name="bemerkung" length="1024" access="field"/>
<property name="abrechenbarVon" type="de.bea.plato.hibernate.TypeDay"/>
<property name="abrechenbarBis" type="de.bea.plato.hibernate.TypeDay"/>
<property name="status" not-null="true"/>
<many-to-one name="budget" column="BudgetOID"/>
<property name="rechnungsempfaenger" length="255" access="field"/>
<property name="zahlungsziel" length="1024" access="field"/>
<many-to-one name="anschrift" column="AnschriftOID"/>
<property name="projektFestPreis" not-null="true"/>
</class>
</hibernate-mapping>
配置:
configuration = new Configuration();
try {
configuration.addClass(Waehrung.class);
configuration.addClass(BK.class);
configuration.addClass(BetriebskalenderAusnahme.class);
configuration.addClass(Mitarbeiter.class);
configuration.addClass(TeilProjekt.class);
configuration.addClass(Projekt.class);
configuration.addClass(ProjektGruppe.class);
configuration.addClass(StundenEntry.class);
Properties properties = databaseInit.getHibernateProperties();
configuration.setProperties(properties);
其由摇摆GUI一个字段被改变之后被调用的方法:
public void flush() throws PlatoDatastoreException {
synchronized (syncObject) {
if (session != null) {
try {
session.flush();
session.connection().commit();
// session.clear();
updateLastUse();
log.info("Session flushed and connection committed.");
}
catch (Exception e) {
log.error("Error while flushing session", e);
throw new PlatoDatastoreException(e);
}
}
else {
log.info("Flush without an active session");
}
}
}
休眠属性:
name = companies/XYZ/hibernate_releaseTest2
hibernate.connection.driver_class=oracle.jdbc.driver.OracleDriver
hibernate.connection.pool_size= 10
# test system ----------------------------
hibernate.connection.url=jdbc:oracle:thin:@xyz:1521:abc
hibernate.connection.username=x
hibernate.connection.password=y
hibernate.dialect=org.hibernate.dialect.OracleDialect
hibernate.query.substitutions= true 1, false 0, yes 'Y', no 'N'
hibernate.statement_cache.size= 100
hibernate.jdbc.fetch_size=1000
hibernate.c3p0.max_size=10
hibernate.c3p0.min_size=0
hibernate.c3p0.max_statements=0
hibernate.c3p0.timeout=60
hibernate.c3p0.valdiate=false
一个变化的领域(如你看到很多很多很多的事情发生,但只是一个字段更新,并应坚持)后的日志文件:
31197 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.AbstractFlushingEventListener - flushing session
31198 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.AbstractFlushingEventListener - processing flush-time cascades
31198 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - processing cascade ACTION_SAVE_UPDATE for: de.bea.plato.domain.Mitarbeiter
31198 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - cascade ACTION_SAVE_UPDATE for collection: de.bea.plato.domain.Mitarbeiter.mitarbeiterZeit
31198 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - done cascade ACTION_SAVE_UPDATE for collection: de.bea.plato.domain.Mitarbeiter.mitarbeiterZeit
31198 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - cascade ACTION_SAVE_UPDATE for collection: de.bea.plato.domain.Mitarbeiter.workingList
31198 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - cascading to saveOrUpdate: de.bea.plato.domain.TeilProjekt
31198 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.AbstractSaveEventListener - persistent instance of: de.bea.plato.domain.TeilProjekt
31198 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - ignoring persistent instance
31198 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - object already associated with session: [de.bea.plato.domain.TeilProjekt#ericjxxxxxxxtw8468gf00000]
31198 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - cascading to saveOrUpdate: de.bea.plato.domain.TeilProjekt
31198 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.AbstractSaveEventListener - persistent instance of: de.bea.plato.domain.TeilProjekt
31198 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - ignoring persistent instance
31198 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - object already associated with session: [de.bea.plato.domain.TeilProjekt#normanzxxxxxfveje5pd00000]
31198 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - cascading to saveOrUpdate: de.bea.plato.domain.TeilProjekt
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.AbstractSaveEventListener - persistent instance of: de.bea.plato.domain.TeilProjekt
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - ignoring persistent instance
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - object already associated with session: [de.bea.plato.domain.TeilProjekt#normanzxxxxxysjbzgpe00000]
31199 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - cascading to saveOrUpdate: de.bea.plato.domain.TeilProjekt
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.AbstractSaveEventListener - persistent instance of: de.bea.plato.domain.TeilProjekt
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - ignoring persistent instance
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - object already associated with session: [de.bea.plato.domain.TeilProjekt#ericjxxxxxxx7ch468gf00000]
31199 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - cascading to saveOrUpdate: de.bea.plato.domain.TeilProjekt
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.AbstractSaveEventListener - persistent instance of: de.bea.plato.domain.TeilProjekt
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - ignoring persistent instance
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - object already associated with session: [de.bea.plato.domain.TeilProjekt#normanzxxxxx4mpke5pd00000]
31199 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - cascading to saveOrUpdate: de.bea.plato.domain.TeilProjekt
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.AbstractSaveEventListener - persistent instance of: de.bea.plato.domain.TeilProjekt
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - ignoring persistent instance
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - object already associated with session: [de.bea.plato.domain.TeilProjekt#normanzxxxxxhv7me5pd00000]
31199 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - cascading to saveOrUpdate: de.bea.plato.domain.TeilProjekt
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.AbstractSaveEventListener - persistent instance of: de.bea.plato.domain.TeilProjekt
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - ignoring persistent instance
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - object already associated with session: [de.bea.plato.domain.TeilProjekt#dominiknxxxxdyi3mkmf00000]
31199 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - cascading to saveOrUpdate: de.bea.plato.domain.TeilProjekt
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.AbstractSaveEventListener - persistent instance of: de.bea.plato.domain.TeilProjekt
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - ignoring persistent instance
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - object already associated with session: [de.bea.plato.domain.TeilProjekt#ericjxxxxxxxtnzjf5ff00000]
31199 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - cascading to saveOrUpdate: de.bea.plato.domain.TeilProjekt
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.AbstractSaveEventListener - persistent instance of: de.bea.plato.domain.TeilProjekt
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - ignoring persistent instance
31199 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - object already associated with session: [de.bea.plato.domain.TeilProjekt#normanzxxxxxu40pe5pd00000]
31199 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - done cascade ACTION_SAVE_UPDATE for collection: de.bea.plato.domain.Mitarbeiter.workingList
31199 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - done processing cascade ACTION_SAVE_UPDATE for: de.bea.plato.domain.Mitarbeiter
31199 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - processing cascade ACTION_SAVE_UPDATE for: de.bea.plato.domain.Mitarbeiter
31199 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - cascade ACTION_SAVE_UPDATE for collection: de.bea.plato.domain.Mitarbeiter.mitarbeiterZeit
31199 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - done cascade ACTION_SAVE_UPDATE for collection: de.bea.plato.domain.Mitarbeiter.mitarbeiterZeit
31199 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - cascade ACTION_SAVE_UPDATE for collection: de.bea.plato.domain.Mitarbeiter.workingList
31199 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - done cascade ACTION_SAVE_UPDATE for collection: de.bea.plato.domain.Mitarbeiter.workingList
31200 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - done processing cascade ACTION_SAVE_UPDATE for: de.bea.plato.domain.Mitarbeiter
31200 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - processing cascade ACTION_SAVE_UPDATE for: de.bea.plato.domain.Mitarbeiter
31200 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - cascade ACTION_SAVE_UPDATE for collection: de.bea.plato.domain.Mitarbeiter.mitarbeiterZeit
31200 [Gui4j-Worker 0] DEBUG org.hibernate.engine.Cascades - done cascade ACTION_SAVE_UPDATE for collection: de.bea.plato.domain.Mitarbeiter.mitarbeiterZeit
... a lot more of this ...
31467 [Gui4j-Worker 0] DEBUG org.hibernate.type.StringType - binding null to parameter: 5
31467 [Gui4j-Worker 0] DEBUG org.hibernate.type.BooleanType - binding 'false' to parameter: 6
31467 [Gui4j-Worker 0] DEBUG org.hibernate.type.DoubleType - binding '5.0' to parameter: 7
31468 [Gui4j-Worker 0] DEBUG org.hibernate.type.DateType - binding '22 Dezember 2010' to parameter: 8
31468 [Gui4j-Worker 0] DEBUG org.hibernate.type.CharacterType - binding null to parameter: 9
31468 [Gui4j-Worker 0] DEBUG org.hibernate.type.StringType - binding null to parameter: 10
31468 [Gui4j-Worker 0] DEBUG org.hibernate.type.DoubleType - binding '0.0' to parameter: 11
31468 [Gui4j-Worker 0] DEBUG org.hibernate.type.DoubleType - binding '0.0' to parameter: 12
31468 [Gui4j-Worker 0] DEBUG org.hibernate.type.DoubleType - binding '0.0' to parameter: 13
31468 [Gui4j-Worker 0] DEBUG org.hibernate.type.StringType - binding 'userxxxxxxxxewshlhnd00300' to parameter: 14
31468 [Gui4j-Worker 0] DEBUG org.hibernate.type.StringType - binding 'userxxxxxxxxixshlhnd00500' to parameter: 15
31468 [Gui4j-Worker 0] DEBUG org.hibernate.type.StringType - binding 'eur' to parameter: 16
31468 [Gui4j-Worker 0] DEBUG org.hibernate.type.StringType - binding 'userxxxxxxxx49zr90ig00000' to parameter: 17
31468 [Gui4j-Worker 0] DEBUG org.hibernate.jdbc.AbstractBatcher - Adding to batch
31469 [Gui4j-Worker 0] DEBUG org.hibernate.jdbc.AbstractBatcher - Executing batch size: 1
31521 [Gui4j-Worker 0] DEBUG org.hibernate.jdbc.AbstractBatcher - success of batch update unknown: 0
31521 [Gui4j-Worker 0] DEBUG org.hibernate.jdbc.AbstractBatcher - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
31521 [Gui4j-Worker 0] DEBUG org.hibernate.jdbc.AbstractBatcher - closing statement
31522 [Gui4j-Worker 0] DEBUG org.hibernate.event.def.AbstractFlushingEventListener - post flush
31532 [Gui4j-Worker 0] INFO de.bea.plato.datastore.PlatoDatastore - Session flushed and connection committed.
谢谢我当然有我自己来分析整个代码很多再多一次思想的每次更改后更新。:我认为我应该使用更多会话?在“Hibernate in Action”中,我读到SessionFactory很昂贵,但是可以使用很多会话。在这个应用程序中,持久化上下文非常庞大,我认为......我是对的:在第一个之后的进一步修改不会被保留(如果我使用session.clear),因为可能所有的对象都处于分离状态 - 可能代码中没有任何地方再次重新连接/合并对象,因此,在第二次修改之后持续? – 2010-12-22 19:16:31
@Kai:其实我不确定使用Hibernate的Swing应用程序的正确设计。可能你需要在加载后分离对象,并且当你要保存它们时合并已改变的对象。是的,在`session.clear()`之后,对象处于分离状态。 – axtavt 2010-12-23 10:56:11