Spring & Hibernate

5 views
Skip to first unread message

Sascha Schäfer

unread,
Aug 11, 2009, 4:58:11 AM8/11/09
to Spring User Group Germany
Hallo,

ich bin dabei mich in Hibernate mit Spring (oder umgekehrt)
einzuarbeiten. Dazu habe ich mir eine kleine Applikation geschrieben,
um die Codebeispiele aus dem Buch "Spring in Action" nachzuvollziehen.
Hier mein kleines Codebeispiel, dass ich nach den Vorlagen von "Spring
in Action" erstellt habe. Bei Bedarf liefere ich auch gern die Spring-
Context.xml dazu.

@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public void runQuery()
{
final BuildingDAO buildingDAO = ( BuildingDAO )
applContext.getBean
( "buildingDAO" );
final Building building = buildingDAO.getBuildingById( "HQ" );
logger.debug( "Geladenes Gebäude: " + building.getId() );
logger.debug( "Geladenes Gebäude: " + building.getName() );

}

Das Laden des Objekts klappt wunderbar. Auch die Ausgabe des
Primarschlüssels funktioniert. Nur die Ausgabe des String-Attributes
schlägt fehl mit einer LazyInitializationException. Die Gründe dafür
sind mir vollkommen klar. Hibernate liefert mir ein Proxy-Objekt, in
denen die Attribute noch nicht geladen sind. Beim Aufruf des
Attributes wird versucht, den Wert zu laden, aber die Session wurde
bereits geschlossen. Prinzipiell ist das Lazy-Loading von Hibernate
eine tolle Sache und ich möchte nicht darauf verzichten.
Das Session-Handling übernimmt Spring für mich. Spring gibt vor, dass
die Session nur innerhalb der load-Methode des Hibernate-Templates
geöffnet ist.
Nun würde ich gern Spring mitteilen, dass die Session für die Dauer
meiner obigen Methode (runQuery()) offen bleiben soll, damit ich mir
die Attribute des Objekts ansehen kann. Ich dachte, dass geht über den
Transaction-Manager von Spring. Deshalb habe ich mich der
Transactional-Annotation bedient um zu sagen, dass hier eine read-
Only-
Transaction geöffnet werden soll. Aber falsch gedacht.
Hat jemand eine Idee, wie ich Spring mitteilen kann, dass die Session
solange geöffnet bleiben soll, bis das Ende der Methode erreicht ist.

Lg Sascha

Eberhard Wolff

unread,
Aug 11, 2009, 5:14:03 AM8/11/09
to sugg
Hallo,


On 11.08.09 10:58 "Sascha Schäfer" <ders...@t-online.de> wrote:

> Nun würde ich gern Spring mitteilen, dass die Session für die Dauer
> meiner obigen Methode (runQuery()) offen bleiben soll, damit ich mir
> die Attribute des Objekts ansehen kann. Ich dachte, dass geht über den
> Transaction-Manager von Spring. Deshalb habe ich mich der
> Transactional-Annotation bedient um zu sagen, dass hier eine read-
> Only-
> Transaction geöffnet werden soll. Aber falsch gedacht.

Na ja, die Methode ist mit Propagation.SUPPORTS markiert. Das heißt soviel
wie: Ich unterstütze eine Transaktion. Du darfst mich mit einer aufrufen
oder auch ohne. Meiner Ansicht nach übrigens eine ziemlich sinnlose
Einstellung. Anyway. REQUIRED sollte helfen.

Gruß,

Eberhard

--
Eberhard Wolff
Regional Director
SpringSource GmbH
Sitz der Gesellschaft: Uhlandstrasse 75 - D-10717 Berlin
Geschäftsführer: Steven Schuurman, Rod Johnson
Amtsgericht Charlottenburg - HRB 103773 B

http://www.springsource.com

Author, "Spring 2 - Framework für die Java Entwicklung"
http://www.spring-buch.de/

Founding Member Java Champions
https://java-champions.dev.java.net/

Mail: eberhar...@springsource.com
Skype: ebr.wolff
Blog: http://JandIandMe.blogspot.com/
Mailing List: http://www.springsource.com/newsletter


Sascha Schäfer

unread,
Aug 11, 2009, 5:31:23 AM8/11/09
to Spring User Group Germany


On 11 Aug., 11:14, Eberhard Wolff <Eberhard.Wo...@springsource.com>
wrote:
> Na ja, die Methode ist mit Propagation.SUPPORTS markiert. Das heißt soviel
> wie: Ich unterstütze eine Transaktion. Du darfst mich mit einer aufrufen
> oder auch ohne. Meiner Ansicht nach übrigens eine ziemlich sinnlose
> Einstellung. Anyway. REQUIRED sollte helfen.
>
> Gruß,
>
> Eberhard

Das hilft leider auch nicht. Es kommt immer noch zu einer
LazyInitializationException. Das Markieren mit Propagation.SUPPORTS
habe ich aus dem Buch "Spring in Action". Diese Propagation-
Einstellung ist meines Erachtens für lesende Methoden gedacht.
Aber villeicht habe ich einen Fehler in meinen Spring-Kontext. Deshalb
hier meine context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"
value="com.sybase.jdbc3.jdbc.SybDataSource" />
<property name="url" value="jdbc:sybase:Tds:afmsrv1:2638?
ServiceName=C173SYBASEHQ" />
<property name="username" value="afm" />
<property name="password" value="afm" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mappingResources">
<list>
<value>mapping/Building.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop
key="hibernate.dialect">org.hibernate.dialect.SybaseAnywhereDialect
</prop>
</props>
</property>
</bean>
<bean id="buildingDAO"

class="de.ebcsoft.afm.persistence.dataaccess.common.building.BuildingDAOImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:annotation-driven />
</beans>

Lg Sascha

Sascha Schäfer

unread,
Aug 11, 2009, 5:45:10 AM8/11/09
to Spring User Group Germany
Ich denke, ich habe meinen Fehler gefunden. Die Klasse, welche die
meine gezeigte Methode runQuery() beinhaltet, wird nicht von Spring
erzeugt. Jetzt ist mir klar, dass es voher nicht funktionieren konnte.
Ich bin eben doch noch ein Anfänger. Danke trotzdem für eure Mühen.

Lg Sascha

Eberhard Wolff

unread,
Aug 11, 2009, 7:09:44 AM8/11/09
to sugg
Hi,


On 11.08.09 11:31 "Sascha Schäfer" <ders...@t-online.de> wrote:

> Das hilft leider auch nicht. Es kommt immer noch zu einer
> LazyInitializationException. Das Markieren mit Propagation.SUPPORTS
> habe ich aus dem Buch "Spring in Action". Diese Propagation-
> Einstellung ist meines Erachtens für lesende Methoden gedacht.

Propagation.SUPPORTS sagt einfach, ich kann mit einer Transaktion umgehen,
aber ich muss nicht unbedingt eine haben. Das ist kein Unterschied zu gar
keiner Annotation. Ich würde REQUIRED nehmen, dann läuft es auf jeden Fall
in einer Transaktion. Das "Nur-Lesen" ist ja durch das read-only-Attribut
definiert.

Ich kenne allerdings Spring in Action nicht. Wäre interessant, was die als
Begründung geben.

Ansonsten: Schön, dass es mittlerweile geht!

Sascha Schäfer

unread,
Aug 11, 2009, 7:20:32 AM8/11/09
to Spring User Group Germany
On 11 Aug., 13:09, Eberhard Wolff <Eberhard.Wo...@springsource.com>
wrote:

> Ich kenne allerdings Spring in Action nicht. Wäre interessant, was die als
> Begründung geben.
>
> Ansonsten: Schön, dass es mittlerweile geht!
>
> Gruß,
>
> Eberhard

Also eine konkrete Begründung gibt Spring in Action nicht für die die
Verwendung von Propagation.SUPPORTS. Es wird so erklärt, dass lesende
Methoden nicht zwingend eine Transaktion brauchen für den lesenden
Zugriff. Stimmt ja auch, die Session reicht aus.

Nochmal danke für deine Mühe und die sehr schnelle Antwort. Echt super
diese Spring User Group!

Lg Sascha

Eberhard Wolff

unread,
Aug 11, 2009, 9:33:48 AM8/11/09
to sugg
Hallo,


On 11.08.09 13:20 "Sascha Schäfer" <ders...@t-online.de> wrote:

>
> Also eine konkrete Begründung gibt Spring in Action nicht für die die
> Verwendung von Propagation.SUPPORTS. Es wird so erklärt, dass lesende
> Methoden nicht zwingend eine Transaktion brauchen für den lesenden
> Zugriff. Stimmt ja auch, die Session reicht aus.

Die Hibernate Session ist aber bei Spring überlicherweise an die Transaktion
gebunden, d.h. die haben dieselbe Lebensdauer. Außerdem sind Transaktionen
beim Lesen sinnvoll, da es auch Isolation von anderen Transaktionen bietet,
d.h. man bekommt für die Dauer einer Transaktion eine konsistente Sicht auf
die Daten.

Aber Hauptsache das Problem ist erstmal gelöst...

Sascha Schäfer

unread,
Aug 11, 2009, 9:58:23 AM8/11/09
to Spring User Group Germany
On 11 Aug., 15:33, Eberhard Wolff <Eberhard.Wo...@springsource.com>
wrote:
> Die Hibernate Session ist aber bei Spring überlicherweise an die Transaktion
> gebunden, d.h. die haben dieselbe Lebensdauer. Außerdem sind Transaktionen
> beim Lesen sinnvoll, da es auch Isolation von anderen Transaktionen bietet,
> d.h. man bekommt für die Dauer einer Transaktion eine konsistente Sicht auf
> die Daten.
>
> Aber Hauptsache das Problem ist erstmal gelöst...
>
> Gruß,
>
> Eberhard

Das stimmt. Von der Seite hab ich das Problem noch gar nicht
betrachtet. Dann gibt es eigentlich für Propagation.SUPPORTS keine
sinnvolle Verwendung ... wie du schon sagtest.

Lg Sascha
Reply all
Reply to author
Forward
0 new messages