kannengi
Elite Observer

session.createEntity() liefert entity mit fsId null

Hallo Community,

ich versuche, mit der access API ein Modul zu erstellen, das ein Excel-Sheet einliest, daraus eine Liste von Objekten instanziiert und dann in einer Schleife diese Objekte in eine Tabelle einer FirstSpirit Datenquelle schreibt.

Mein Problem ist, dass unregelmäßig, etwa nach 4 - 10 Iterationen, die von der Methode session.createEntity() erzeugte Entity keine fsId hat.

Dies führt dann dazu, dass die Werte in den FormData Feldern nicht gespeichert werden können. Hier der vereinfachte Code:

Project project = myProject;
Language lang = project.getMasterLanguage();
ContentStoreRoot contentStore = (ContentStoreRoot) project.getUserService().getStore(Store.Type.CONTENTSTORE, true, false);
Content2 table = contentStore.getContent2ByName("TABLE_NAME");
Session session = table.getSchema().getSession();

List myObjectListToSave = meineListeVonImportiertenObjekten;
for (Object myObjectToSave : myObjectListToSave) {
     Entity entity = session.createEntity(table.getEntityType().getName());
     session.commit();
     Long fsId = (Long) entity.get("fs_id"); // ist manachmal null!!!!!
     table.lock(entity);
     Dataset dataset = table.getDataset(entity);
     FormData formData = dataset.getFormData();

     FormField formField1 = formData.get(lang, "field1");
     formField.set(myObjecToSave.getField1());
     // etc. mit anderen Feldern
    
     dataset.setFormData(formData); // => Exception "The entity is invalid" wenn fsId vorher null war
     dataset.save();
     table.unlock(entity);
     table.setLock(true);
     table.save();
     table.setLock(false);
     entity.getSession().commit();
}

FirstSpirit 5.1.311.65223

Woran könnte es liegen?

Für einen Tip wär ich sehr dankbar!

Danke und Gruß,

Benny Kannengießer

// re-lounge

0 Kudos
7 Replies
Peter_Jodeleit
Crownpeak employee

In dem Code sind einige Schritte überflüssig, das erklärt aber nicht das Verhalten. Damit solltest du dich an unseren Technical Support wenden. Gibt es vorher Log-Ausgaben, die auf einen Fehler hindeuten?

Die Schleife müsste in der folgenden Form ausreichend sein (wenn ich keinen Syntax-Fehler eingabaut habe):

for (Object myObjectToSave : myObjectListToSave) {

     Entity entity = session.createEntity(table.getEntityType().getName());

     Dataset dataset = table.getDataset(entity);

     FormData formData = dataset.getFormData();

     FormField formField1 = formData.get(lang, "field1");

     formField.set(myObjecToSave.getField1());

     // etc. mit anderen Feldern

    

     dataset.setFormData(formData); // => Exception "The entity is invalid" wenn fsId vorher null war

     dataset.save();

}

Kannst du bitte den Fehler mit dieser Version des Codes wiederholen, das sollte weniger Log-Ausgaben produzieren.

Peter

Hallo Peter,

danke für die schnelle Rückmeldung.

Tatsächlich ist die Exception nicht mehr aufgetaucht, nach dem ich den Aufruf "session.commit()" nach "session.createEntity()" herausgenommen habe.

(Obwohl dann das entity Object noch keine fsId hat).

Trotzdem muss ich immer noch das "dataset.save()" mit einem "table.lock(entity)/table.unlock(entity)" umschließen, da ansonsten manchmal dieser Fehler auftaucht:

ERROR 04.03.2015 09:16:39.285 (de.espirit.firstspirit.impl.access.ScriptContextImpl): entity has changed: de.espirit.or.impl.IdentifierImpl$TemporalIdentifierUC@a54f5a9c{product,FS_ID=6656,FS_VALID_FROM=1425456988056,FS_VALID_TO=1425456993005,FS_RELEASE_TO=0}
FSVersion=5.1.311.65223#3209;JDK=1.6.0_39 32bit Sun Microsystems Inc.;OS=Windows 8 6.2 x86;Date=04.03.2015 09:16:39

Ich sehe, dass die entity erst nach dem Aufruf von "dataset.save()" eine fsId hat - ich nehme an, das heißt, dass intern die Session committed wird?

Danke und Gruß,

Benny Kannengießer

// re-lounge

0 Kudos

Ja, das Dataset.save() macht intern das commit.


Die Fehlermeldung wird in deinem Code ausgegeben? Kannst du da einen Trace ausgeben?

Ohne Trace kann man nur Vermutungen über die Ursache anstellen.. Es könnte eine Fremdschlüsselbeziehung zu einem Datensatz ("product") sein, das in einer anderen Session geändert wurde.. Diese parallele Bearbeitung wird über das "lock/unlock" dann natürlich unterbunden.

Peter
0 Kudos

Stimmt, meine entities halten einen Fremdschlüssel zu einer anderen Tabelle "products".

Dann war das der Grund..

Das mit dem Trace weiß ich nicht wie man das macht.

Aber seit ich table.lock(entity) benutze, ist der error nicht wieder gekommen, also für mich ist die Sache gelöst 🙂

0 Kudos

Hallo,

wir haben leider beim Importieren von Daten aus einer CSV Datei genau die selbe Fehlermeldung "The entity is invalid".

Wie auch im 1. Post beschrieben tritt der Fehler nach einer zufälligen Anzahl von geschriebenen Datensätzen auf.

Bei manchen Versuchen werden nur 2 Datensätze erzeugt, bei anderen sogar gute 100. (in der CSV sind 450 Datensätze vorhanden).

1-2 Durchläufe waren auch mal erfolgreich, ein erneuter Durchlauf ließ das Ergebnis aber nicht reproduzieren - für den späteren Redakteur ist es eher unzumutbar den Import "x-fach" zu starten bis einer erfolgreich war.

Wir haben versucht das ganze mit dem "table.lock()" zu beheben, allerdings ohne Erfolg.

Im Prinzip sieht unser Code identisch zum Umsetzungsvorschlag aus.

Unsere Komplexität dabei ist das wir zusätzlich beim Import Querverweise auf 2 weitere Datenquellen erzeugen und falls nötig dort ebenfalls einen Datensatz erzeugen. Letztes funktioniert allerdings problemlos - die Fehlermeldung erscheint immer beim Speichern der "Haupt-Entity".

Da user Code durch den CSV-Import etwas länger geworden ist, habe ich diesen in die angehängte Datei ausgelagert.

Die Klasse wird in einem Script innerhalb des SiteArchitects aufgerufen, hier haben wir aber auch keine Probleme.

Grüße,

Lars

0 Kudos

Hallo Lars,

wir haben genau wie Du auch Datensätze in einer anderen Tabelle erzeugt, mit der der aktuelle "Hauptdatensatz" in einer 1:N-Beziehung stand.

Wir haben letztendlich überall die "session.commit()" Aufrufe entfernt, da der dataset.save() ja schon ein Commit macht.

Also probier's doch auch mal und entferne die commits aus den Methoden "handleCategoryColumn()" und "handleCountryColumn".

Viele Grüße,

Benny Kannengießer

// re-lounge

0 Kudos

Hallo Benny,

das "commit()" bei den Countries und Categories brauchten wir, da es sonst reproduzierbar bei der Anlage der Location mit einem zuvor angelegten Querverweis zu einer "Invalid Entity" gekommen ist.

Aufgefallen ist uns allerdings auch das ohne ein "commit" im SiteArchitect die neuen Datensätze nicht gelistet wurden.

Wir haben nun noch ein "dataset.setLock(false)" nach dem "save" hinzugefügt, da ansonsten alle neuen Datensätze im SiteArchitect im Bearbeitungsmodus blieben und aktuell läuft das Script reproduzierbar ohne Fehler durch. Vielleicht hat es daran gelegen haben, aber ob es das wirklich war wird sich wohl erst noch zeigen...

Grüße,

Lars

0 Kudos