# DAO - Designfrage



## y0dA (23. Jan 2008)

Hi!
Kennt ihr eine schöne DAO Abstraktion, welche ich mit Hibernate (ohne Spring!) benutzen kann?

Folgendes kenne ich schon, verstehe ich aber nicht: Hibernate Dao
Sprich hierbei fehlt mir einfach ein Anwendungsbeispiel.

Reicht es nicht einfach für jede meiner Tabellen (sofern in Hibernate abgebildet) ein eigenes DAOInterface zu machen oder brauch ich noch ein "Über-"Interface?

mfg


----------



## maki (23. Jan 2008)

Den Link den du gefunden hast, ist eigentlich alles was du brauchst imho.
Schön, elegant und sehr allgemein, um nicht zu sagen generisch 

Ein Beispiel ist schon drinnen 



> verstehe ich aber nicht


Das ist am Anfang immer so, einfach anfangen, irgendwann fällt dann meistens der Groschen.


----------



## y0dA (23. Jan 2008)

Naja ich habe die Klassen/Interfaces aus dieser Seite in mein Projekt kopiert, jedoch fehlen mir die Klassen "Item" und "Bit"..


----------



## maki (23. Jan 2008)

Item und Bid sind die Beispiele *g*


----------



## y0dA (23. Jan 2008)

Gibts davon irgendwo auch den Code zum runterladen?

Also Item und Bid sind normale Pojos welche in der Datenbank Tabellen repräsentieren?

**EDIT**
Weiteres Problem:

```
package org.pcd.wam.gegenstandsbereich.streetDetection.persistence.dao;
import java.io.Serializable;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;
import org.hibernate.usertype.ParameterizedType;

public abstract class GenericHibernateDAO<T, ID extends Serializable>
        implements GenericDAO<T, ID> {

    private Class<T> persistentClass;
    private Session session;

    public GenericHibernateDAO() {
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
                                .getGenericSuperclass()).getActualTypeArguments()[0];
     }

    @SuppressWarnings("unchecked")
    public void setSession(Session s) {
        this.session = s;
    }

    protected Session getSession() {
        if (session == null)
            throw new IllegalStateException("Session has not been set on DAO before usage");
        return session;
    }

    public Class<T> getPersistentClass() {
        return persistentClass;
    }

    @SuppressWarnings("unchecked")
    public T findById(ID id, boolean lock) {
        T entity;
        if (lock)
            entity = (T) getSession().load(getPersistentClass(), id, LockMode.UPGRADE);
        else
            entity = (T) getSession().load(getPersistentClass(), id);

        return entity;
    }

    @SuppressWarnings("unchecked")
    public List<T> findAll() {
        return findByCriteria();
    }

    @SuppressWarnings("unchecked")
    public List<T> findByExample(T exampleInstance, String[] excludeProperty) {
        Criteria crit = getSession().createCriteria(getPersistentClass());
        Example example =  Example.create(exampleInstance);
        for (String exclude : excludeProperty) {
            example.excludeProperty(exclude);
        }
        crit.add(example);
        return crit.list();
    }

    @SuppressWarnings("unchecked")
    public T makePersistent(T entity) {
        getSession().saveOrUpdate(entity);
        return entity;
    }

    public void makeTransient(T entity) {
        getSession().delete(entity);
    }

    public void flush() {
        getSession().flush();
    }

    public void clear() {
        getSession().clear();
    }

    /**
     * Use this inside subclasses as a convenience method.
     */
    @SuppressWarnings("unchecked")
    protected List<T> findByCriteria(Criterion... criterion) {
        Criteria crit = getSession().createCriteria(getPersistentClass());
        for (Criterion c : criterion) {
            crit.add(c);
        }
        return crit.list();
   }

}
```

Detail des Problems:

```
public GenericHibernateDAO() {
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
                                .getGenericSuperclass()).getActualTypeArguments()[0];
     }
```


```
.getActualTypeArguments()[0];
```
ist undefiniert für den Typ *ParameterizedType*


----------



## maki (23. Jan 2008)

> Gibts davon irgendwo auch den Code zum runterladen?


Soll das ein Witz sein?? lol
Der Code ist vollständig auf der Seite in deinem Link... lies dir die Seite nochmals in Ruhe durch.

Du brauchst das Interface GenericDAO und die abstrakte Klasse GenericHibernateDAO, fertig.

Eigene Interfaces & Implementierungen schreiben, so wie in den Beispielen 
Normalerweise sind deine Interfaces übrigens leer, sowie deine Implmentierungen auch, ausser du brauchst spezielle funktionen, die allgemeinen sind schon drinn.
getMaxBid/getMinBid sind spezielle Funktionen, das Beispiel zeigt wie man diese implmentiert, kannst du weglassen.



> Also Item und Bid sind normale Pojos welche in der Datenbank Tabellen repräsentieren?


Ja.


----------



## y0dA (23. Jan 2008)

Ja ich hab heute nen schweren brain lagg..

Diese Methode ist hier anders implementiert als im Interface:

```
@SuppressWarnings("unchecked")
    public List<T> findByExample(T exampleInstance, String[] excludeProperty) {
        Criteria crit = getSession().createCriteria(getPersistentClass());
        Example example =  Example.create(exampleInstance);
        for (String exclude : excludeProperty) {
            example.excludeProperty(exclude);
        }
        crit.add(example);
        return crit.list();
    }
```
Was sollte die Methode eigentlich machen?

Und hier wird nach wie vor von Eclipse behauptet dass ParameterizedType "getActualTypeArguments" nicht definiert..

```
public GenericHibernateDAO() { 
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass() 
                                .getGenericSuperclass()).getActualTypeArguments()[0]; 
     }
```


----------



## byte (23. Jan 2008)

Dann belügt Dich Eclipse, denn:
http://java.sun.com/javase/6/docs/api/java/lang/reflect/ParameterizedType.html#getActualTypeArguments()


----------



## y0dA (23. Jan 2008)

byto hat gesagt.:
			
		

> Dann belügt Dich Eclipse, denn:
> http://java.sun.com/javase/6/docs/api/java/lang/reflect/ParameterizedType.html#getActualTypeArguments()



Wie schon erwähnt steh ich heute auf der Leiter..

Hibernate besitzt ebenfalls ParameterizedType als Klasse und jene hatte ich implementiert..


----------



## maki (23. Jan 2008)

Welche Hibernate Version verwendest du y0dA?


----------



## y0dA (23. Jan 2008)

Hibernate: 3.2.5.ga

Kann mir noch jemand sagen was es mit dieser Methode "findByExample" auf sich hat?


----------



## maki (23. Jan 2008)

Die Methode sucht nach Objekten die ähnlich der übergebenen exampleInstance sind.


----------



## y0dA (23. Jan 2008)

maki hat gesagt.:
			
		

> Die Methode sucht nach Objekten die ähnlich der übergebenen exampleInstance sind.



Muss ich das verstehen? Was ist mit dem 2ten Parameter *final String[] excludeProperty*? Habe bisher noch nie mit Criteria gearbeitet. Wie definiert sich "ähnlich"?


----------



## y0dA (4. Feb 2008)

Also habe diese DAO Konstrukt nun implementiert, jedoch tut sich mir hierbei noch eine Frage auf:

Wie implementiere ich eine DAO, welche nur Hilfsoperationen beinhaltet, also kein save/load eines Objektes sondern schlicht weg nur bestimmte Operationen (GEO) durchführt und mir bspw eine Distanzangabe zurückliefert?
Also ich habe einfach kein Model (wie bei dem Bsp Item) auf welchen Operationen stattfinden sollen, sondern eine DAO voller DB Operationen, welche zu keinem Objekt passen und für sich stehen.

Kann man dies mit diesem DAO Konstrukt von Hibernate?
Jemand eine Idee?

mfg


----------



## ARadauer (4. Feb 2008)

> sondern schlicht weg nur bestimmte Operationen (GEO)


Wenn es nur Hilfoperationien hat ist es auch kein DAO (Data Access Objekt)

Was machen diese Hilfsoperationen kokret?

Zb sowas wie Entfernung zwischen zwei Punkten.. würd ich ich im Fachobjekt selber halten. also Punkt

```
public int getDistance(Point p1){
}
```

für andere Dinge kannst du dir ja Hilfsklassen oder Adapter basteln.

Was machen den deine Objekte konkret?


----------



## y0dA (5. Feb 2008)

Hi!
Ja wie du schon geschrieben hast, berechne ich div. Distanzen, Geschwindigkeiten etc. - leider habe ich halt kein Objekt wo jene Operationen reinpassen, also die basieren nicht auf einen Punkt etc.

Wie darf ich das mit Hilfsklassen und Adapter verstehen?

mfg


----------



## ARadauer (5. Feb 2008)

es wird zwar immer geprädigt, dass static methoden nicht so gut sind und gegen objektorientierten prinzipien usw... aber wenn du einfache berechnungen aufgrund von Werten machen musst kannst du dir ruhig eine Klasse schreiben die statische Methoden hat. Ist ja auch in der Math Klasse von Java so gemacht.


```
public class CalcUtil {			
		/**
		 * @param distance entfernung in KM
		 * @param time Zeit in Stunden
		 * @return km/h
		 */
		public static float calcSpeed(float distance, float time){
			return distance/time; 
		}

}
```
formel stimmt oder? *g*

Wenn du zb Distanzen berechnen willst, würd ich schon sagen, dass sich die auf einen Punkt bezieht oder?


```
public class Punkt {			
		
		public float getDistance(Punkt p){
			/**
			 * berechnet die Entfernung von diesem Punkt zu dem Übergebenen Punkt
			 */
		}

}
```

Mit Adapter (Pattern Profis werden mich steinigen) hatte ich zb einen Export als HTML im Sinn. Das passt direkt zum Punkt, ist aber vielleciht ganz Sinnvoll wenn man es in eine andere Klasse bringt...

```
public class PunktHtmlExport {			
		
		private Punkt p;
		
		public String toString(){
			/**
			 * macht lustige Ausgbaben um den Punkt als HTML zu visualisieren
			 */
		}

		public Punkt getP() {
			return p;
		}

		public void setP(Punkt p) {
			this.p = p;
		}
		
		

}
```

Sowas könnte man auch super in einem Interface definieren und dann verschiede Export Möglichkeiten über eine Factory zurück geben....


----------

