luettel
I'm new here

Anhand eines Skripts ein neues Datenbank-Attribut erstellen

Hallo Zusammen,

ich möchte ein einfaches Skirpt erstellt, welches ein neues Attribut in eine Tabelle schreibt.

Dies ist bisher mein Ansatz, aber leider bekomme ich immer einen Fehler. Ich glaube, dass das Schema nicht erstellt werden kann (siehe Kommentar im Code).

Kann mir jemand helfen?

createNewIR() {

    _context.logInfo("createNewIR ....");

    TemplateStoreRoot templateStore = (TemplateStoreRoot) _context.requireSpecialist(StoreAgent.TYPE).getStore(Store.Type.TEMPLATESTORE,false);

  
   TableTemplate tableTemplate = (TableTemplate) templateStore.getStoreElement("test", UidType.TEMPLATESTORE_TABLEFORMATTEMPLATE);
//   getStoreElement("test", UidType.TEMPLATESTORE_TABLEFORMATTEMPLATE);
  
   Schema _schema = tableTemplate.getSchema(); // hier kommt immer der Fehler.
   String _entityTypeName = "Article";
   String _attributeName = "MyAttribute";
    
     try {
        _schema.setLock(true, false);
        final Session orSession = _schema.getSession(false);
        final de.espirit.or.schema.Schema orSchema = orSession.getSchema();
        final EntityType entityType = orSchema.getEntityType(_entityTypeName);
        SimpleAttribute _attribute = entityType.createSimpleAttribute(_attributeName, String.class);
        _attribute.setSize(64);
        orSession.syncSchemaWithDB(orSchema, false);
        _schema.setOrSchema(orSchema);
        _schema.save();
   } catch (Exception e) {
        throw new RuntimeException(e);
   } finally {
        try {
            _schema.setLock(false, false);
        } catch (Exception ignore) {
            // catch exception
        }
   }
  
   return ;
   }

    _context = context;

    createNewIR();

Später sollen dann die Inhalte aus einem Formularfeld (CMS_INPUT_TEXT) in dem Feld gespeichert werden.

0 Kudos
12 Replies
gockel
Crownpeak employee

Hi,

welchen Fehler du bekommst hast du ja leider nicht geschrieben.

Deinem Code nach zu urteilen, würde ich eine NullPointerException vermuten, da das TableTemplate nicht gefunden wird, weil du den falschen UID_TYPE verwendest.

so sollte es gehen:

TableTemplate tableTemplate = (TableTemplate) templateStore.getStoreElement("test", TableTemplate.UID_TYPE);

weitere Probleme in deinem Code, die mir beim überfliegen aufgefallen sind:

unnötig:

orSession.syncSchemaWithDB(orSchema, false);

Hier wird NICHT-rekursiv gelockt (gut)

schema.setLock(true, false);

das ist ein rekursives Speichern (passt nicht zum nicht-rekursiven Lock)

schema.save();

so ist es richtig:

schema.save("attribute added", false);

Gruss

Hi,

vielen dank für die Antwort.

Ich habe das Template wie folgt umgeändert:

createNewIR() {

_context.logInfo("createNewIR ....");

TemplateStoreRoot templateStore = (TemplateStoreRoot) _context.requireSpecialist(StoreAgent.TYPE).getStore(Store.Type.TEMPLATESTORE,false);
  
//    TableTemplate tableTemplate = (TableTemplate) templateStore.getStoreElement("test", UidType.TEMPLATESTORE_TABLEFORMATTEMPLATE);
     TableTemplate tableTemplate = (TableTemplate) templateStore.getStoreElement("test", TableTemplate.UID_TYPE);
  
//    getStoreElement("test", UidType.TEMPLATESTORE_TABLEFORMATTEMPLATE);
  
   Schema _schema = tableTemplate.getSchema(); // hier stürtzt das System ab.
   String _entityTypeName = "Article";
   String _attributeName = "MyAttribute";

   

   try {
   _schema.setLock(true, false);
   final Session orSession = _schema.getSession(false);
   final de.espirit.or.schema.Schema orSchema = orSession.getSchema();
   final EntityType entityType = orSchema.getEntityType(_entityTypeName);
   SimpleAttribute _attribute = entityType.createSimpleAttribute(_attributeName, String.class);
   _attribute.setSize(64);
//  orSession.syncSchemaWithDB(orSchema, false);
   _schema.setOrSchema(orSchema);
//  _schema.save();
   _schema.save("attribute added", false);
   } catch (Exception e) {
   throw new RuntimeException(e);
   } finally {
   try {
   _schema.setLock(false, false);
   } catch (Exception ignore) {
   // catch exception
   }
   }
  
     return ;

     }

_context = context;

createNewIR();

Leider funktioniert damit noch nicht. Anbei noch die Exception:

31.01.2013 12:54:15 (de.espirit.firstspirit.webedit.server.script.ScriptServiceImpl): Unexpected exception during script execution!

FSVersion=5.0.106.53541#3053;JDK=1.6.0_31 64bit Sun Microsystems Inc.;OS=Linux 3.0.38-0.5-default amd64;Date=31.01.2013 12:54:15

de.espirit.firstspirit.access.script.ExecutionException: Typed variable declaration : at Line: 23 : in file: inline evaluation of: ``__execute() { import de.espirit.firstspirit.access.ScriptContext; import de.esp . . . '' : tableTemplate .getSchema ( )

Called from method: createNewIR : at Line: 52 : in file: inline evaluation of: ``__execute() { import de.espirit.firstspirit.access.ScriptContext; import de.esp . . . '' : createNewIR ( )

Called from method: __execute

Target exception: java.lang.NullPointerException: Null Pointer in Method Invocation

at line 23

  at de.espirit.firstspirit.server.script.BeanshellScriptEngine$BeanshellExecutable.execute(BeanshellScriptEngine.java:108)

  at de.espirit.firstspirit.client.gui.applications.ApplicationTabRegistry$IdentifiableExecutable.execute(ApplicationTabRegistry.java:150)

  at de.espirit.firstspirit.common.ScriptUtil.execute(ScriptUtil.java:97)

  at de.espirit.firstspirit.webedit.server.script.WebeditScriptUtil.execute(WebeditScriptUtil.java:62)

  at de.espirit.firstspirit.webedit.server.script.ScriptServiceImpl.executeScript(ScriptServiceImpl.java:68)

  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

  at java.lang.reflect.Method.invoke(Method.java:597)

  at de.espirit.firstspirit.webedit.server.control.PollSupportingWebeditService$RPCInvoke.call(PollSupportingWebeditService.java:172)

  at de.espirit.firstspirit.webedit.server.control.PollSupportingWebeditService$ServiceCallPollFeedWrapper.call(PollSupportingWebeditService.java:285)

  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)

  at java.util.concurrent.FutureTask.run(FutureTask.java:138)

  at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

  at java.lang.Thread.run(Thread.java:662)

Caused by: java.lang.NullPointerException: Null Pointer in Method Invocation

  at bsh.Name.invokeMethod(Name.java:844)

  at bsh.BSHMethodInvocation.eval(BSHMethodInvocation.java:75)

  at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:102)

  at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:47)

  at bsh.BSHVariableDeclarator.eval(BSHVariableDeclarator.java:86)

  at bsh.BSHTypedVariableDeclaration.eval(BSHTypedVariableDeclaration.java:84)

  at bsh.BSHBlock.evalBlock(BSHBlock.java:130)

  at bsh.BSHBlock.eval(BSHBlock.java:80)

  at bsh.BshMethod.invokeImpl(BshMethod.java:362)

  at bsh.BshMethod.invoke(BshMethod.java:258)

  at bsh.BshMethod.invoke(BshMethod.java:186)

  at bsh.Name.invokeLocalMethod(Name.java:917)

  at bsh.Name.invokeMethod(Name.java:804)

  at bsh.BSHMethodInvocation.eval(BSHMethodInvocation.java:75)

  at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:102)

  at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:47)

  at bsh.BSHBlock.evalBlock(BSHBlock.java:130)

  at bsh.BSHBlock.eval(BSHBlock.java:80)

  at bsh.BshMethod.invokeImpl(BshMethod.java:362)

  at bsh.BshMethod.invoke(BshMethod.java:258)

  at bsh.BshMethod.invoke(BshMethod.java:161)

  at bsh.PreparsedScript.invoke(PreparsedScript.java:65)

  at de.espirit.firstspirit.server.script.BeanshellScriptEngine$BeanshellExecutable.execute(BeanshellScriptEngine.java:99)

... 15 more

0 Kudos
gockel
Crownpeak employee

Ok, jetzt kann man ja gar nichts mehr lesen.

Bitte mal das obige Posting anpassen, so dass der Code vernünftig angezeigt wird ("Use advanced editor" -> Insert ->  Syntax-Highlighting -> Java).

Davon ab, ist die Fehlermeldugn doch eindeutig. Es tritt eine NPE auf in der Zeile, die du auch kommentierst. Die Variable "tabletemplate" ist null. Ist die UID "test" denn überhaupt korrekt ?

Das mit der UID war ein guter Typ. Vielen Dank. Jetzt wird mein Datenbank-Attribut MyAttribute zur Tabelle Article angelegt.

Wie könnte man jetzt in dieses Attribut einen Wert schreiben?

0 Kudos

Hallo,

man kann das Attribut ganz normal, wie alle anderen Attribute auch, wahlweise manuell oder per Skript befüllen.

Anhand des Skripts geht es am besten über ein Content2 Objekt. Von diesem holt man sich den Dataset und dann über FormData und dem Namen der passenden Eingabekomponente das FormField. Auf diesem kann man nun den Wert setzen.

Viele Grüße

Rouven

0 Kudos

Hallo,

vielen dank für die Antwort.

Leider kann ich damit noch nicht viel anfangen. In meinem Beispiel oben lege ich ja eine Spalte an.

_attributeName='Spalte1'

_attributeName2='Spalte2'

entityType.createSimpleAttribute(_attributeName, String.class);

entityType.createSimpleAttribute(_attributeName2, String.class);

In dieser Spalte "Spalte1" und "Spalte2" und möchte ich jetzt gerne erstmal Dummy Werte schreiben, wie z.B. wert1="Dummy1", wert2="Dummy2". Hierdurch weiß ich dann schonmal, wie ich in eine Zeile in die Datenbank schreibe, oder auch lesen könnte.

Gibts dafür keine Beispiele von FS?

Gruß

Daniel

0 Kudos

Hallo Daniel,

gibt es in der Tabellenvorlage eine Eingabekomponente, die auf dieses Attribut gemappt ist?

Wenn ja, dann lässt sich das genauso machen, wie oben beschrieben.

In diesem Beitrag gibt es Code, der als Anregung dienen kann: (über die Suche sollten noch weitere Beiträge zum Arbeiten mit Datensätzen und Content2 zu finden sein)

https://community.e-spirit.com/message/8834#8834

Wenn nein, dann kann man über Entity.setValue() den Wert setzen.

Vorzugsweise sollte der erste Weg gegangen werden, da er der offiziell empfohlene und elegantere Weg ist. Hierfür kann überlegt werden die Tabellenvorlage entsprechend anzupassen, damit es eine enstprechende Eingabekomponente gibt.

Viele Grüße

Rouven

0 Kudos

Hallo Rouven,

ich habe das jetzt mal ausprobiert und erhalte leider noch einen Fehler.

Die Variable cont ist immer Null bei mir.

Die Datenbank-Struktur ist im Anhang vorhanden.

Der Code sieht wie folgt aus:

public void test() throws IOException,
   MaximumNumberOfSessionsExceededException, AuthenticationException {
   // FirstSpirit server hostname
   String host = "localhost";

   // FirstSpirit server http port
   // the default is port 8000, training server runs on port 4200
   int port = 8000;

   // FirstSpirit server login name
   String login = "123";

   // FirstSpirit server password
   String password = "123";

   // FirstSpirit project to connect to

   String projectName = "Entwicklung";

   Project project = null;
   UserService us = null;
   Connection connection = ConnectionManager.getConnection(host, port,
   ConnectionManager.HTTP_MODE, login, password);
   try {

   // print out info
   System.out.println("Connecting to server " + host + " at port "
   + port + ".");

   // connect to server
   connection.connect();

   // print out info
   System.out.println("Connected.");

   // get the project
   project = connection.getProjectByName(projectName);
   // print out info
   System.out.println("Got project " + project.getId() + "("
   + projectName + ")");
   System.out.println("Executing script(s)...");

   us = project.getUserService();
   } catch (Exception e) {
   e.printStackTrace();

   }
   Language lang = project.getMasterLanguage();

   ContentStoreRoot contentStore = (ContentStoreRoot) us.getStore(
   Store.Type.CONTENTSTORE, false);
   Content2 cont = (Content2) contentStore.getStoreElement(
   "pressreleases", IDProvider.UidType.CONTENTSTORE);
   // Hier ist cont immer leer.

   EntityType entityType = cont.getEntityType();
   Session sess = cont.getSchema().getSession();

   try {

   for (int i = 1; i < 1001; i++) {
   Entity ent = sess.createEntity(entityType.toString());
   Dataset d = cont.getDataset(ent);
   FormData fd = d.getFormData();
   fd.get(lang, "cs_title").set("cs_title" + i);
   fd.get(lang, "cs_subheadline").set("Subheadline_" + i);
   d.setFormData(fd);
   System.out.println("Created Entity number " + i);
   if (i % 100 == 0) {
   sess.commit();
   }
   }
   } catch (Exception e) {
   e.printStackTrace();
   throw new RuntimeException(e);
   } finally {
   try {
   System.out.println("Spalte angelegt.");
   } catch (Exception ignore) {
   // catch exception
   }
   }

    }

Als Fehlermeldung erhalte ich eine NullPointerException

Exception in thread "main" java.lang.NullPointerException

    at EintraegeBearbeiten.test(EintraegeBearbeiten.java:113)

    at Test.main(Test.java:73)

0 Kudos
gockel
Crownpeak employee

Dann gibt es wohl kein Content2 Objekt (Datenquelle) mit der UID 'pressreleases' in dem Projekt 'Entwicklung' ganz abgesehen davon, dass hier wieder nicht die Konstante des Interfaces Content2#UID_TYPE verwendet wird (siehe auch meinen Post oben).