Hibernate/iBatis gleichzeitig auf 2 Datenbanken

Status
Nicht offen für weitere Antworten.

MQue

Top Contributor
Hallo,

ist es mit iBatis oder/und Hibernate möglich, auf 2 Datenbanken gleichzeitig zuschreiben, ohne zuviel Aufwand zu treiben, z.B.: nur in einer XML- Datei konfigurieren o.ä.

lg
 
Was meinst du mit "viel Aufwand"? Mehr als eine XML konfig? 😉

Hab das mit iBatis schon gemacht, sollte auch mit Hibernate funktionieren.
Brauchst pro DB eine Datasource und zu jeder Datasource einen eigenen Transactionmanager, ausser du willst globale Transaktionen die für beide DBs gleichzeitig gelten, aber das musst du uns schon verraten.
Würde dir aber auf jedenfall mehr als eine Konfig Datei empfehlen, selbst mit nur einer DB und Spring.
 
ausser du willst globale Transaktionen die für beide DBs gleichzeitig gelten

Das wäre natürlich der Hammer, am Besten wärs für mich, wenn ich in einer XML die Datenbanken angebe und ein Transaktionenmanager kümmert sich um alles 🙂

Da ich jetzt weiß, das es funkt. werd ichs gleich mal in diese Richtung probieren,
lg
 
Wie byto bereits sagte sind globale Transaktionen nicht ganz so einfach, deswegen hatte ich ja nachgefragt 😉
 
Was meinst du mit "viel Aufwand"? Mehr als eine XML konfig? 😉

Hab das mit iBatis schon gemacht

wie geht das eigentlich mit iBatis, braucht man da 2 *.properties - Dateien oder schreibt man die 2 Verbindungen in eine Properties- Datei und was passiert dann mit der SqlMapConfig.xml? Brauche ich da 2 Dateinen von SqlMapConfig.xml oder 2 <transactionManager type="JDBC" > Einträge in dieser Datei?

lg

Java:
<property name="JDBC.Driver" 					value="${driver}"	/>
			<property name="JDBC.ConnectionURL" 			value="${url}"		/>
			<property name="JDBC.Username" 					value="${username}"	/>
			<property name="JDBC.Password" 					value="${password}"	/>
 
wie geht das eigentlich mit iBatis, braucht man da 2 *.properties - Dateien
Habe dafür gar keine Properties Datei genutzt, sondern den ressourcenfilter von Maven 2, geht aber beides.
Die Proprties sollten halt eindeutig benannt sein, so wie die beans dann auch 😉

was passiert dann mit der SqlMapConfig.xml?
Was soll denn mit der passieren? MIt iBatis habe oich pro DB immer eine sql-map-config gehabt.

Brauche ich da 2 Dateinen von SqlMapConfig.xml oder 2 <transactionManager type="JDBC" > Einträge in dieser Datei?
<transactionManager type="JDBC" > solltest du gar nicht haben wenn du Spring einsetzt, denn Spring kümmert sich um die Transaktionen.
 
Also mit iBatis habe ich jetzt probiert (vorher recherchiert) eine Tabelle zu erzeugen, das hat nicht geklappt, ich benötige unbedingt, dass beim Prgrammstart nachgesehen wird, ob es die Tabelle X schon gibt, wenn nein, dann soll die Tabelle erzeugt werden.
Das geht meines wissens nach nicht, ich hätte es vor ein paar Monaten auch schon benötigt aber da bin ich auch auf keinen grünen Zweig gekommen,
Nur für das Erzeugen der Tabelle bin ich neben iBatis "vorbeigefahren", was auch nicht so sauber war.

deshalb bin ich jetzt gerade am Recherchieren, ob ich das vielleicht mit Hibernate realisieren könnte,

Wisst Ihr ob es mit Hibernate geht, eine Tabelle zu erzeugen, wenn diese nicht existiert?
lg
 
iBatis bietet dir doch einen SQL Script Runner, denn iBatis erstellt dir kein Schema vollautomatisch auf Wunsch.
Hibernate kann dir ganze DB Schema aus den Metainformationen erzeugen.

Hibaernate und iBatis sind sich nicht ähnlich, denn Hibernate ist ein ORM, iBatis nur ein SQL Mapper (und ein DAO Framework, wenn man es braucht).
 
Ich hab mich eh schon entschieden, das mit Hibernate zu realisieren, habe auch das Hibernate- Buch von Sebastian Hennebrüder in der Hand, bin mir auch bewußt, dass es einige Zeit in Anspruch nehmen wird, scheitere momentan aber schon am downloaden,
da gibt es ja zig Versionen -> https://www.hibernate.org/6.html
Was brauch ich da für eine Version, ich hab mir jetzt diese mal Heruntergeladen:

hibernate-distribution-3.3.2.GA-dist.zip

die hat 42,8MB, das kanns ja auch nicht sein oder???

[EDIT] Versteh, die Doku hat schon 30MB
 
Zuletzt bearbeitet:
Das sind keine Versionen, sondern die verschiedenen Packages, je nachdem was man braucht.

die hat 42,8MB, das kanns ja auch nicht sein oder???
Ach, warte nur bis du alle 1-2 dutzend Abhängigkeiten (jars) runtergeladen hast *g*
Für so etwas ist Maven2 wirklich genial...
 
Das sind keine Versionen, sondern die verschiedenen Packages, je nachdem was man braucht.


Ach, warte nur bis du alle 1-2 dutzend Abhängigkeiten (jars) runtergeladen hast *g*
Für so etwas ist Maven2 wirklich genial...

ich arbeite mit Netbeans und weiß, das NEtBeans Maven unterstützt, hab aber noch nie damit gearbeitet, keine Ahnug ob das nicht ein bisschen viel ist, wenn ich mich in Maven und Hibernate gleichzeitig einarbeite,

Wisst ihr vielleicht ein gutes Tutorial über Hibernate mit Netbeans (standalone, ohne EJB oder sonst was), hab bis jetzt noch nichts gefunden.
Vielen Dank für die Hilfe,
lg
 
Die Hibernate Doku enthält eine Art "Hello World" Tutorial. Da steht ganz genau beschrieben, was man machen muss, um ne einfache Klasse zu mappen.
Wenn man das Schritt für Schritt macht, kann man eigentlich nichts falsch machen (vorausgesetzt man ist der englischen Sprache mächtig).
 
Super, hab das Teil mal fürs erste gepändigt, ist wirklich ideal für meinen Einsatz, da ich FireBird benutze und Firebird eben einen ziemlichen Dialekt hat, was ich vorher immer im Code ausgleichen musste und jetzt einfach eine Zeile ist.🙂
lg
 
Hallo,

ich habe die Datei hibernate.cfg.xml momentan in meiner IDE (Netbean) in einem <default package> (also in der Verzeichnisstruktur im scr- Ordner),

jetzt wollte ich hergehen und diese Datei hibernate.cfg.xml in ein jar geben und dann dem Projekt hinzufügen, was ich auch gemacht habe, das mag hibernate aber gar nicht, ich bekomme dann die Fehlermeldung:

Java:
Initial SessionFactory creation failed.org.hibernate.HibernateException: /hibernate.cfg.xml not found
Exception in thread "main" java.lang.ExceptionInInitializerError

Meine Frage wäre jetzt, wo sucht hibernate nach dieser Datei bzw. wo kann ich diese Datei noch hingeben?

Vielen Dank,
lg
 
gesucht wird im ClassPath,
du könntest die Datei z.B. in dein src-Verzeichnis legen, von wo aus sie wahrscheinlich ins bin-Verzeichnis kopiert wird,
bei einer Entwicklungsumgebung wie Eclipse,

oder in ein lib/ conf-Verzeichnis, und dieses in den ClassPath hinzufügen


edit:
> ich habe die Datei hibernate.cfg.xml momentan in meiner IDE (Netbean) in einem <default package> (also in der Verzeichnisstruktur im scr- Ordner)

erst zu spät gelesen 😉
dann weiß ich auch nicht, wo liegen die .class-Dateien? ist die xml-Datei auch dort?
 
gesucht wird im ClassPath,
du könntest die Datei z.B. in dein src-Verzeichnis legen, von wo aus sie wahrscheinlich ins bin-Verzeichnis kopiert wird,
bei einer Entwicklungsumgebung wie Eclipse,

oder in ein lib/ conf-Verzeichnis, und dieses in den ClassPath hinzufügen


edit:
> ich habe die Datei hibernate.cfg.xml momentan in meiner IDE (Netbean) in einem <default package> (also in der Verzeichnisstruktur im scr- Ordner)

erst zu spät gelesen 😉
dann weiß ich auch nicht, wo liegen die .class-Dateien? ist die xml-Datei auch dort?

ich hab die Datei in der *.jar noch in einen Ordner config gehabt, da findet er sie nicht, habs rausgetan, funkt jetzt super,
danke!
 
Das kommt auf die eingesetze IDE an.

Unter Eclipse: Project Properties -> Java Build Path -> Source -> Add folder...
 
Das kommt auf die eingesetze IDE an.

Unter Eclipse: Project Properties -> Java Build Path -> Source -> Add folder...

ah, verstehe, das meinst du, das hab ich gemacht und funktioniert super.

eine andere Frage hätte ich noch zum Einfügen von TUPLES, ich hab jetzt 2 Tabellen mit einer n:m- Verbindung (also in der Datenbank sinds dann 3 Tabellen):

Java:
     MAPPINGPOOL  ------ MAPPINGPOOL_CONNECTION ------ CONNECTION

aus der Einführung vom Link oben (1.2.Part 1 - The first Hibernate Application) hab ich mal diesen Code zum Einfügen eines Tupels in die eine Tabelle CONNECTION (andere Namen als im Tutorial, funktion ist aber die Gleiche):

Java:
private void createAndStoreEvent(final String connectionName) {
        final Session session = HibernateUtil.getSessionFactory().getCurrentSession();  
        session.beginTransaction();
        final Connection theEvent = new Connection();
        theEvent.setConnectionName(connectionName);       
        session.save(theEvent);
        session.getTransaction().commit();
        }

Meine Frage wäre jetzt, wie kann ich es machen, dass ich in allen 3 Tabellen das richtige für ein Tupel einfüge. Muss ich den obigen Code für alle 3 Tabellen je nach Tabelle ausführen, oder kann ich das mit Hibernate auf einen Schlag alles machen, sodass in allen 3 Tabellen gleich das Richtige für den Tupel drinnensteht?

lg
 
Zuletzt bearbeitet:
Ist es eine bidirektionale Verbindung? Dann musst Du in beiden Hibernate Objekten die Referenzen richtig setzen vor dem Speichern. Ausserdem hängts von der Kaskadierung ab, ob die referenzierten Objekte mit gespeichert werden.
 
Meine Frage wäre jetzt, wie kann ich es machen, dass ich in allen 3 Tabellen das richtige für ein Tupel einfüge. Muss ich den obigen Code für alle 3 Tabellen je nach Tabelle ausführen, oder kann ich das mit Hibernate auf einen Schlag alles machen, sodass in allen 3 Tabellen gleich das Richtige für den Tupel drinnensteht?
Hiberrnate kann "alles" 😉
 
Ist es eine bidirektionale Verbindung? Dann musst Du in beiden Hibernate Objekten die Referenzen richtig setzen vor dem Speichern. Ausserdem hängts von der Kaskadierung ab, ob die referenzierten Objekte mit gespeichert werden.

ich brauch nur die MAPPINGPOOL- TUPLEs und dann die dazugehörigen CONNECTIONs, aber nicht umgekehrt. könntet ihr mir vielleicht ein bisschen auf die Sprünge helfen, komm mom. nicht so richig weiter.
Besten Dank,
 
Viel zu wenig Infos, man kann nur raten...

[HQL]select distinct m
from MappingTool m
left join FETCH m.connections[/HQL]
 
Zuletzt bearbeitet:
OK, im Tutorial von dir ist eigentlich eh genau das dabei, was ich benötige, zuerst einen Event hinzufügen (bei mir eine Connection), dann eine Person hinzufügen (bei mir eine MappingPool) und dann diese 2 Verbinden mit:

Java:
Long eventId = mgr.createAndStoreEvent("My Event");
            Long personId = mgr.createAndStorePerson("Foo", "Bar");
            mgr.addPersonToEvent(personId, eventId);
            System.out.println("Added person " + personId + " to event " + eventId);

meine Frage wäre noch, macht man das immer so wenn man ein Tupel einfügen will oder gibt es einen einfacheren Weg, ein Tuple einzufügen?

lg


Java:
 private Long createAndStoreEvent(String title) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        Connection theEvent = new Connection();
        theEvent.setConnectionName(title);
        session.save(theEvent);
        session.getTransaction().commit();
        return theEvent.getId();
        }

    private Long createAndStorePerson(String firstname, String lastname) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        MappingPool thePerson = new MappingPool();
        thePerson.setName(firstname);
        thePerson.setZustand(lastname);
        session.save(thePerson);
        session.getTransaction().commit();
        return thePerson.getId();
        }
 
Wäre euch dankbar, wenn ihr sagen könntet, ob das so OK ist, wenn ich das so mache,
hab leider noch keine Erfahrung mit Hibernate in diese Richtung,
lg
 
Das kann man so machen. Üblich ist es aber eher, den Persistenzcode wegzukapseln, indem man sich z.B. DAOs für die Hibernate Objekte schreibt. Siehe dazu: https://www.hibernate.org/328.html

Danke, schau mal ob ich durchsteigen kann,

Was ich bei Hibernate noch nicht verstehe ist, wo schreibe ich meine SQL - Statements hin, ich habe vorher iBatis verwendet -> da schreibt man die SQL ABFRAGE in eine XML- Datei, ist das bei Hibernate auch so oder wie funkt. das?
 
Hibernate hat eine eigene Query Language (HQL). HQL ist für alle DBs gleich und übersetzt (je nach konfiguriertem Dialekt) in für die eingesetzte DB korrektes SQL. Alternativ ist es aber auch möglich, natives SQL abzufeuern. Sollte man aber idR nicht brauchen / vermeiden.

Du kannst bei Hibernate das HQL entweder in Form eines Named Query in der XML / Annotation ablegen oder einfach programmatisch abfeuern:

Java:
sessionFactory.getCurrentSession().createQuery(hql).list();

Solchen Persistence Code kapselt man idR in DAOs oder Repositories.
 
Das sind die für dieses Beispiel gemappten Hibernate Objekte...

Hibernate ist ein OR-Mapper. Das heisst, Du mappst ein Java Objekt auf eine (oder mehrere) Tabellen in der Datenbank. IdR definiert man sich dann pro gemapptem Hibernate Objekt ein DAO, um diese Objekte zu laden, zu speichern usw.

Wenn Du einmal Deine Mappings geschrieben hast, arbeitest Du im Grunde nur noch auf dem Java Objektmodell (Domain Model genannt) und nicht mehr auf dem Datenbankschema.
 
Zuletzt bearbeitet:
Ich hab jetzt gerade dieses Projekt angesehen Generic Dao: Create : DAO Generic DAOHibernateJava -> DAOCreate, funktioniert auch und entspricht auch dem was du geschrieben hast, man schreibt nur mehr eventDao.create(event); und das Objekt wird gespeichert,

Ist es das was du meinst?
Was mich bei diesem Beispiel irritiert ist, das die SQL- Statements direkt im Code drinnenstehen!?


Java:
public static void main(String[] args) {
		HibernateUtil.setup("create table EVENTS ( uid int, name VARCHAR(30), start_Date date, duration int);");
        EventDao eventDao = new EventDao();
        Event event = new Event();
        event.setName("Create");
        eventDao.create(event);
        HibernateUtil.checkData("select uid, name from events");                		
        }
 
Wenn Du nicht willst, dass das HQL/SQL im Code steht, dann guck Dir Named Queries an.
 
Tut mir leid wenn ich so viel (und blöd) frage, aber was ist dann der untere Code, da braucht man auch kein SQL,
was ist eingentlich "from Event", steht dieser Name irgendwo in einer XML- Datei oder kennt sich da Hibernate aus, das die Eintrage von der Tabelle Event gelesen werden?

lg

Java:
final Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        final List result = session.createQuery("from Event").list();
        session.getTransaction().commit();
        return result;
 
und wenn ich HQL verwende erübrigt sich das Verwenden von DAO? Mit DAO bin ich eh schon ziemlich abstract??

PS: den Link zu 1.2.Part 1 - The first Hibernate Application gibts nicht mehr
 
Nein, damit erübrigt sich SQL.

Beim Hibernate Core Download ist die Doku als PDF dabei. Nimm die am besten (die Online Version spinnt grade).
 
Das DAO ist dafür da, damit Du nicht den Hibernate Code über Deine gesamte Anwendung verstreust. Du wirst aber idR nicht drum herum kommen, in Deinen DAOs noch spezifische Queries abzufeuern. Das GenericDao deckt nur simple Datenbankabfragen ab. Wenn Du aber später alle Objekte eines Typs haben willst, wo bestimmte Kriterien erfüllt sind, dann musst Du das in dem entsprechenden DAO implementieren und ein HQL-, Criteria- oder SQL-Query schreiben.
 
ok, danke, schön langsam verstehe ich, was mit aber noch unklar ist,
ich hab bei mir 3 Tabellen, wie oben schon beschrieben, wobei 2 Tabellen eine n:m- Verbindung haben und dadurch die dritte Tabellen entsteht.

Du hast ja geschrieben, für jetzt Tabelle (bzw. Klasse) eine DAO- Klasse, meine Frage wäre jetzt -> auch für die Verbindungstabelle eine DAO- Klasse.

Mit ist nämlich nicht ganz klar, wie ich Tuples (z.B.: Person + dazugehörige Events) auslesen soll, wenn ich für jede Tabelle eine DAOKlasse habe.
 
Nein, für die Verbindungstabelle brauchst Du idR keine Klasse anlegen. Du definierst das direkt im Mapping mittels @JoinTable. Siehe dazu Doku...
 
Denke weniger in Tabellen und mehr an Objekte die relationen (Referenz, Collection) untereinander haben.
Anstatt "Tuples" hast du eben die Objekte und navigierst über diese.

M:N Verbindungen sind nicht unproblematisch, manchmal nötig, aber wenn nicht dann sollte man sie vermeiden.
Normalerweise braucht man kein DAO für die Mappingtabelle in der DB, wenn sie nur dort existiert 😉
 
Denke weniger in Tabellen und mehr an Objekte die relationen (Referenz, Collection) untereinander haben.
Anstatt "Tuples" hast du eben die Objekte und navigierst über diese.

Das Versuch ich und mir ist auch schon so einiges klarer, ein Object hat eine Liste/Set mit Objekten von einer anderen Klasse -> unidirektional
wenn ei Objekt in der Liste auch eine Liste mit Objekten der anderen Klasse hat, dann ist es bidirektional -> so stell ich mir das vor

Was mir jedoch noch unklar ist, ist der workaround um das INSERT und das SELECT mit Hibernate.


@byte: Du definierst das direkt im Mapping mittels @JoinTable. Siehe dazu Doku
Das in der Doku suchen ist noch nicht so leicht, da suche ich die Nadel im Heuhaufen.
Mal wieder ne blöde Frage, reicht das untere Mapping, damit Hibernate klar ist, das die beiden Tabelle n:m (unidirectional) verbunden sind oder muss ich da wirklich die Annotation auch noch einbauen (irgendwo habe ich gelesen -> XML oder Annotation)

Vielen Dank für Eure Hilfe,
lg

Code:
<hibernate-mapping>
    <class name="events.Person" table="PERSON">
    <id name="id" column="PERSON_ID">
        <generator class="native"/>
    </id>
    <property name="age"/>
    <property name="firstname"/>
    <property name="lastname"/>
    <set name="events" table="PERSON_EVENT">
        <key column="PERSON_ID"/>
        <many-to-many column="EVENT_ID" class="events.Event"/>
    </set>
</class>
</hibernate-mapping>
 
Ich benutze keine XML Mappings sondern Annotations. Daher kann ich dazu wenig sagen.
 
Ich habe jetzt einen blöden Fehler, wenn ich jetzt den unteren Code ausführe klappt alles wunderbar nur, der Primarykey wird in der ersten Tabelle von 1 bis 5 hochgezählt (was eh passt) und in der zweiten Tabelle fängt der Primary key dann bei 6 an, er hängt also zwischen den beiden Tabellen zusammen,
Hat das schon mal jemand gehabt, ich komm nicht drauf, was da der Fehler ist.


Code:
final ConnectionDao connectionDao = new ConnectionDao();
        final MappingPoolDao mappingPoolDao = new MappingPoolDao();

        for (int i = 0; i < 5; i++) {
            final MappingPool mappingPool = new MappingPool();
            mappingPool.setName("MappingPool " + i);
            mappingPool.setWert(22.4f);
            mappingPool.setZustand("nicht verbunden");
            mappingPoolDao.create(mappingPool);
            }

        for (int i = 0; i < 7; i++) {
            final Connection connection = new Connection();
            connection.setConnectionName("TestMQ " + i);
            connectionDao.create(connection);
            }
 
Habs schon, das hängt von der Datenbank ab, die vergibt einfach irgendwelche IDs,
FireBird z.B.: hat nur einen keygenerator und zählt einfach stupide hinauf, egal welche tabelle, derby fängt bei der einen Tabelle bei 1 an und bei der anderen Tabelle mit 32767,
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben