# Type-Mapping von DB-Type zu ObjectType via Hibernate



## Foermchen82 (14. Okt 2008)

Hallo zusammen.

Ich habe folgende Situation:

Ich lade und speichere ein Object via Hibernate in eine Datenbank.
Jetzt habe ich da ein Attribut, ich nenn es jetzt mal "mappingAttribut", was in der Datenbank einen bestimmten Type hat. Im object jdedoch soll es in einem anderen Typ, nämlich in einem eigenen Object abgebildet werde.
Beispiel: in der Datenbank ist es String und in meinem Object soll es z.b. den TypABC haben.
Den Typ ABC kann ich Problem los aus dem String herstellen (z.b. ein Object, was den Stringinhalt, die Länge und das Wort rückwärts haben)

Hibernate füllt ja normalerweise die Properties via Getter und Setter methoden. Die sollten aber schon den DB-Typ bzw. ein Äquivalent haben. Das Object jedoch soll für das "mappingAttribut" den Typ ABC haben. Wie kann ich das also am einfachsten herstellen?


----------



## SlaterB (14. Okt 2008)

sowas wie User Types?
http://i-proving.ca/space/Technologies/Hibernate/User+Types+in+Hibernate

oder einfacher
http://www.hibernate.org/hib_docs/reference/en/html/components.html

hab grad keine Ahnung wie das heißt, Value Type, Compoment, composite element,

einfach mal in einem Hibernate-Buch alle möglichen Mappings anschauen?


----------



## Foermchen82 (15. Okt 2008)

Danke für die Antwort.
Sowas wie USerType hab ich gesucht.

Jedoch stehe ich jetzt vor dem Nächsten Problem:

Mein Object referenziert auf ein weiteres, welches auch in der DB liegt. Soweit so gut. das kann man ja via one-to-one machen.

Jedoch benötigt mein "mappingAttribut" zum korrektem mappen des Typs informationen von dem Object auf welches in der assoziation refernziert wird.

Die methode:

```
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner)
			throws HibernateException, SQLException {
}
```

aus dem UserType-Interface jedoch bietet mir keine Möglichkeiten auf andere Properties meines Objektes zuzugreifen. Was kann ich da tun??

Danke im voraus.


----------



## Foermchen82 (16. Okt 2008)

In meiner Frage liegt zum Teil die Antwort. Die Methoden-Signatur, die ich gepostet haben gibt mir ja das owner-Objekt mit. Das ist jedoch noch nicht gefüllt. Zum zeitpunkt an dem das Mapping mit dem UserType durchgeführt wird.

Wozu ist also das owner-Objekt zu gerbrauchen, wenn es doch gar nicht vollständig ist. Kann ich das irgenwie so konfigurieren, das erst alle Properties geladen werden und erst dann das was ich mappen will?

Danke im Voraus!!


----------



## SlaterB (16. Okt 2008)

ich kann da nicht weiterhelfen,
hab mal bei einem UserType aus meinem Programm geschaut,
nicht von mir geschrieben, da ist der Owner immer vorhanden

einn UserType mit zwei int-Werten

Mapping:

```
<property name="z" type="package.ZType">
			<column name="Unit" precision="12" scale="0" />
			<column name="Count" precision="12" scale="0" />
		</property>
```
die Klasse

```
public class ZUserType implements CompositeUserType
{
    
    public String[] getPropertyNames()
    {
        return new String[]{"unit", "count"};
    }

    public Type[] getPropertyTypes()
    {
        return new Type[]{Hibernate.INTEGER, Hibernate.INTEGER};
    }

    public Object getPropertyValue(Object component, int property)
        throws HibernateException
    {
        final Z z = (Z)component;

        return property == 0 ? (Object)z.getUnit() : (Object)z.getCount();

    }

    public void setPropertyValue(Object component, int property, Object value)
        throws HibernateException
    {
        final Z z = (Z)component;

        if (property == 0)
            z.setUnit((Integer)value);
        else
            z.setCount((Integer)value);
    }

    public Class returnedClass()
    {
        return Z.class;
    }

    public boolean equals(Object x, Object y)
        throws HibernateException
    {
        if (x == y) return true;
        if (x == null || y == null) return false;

        final Z zX = (Z)x;
        final Z zY = (Z)y;

        return (zX.getUnit() == zY.getUnit()) &&
               (zX.getCount() == zY.getCount());
    }

    public int hashCode(Object x)
        throws HibernateException
    {
        final Z z = (Z)x;
        return z.getCount() * 100 + z.getUnit();
    }

    public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
        throws HibernateException, SQLException
    {
        System.out.println("owner: "+owner);
        final Integer unit = (Integer)Hibernate.INTEGER.nullSafeGet(rs, names[0]);

        if (unit == null) 
            return null;

        final Integer count = (Integer)Hibernate.INTEGER.nullSafeGet(rs, names[1]);
        return new Z(unit, count);

    }

    public void nullSafeSet(PreparedStatement st, Object value, int index,
                            SessionImplementor session)
        throws HibernateException, SQLException
    {
        final Z z = (Z)value;

        final Integer unit;
        final Integer count;

        if (z == null)
        {
            unit = null;
            count = null;
        }
        else
        {
            unit = z.getUnit();
            count = z.getCount();
        }
        
        Hibernate.INTEGER.nullSafeSet(st, unit, index);
        Hibernate.INTEGER.nullSafeSet(st, count, index + 1);
    }

    public Object deepCopy(Object value)
        throws HibernateException
    {
        if (value == null)
            return null;
        
        final Z z = (Z)value;
        return new Z(z.getUnit(), z.getCount());
    }

    public boolean isMutable()
    {
        return true;
    }

    public Serializable disassemble(Object value, SessionImplementor session)
        throws HibernateException
    {
        return (Serializable)deepCopy(value);
    }

    public Object assemble(Serializable cached, SessionImplementor session, Object owner)
        throws HibernateException
    {
        return deepCopy(cached);
    }

    public Object replace(Object original, Object target, SessionImplementor session, Object owner)
        throws HibernateException
    {
        return deepCopy(original); //TODO: improve
    }
}
```
System.out.println("owner: "+owner); 
aus Zeile 89 liefert nie null, 
zumindest bei einfachem Test, paar Objekte aus DB lesen, nix angelegt usw.


----------



## Foermchen82 (16. Okt 2008)

Das owner-Objekt ist ja auch nicht null. Nur die Properties sind noch nicht aus der DB geladen.


----------



## SlaterB (16. Okt 2008)

ok, das kann ich auch bestätigen bis auf den Primärschlüssel,

sonst aber nix mehr beitragen


----------

