# Problem mit EMF/Teneo, GregorianCalendar, Date, Hibernate Timestamp



## krazun (8. Okt 2010)

Schönen guten Tag,

ich arbeite mich grade in EMF/Teneo ein und habe folgendes Problem:

Ich habe in einem EMF Modell einige EAttribute die bis jetzt vom Typ java.util.date waren in java.util.calendar geändert. Da ich in Java mit java.util.GregorianCalendar arbeite möchte ich mir das hin und her konvertieren ersparen.

Ich habe also einen EDataType hinzugefügt mit dem instance class name: java.util.Calendar und in den Objekten wo ich vorher folgenden EType benutz habe: EDate [java.util.Date], nutze ich nun: Calendar [java.util.Calendar]. 

Ich habe das genmodel aktualisiert und den model-code neu generieren lassen. Im *.model.impl package wurden die entsprechenden Klassen auch wie gewollt von date auf calendar aktualisiert.
Auch habe ich sämtliche Tabellen gelöscht und von Hibernate neu anlegen lassen, nach dem aktualisieren des genmodel.

Allerdings bekomme ich nun bei dem Versuch die Objekte mit session.save(component) zu persistieren folgende Exception:


```
Exception in thread "main" java.lang.ClassCastException: java.util.GregorianCalendar cannot be cast to java.util.Date
    at org.hibernate.type.TimestampType.deepCopyNotNull(TimestampType.java:89)
    at org.hibernate.type.MutableType.deepCopy(MutableType.java:48)
    at org.hibernate.type.TypeFactory.deepCopy(TypeFactory.java:397)
    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:303)
    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
    at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
    at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:562)
    at org.hibernate.impl.SessionImpl.save(SessionImpl.java:550)
    at org.hibernate.impl.SessionImpl.save(SessionImpl.java:546)
```

Für mich sieht das so aus als ob Hibernate nun versuchen würde Calendar-Werte als Timestamp zu nutzen, obwohl ich an den Hibernate/Teneo Einstellungen nichts verändert habe. An den vom EMF generierten Klassen habe ich auch keine manuellen Veränderungen durchgeführt (Keine Annotation geändert oder ähnliches). 

Die Initialisierung von Hibernate/Teneo wurde vorher und nacher wie folgt durchgeführt:


```
public void initDataStore() {

        Properties hibernateProperties = new Properties();
        hibernateProperties.setProperty(Environment.DRIVER, "com.microsoft.sqlserver.jdbc.SQLServerDriver");
        hibernateProperties.setProperty(Environment.USER, "user");
        hibernateProperties.setProperty(Environment.PASS, "pass");
        hibernateProperties.setProperty(Environment.URL, "jdbc:sqlserver://127.0.0.1\\SQLEXPRESS;DatabaseName=database");
        hibernateProperties.setProperty(Environment.DIALECT, SQLServerDialect.class.getName());
        hibernateProperties.setProperty(PersistenceOptions.CASCADE_POLICY_ON_NON_CONTAINMENT, "REFRESH,PERSIST,MERGE");
        hibernateProperties.setProperty(PersistenceOptions.INHERITANCE_MAPPING, "JOINED");
        
        final String dataStoreName = "datastore";
        final HbDataStore dataStore = HbHelper.INSTANCE.createRegisterDataStore(dataStoreName);
        dataStore.setProperties(hibernateProperties);
        dataStore.setEPackages(new EPackage[] { ModelPackage.eINSTANCE });
        try {
            dataStore.initialize();
        } catch (Exception ex) {
            System.err.println(dataStore.getMappingXML());
            ex.printStackTrace();
        }
        sessionFactory = dataStore.getSessionFactory();
        
    }
```

Hatte vielleicht schonmal jemand ein ähnliches Problem oder eine Idee woran das liegen könnte ?

mfg,
krazun


----------



## diel2001 (8. Okt 2010)

Gibt es keine Möglichkeit einfach die getDate() methode in dem Calendar aufzurufen ??
Dann bekommst du nämlich ein DateObject zurück


----------



## SlaterB (8. Okt 2010)

ändere das schleunigst wieder in Date zurück, Hibernate versteht nur begrenzt viele Standard-Klassen,
du würdest ja auch nicht einen StringBuilder an Stelle eines Strings mappen


----------



## krazun (8. Okt 2010)

diel2001 hat gesagt.:


> Gibt es keine Möglichkeit einfach die getDate() methode in dem Calendar aufzurufen ??
> Dann bekommst du nämlich ein DateObject zurück




Ich denke wenn ich für mein Problem keine Lösung finde werd ich es so machen müssen 

Ich arbeite dann in Java mit Calendar, persistiere als Date und konvertiere immer mit calendar.setTime(Date), calendar.getTime() hin und her.

Funktionieren tut es schon, ich hätte es nur schöner gefunden durchgängig mit Calendar zu arbeiten 

mfg,
krazun


----------



## krazun (8. Okt 2010)

SlaterB hat gesagt.:


> ändere das schleunigst wieder in Date zurück, Hibernate versteht nur begrenzt viele Standard-Klassen,
> du würdest ja auch nicht einen StringBuilder an Stelle eines Strings mappen



Allerdings hat man bei EMF doch die Möglichkeit beliebige Klassen als EDataType zu benutzen.

In dem Artikel "Eclipse Modeling Framework (EMF) - Tutorial " von Lars Vogel (Eclipse Modeling Framework (EMF) - Tutorial) wird ebenfalls Calendar als eigener Datentyp definiert:







Ich hab bis jetzt noch nirgens gelesen das Teneo nur die vorgegeben ETypes persistieren kann und keine EDataTypes. Ich hab angenommen das mit Calendar dann ebenso umgegangen wird als wenn ich eine beliebige selbst erstellte Klasse persistiere.

Ich werd nochmal schauen ob ich in der Teneo Dokumentation etwas übersehen hab.

Ich mag es ja auf einer hohen Abstraktionsebene zu arbeiten mit EMF/Teneo. Man kann so wirklich verdammt schnell komplexe Modelle entwickeln, in Java Code umsetzen lassen und persistieren. Aber bei der Fehlersuche kann das echt anstrengend werden, wenn man sich noch nicht wirklich tiefgehend eingearbeitet hat 

mfg,
krazun


----------



## Wildcard (8. Okt 2010)

Du kannst einfach ein derived (und transient und volatile) Feature vom Typ Calendar in deinem Modell erstellen. Du musst dann die entsprechende get Methode implementieren und einfach dort dein Date in einen Calendar  umwandeln. Da dieses Feature transient  ist (also nicht serialisiert wird) stört sich Hibernate nicht an diesem Typ.


----------



## krazun (11. Okt 2010)

Wildcard hat gesagt.:


> Du kannst einfach ein derived (und transient und volatile) Feature vom Typ Calendar in deinem Modell erstellen. Du musst dann die entsprechende get Methode implementieren und einfach dort dein Date in einen Calendar  umwandeln. Da dieses Feature transient  ist (also nicht serialisiert wird) stört sich Hibernate nicht an diesem Typ.



Vielen Dank für den Tipp! Ich werde gleich versuchen das so Umzusetzen.

mfg,
krazun


----------

