Hibernate - Performance

Guten Morgen :) !

Ich bin leider betreffend Hibernate noch nicht ganz fit, und mir wurde halt einmal so gezeigt zu arbeiten und nun mach ich das immer so. Brauche ich denn keine Transaktionen? Auch nicht wenn ich auf die Db schreibe? Wie soll ich denn ohne Transaktionen arbeiten?

mfg

**EDIT**
Code:
session.setFlushMode(FlushMode.NEVER);
Ist ebenfalls deprecated..

**EDIT**
Ok bin nun ein wenig weiter. Bisher habe ich wohl den Fehler gemacht dass ich in der DAO meine Transaction beginne und nicht in der Businesslogik. Jedoch wenn ich es nun so mache dann klappt zwar das 1. Stmt aber beim 2. Stmt bekomme ich dann eine Exception da meine Transaction geschlossen ist (obwohl ich jene nicht geschlossen habe nach dem 1. Stmt).

Und wenn ich keine Transaktion benutze, bekomme ich folgende Exception:
Code:
org.hibernate.HibernateException: createSQLQuery is not valid without active transaction
 
Zuletzt bearbeitet:
Wenn du in die DB schreibst brauchst du natürlich eine Transaktion. Allerdings ist von SChreiben in deinem Code nichts zu sehen.

Code:
FlushMode.NEVER
ist tatsächlich deprecated. Nun gut, ich hab die API auch nicht 100%ig im Kopf. Gut das im JavaDoc aber steht, man soll einfach
Code:
FlushMode.MANUAL
benutzen. Darfst dann halt einfach kein flush() rufen.

Weiß allerdings nicht, ob der Effekt dann noch der gleiche ist, da die Connection dann eigentlich nicht mehr readOnly werden kann, weil potentiell ja Schreibzugriffe stattfinden könnten.

Wegen der Exception. Die macht natürlich Sinn, auch wenn das meiner Meinung nach ganz klar ne Schwäche der Session API ist. Wenn die Methode beliebige SQL Statements bekommen kann, können das natürlich potentiell Schreibende SQL Statments sein und dann ist eine Transaktion von nöten. Ein Grund mehr für richtige SQL Querys an Hibernate vorbeizuarbeiten.

Dann schau mal, wie weit du damit kommst, alles in eine Transaktion zu fassen.

Gruß
Ollie
 
Wenn du in die DB schreibst brauchst du natürlich eine Transaktion. Allerdings ist von SChreiben in deinem Code nichts zu sehen.

Code:
FlushMode.NEVER
ist tatsächlich deprecated. Nun gut, ich hab die API auch nicht 100%ig im Kopf. Gut das im JavaDoc aber steht, man soll einfach
Code:
FlushMode.MANUAL
benutzen. Darfst dann halt einfach kein flush() rufen.

Weiß allerdings nicht, ob der Effekt dann noch der gleiche ist, da die Connection dann eigentlich nicht mehr readOnly werden kann, weil potentiell ja Schreibzugriffe stattfinden könnten.

Wegen der Exception. Die macht natürlich Sinn, auch wenn das meiner Meinung nach ganz klar ne Schwäche der Session API ist. Wenn die Methode beliebige SQL Statements bekommen kann, können das natürlich potentiell Schreibende SQL Statments sein und dann ist eine Transaktion von nöten. Ein Grund mehr für richtige SQL Querys an Hibernate vorbeizuarbeiten.

Dann schau mal, wie weit du damit kommst, alles in eine Transaktion zu fassen.

Gruß
Ollie

Wenn ich alles in eine Transaktion packe, dann bekomme ich ebenfalls oben genannte Exception (beim 2. Stmt):
Code:
rg.hibernate.HibernateException: createSQLQuery is not valid without active transaction

D.h. bei mir wird die Transaktion geschlossen nachdem ersten Stmt - warum auch immer (ich schließe sie nicht von selbst!). Gibt es hier vllt dem Session Objekt irgendwas mitzuteilen? Kann sowas wie ein AutoClose gesetzt sein?
 
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
	<property name="hibernate.connection.driver_class">
		oracle.jdbc.driver.OracleDriver
	</property>
	<property name="hibernate.connection.password">navteq</property>
	<property name="hibernate.connection.url">
		jdbc:oracle:thin:@192.11.100.207:1521:XE
	</property>
	<property name="hibernate.connection.username">navteq</property>
	<property name="hibernate.dialect">
		org.hibernate.dialect.OracleDialect
	</property>
	<property name="myeclipse.connection.profile">
		ORACLE_SPATIAL_VM
	</property>
	<property name="connection.url">
		jdbc:oracle:thin:@192.11.100.207:1521:XE
	</property>
	<property name="connection.username">navteq</property>
	<property name="connection.password">navteq</property>
	<property name="connection.driver_class">
		oracle.jdbc.driver.OracleDriver
	</property>
	<property name="dialect">
		at.pcd.wam.technologie.persistence.custom.type.OracleSpatialDialect
	</property>

	<!-- Enable Hibernate's automatic session context management -->
	<property name="current_session_context_class">thread</property>

	<!--  -->
	<property name="hibernate.show.sql">true</property>
	<!--<property name="hibernate.hbm2ddl.auto">create</property>-->
	<!-- <property name="hibernate.hbm2dll.auto">update</property>  -->
	<mapping
		resource="at/pcd/wam/technologie/persistence/hbm/GPSToursModel.hbm.xml" />
	<mapping
		resource="at/pcd/wam/technologie/persistence/hbm/FeatureModel.hbm.xml" />

</session-factory>
</hibernate-configuration>

wohl nicht, d.h. durch das autocommit wird sowieso nach jedem stmt ein commit abgesetzt?
 
Ich hoffe ich strapaziere deine/eure Geduld nicht, aber folgendes würde mir noch sehr helfen:

Wenn ich nur lesend auf die DB gehe kann ich Transaktionen komplett weglassen (auch wenn ich nicht mit HQL sondern mit SQL arbeite - oder benötigt SQL Transaktionen?

Wie handhabt ihr das mit der Hibernate Session und der Transaktion? Sprich setzt ihr beides schon in der Businesslogik oder erst in der DAO (wenn vorhanden)?
 
Ich hoffe ich strapaziere deine/eure Geduld nicht, aber folgendes würde mir noch sehr helfen:
Nur kein Stress, wenn ich arg viel zu tun hab, antworte ich einfach nicht so schnell ;)
Wenn ich nur lesend auf die DB gehe kann ich Transaktionen komplett weglassen (auch wenn ich nicht mit HQL sondern mit SQL arbeite - oder benötigt SQL Transaktionen?
SQL bzw. JDBC benötigen erstmal gar keine Transaktionen, da auch nicht jede DB Transaktionen anbietet. Für rein lesende Operation kann man die also eigentlich weglassen. Wo das Problem mit Hibernates createSqlQuery() liegt, hab ich ja oben schon beschrieben. Scheint so, als "erzwingt" hibernate damit Transaktionen.

Wie handhabt ihr das mit der Hibernate Session und der Transaktion? Sprich setzt ihr beides schon in der Businesslogik oder erst in der DAO (wenn vorhanden)?
Ich bevorzuge den Weg über Spring. Das bietet ein HibernateTemplate, was das ganze Sessionhandling kapselt und man Transaktionen deklarativ konfigurieren kann. Zum anderen sorgt das Ding dafür, dass man datenbankunabhängige Exceptions bekommt und diese somit besser verarbeiten kann. (Das macht es unter anderem auch sehr leicht möglich für 90% der DB Anfragen Hibernate zu benutzen, StoredProcedures oder ähnliches allerdings mit JDBC zu triggern). Arbeit mit der Session gehört meiner meinung nach wenn dann ins DAO. Allerdings sind die DAOs meist nicht der richtige Platz für die Demarkation von Transaktionen (Methodenschnittstellen zu feingranular, nicht clientorientiert). Daher ist IMHO das Arbeiten mit plain Hibernate nichts, was wirklich Spass macht bzw. elegant wird. Desweiteren würde ich deklarative Transaktionen programmatischen immer vorziehen. Man schreibt einfach zuviel Boilerplatecode sonst.

Gruß
Ollie
 
Zurück