<component-import key="ao" interface="com.atlassian.activeobjects.external.ActiveObjects"/>
<component key="appLifecycle" class="com.teknologiaplaneetta.confluence.grideditor.Servlets.AppLifecycle" interface="com.atlassian.sal.api.lifecycle.LifecycleAware" public="true"/>
<ao key="ao-module">
<description>The module configuring the Active Objects service used by this plugin for Tasks</description>
<entity>com.teknologiaplaneetta.confluence.grideditor.Servlets.Status</entity>
<entity>com.teknologiaplaneetta.confluence.grideditor.Servlets.Timesheet</entity>
<entity>com.teknologiaplaneetta.confluence.grideditor.Servlets.Hours</entity>
</ao>
And these also:
package com.teknologiaplaneetta.confluence.grideditor.Servlets;
import com.atlassian.activeobjects.external.ActiveObjects;
import com.atlassian.sal.api.lifecycle.LifecycleAware;
import com.teknologiaplaneetta.confluence.grideditor.Servlets.LoadContentToStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AppLifecycle implements LifecycleAware {
private static final Logger log = LoggerFactory.getLogger(AppLifecycle.class);
private final ActiveObjects ao;
public AppLifecycle(ActiveObjects ao) {
this.ao = ao;
}
@Override
public void onStart() {
log.info("AppLifecycle onStart method called");
LoadContentToStatus loader = new LoadContentToStatus(ao);
loader.importDataToStatus();
}
}
package com.teknologiaplaneetta.confluence.grideditor.Servlets;
import java.util.ArrayList;
import java.util.List;
import com.atlassian.activeobjects.external.ActiveObjects;
import net.java.ao.Query;
import com.teknologiaplaneetta.confluence.grideditor.Servlets.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoadContentToStatus {
private static final Logger log = LoggerFactory.getLogger(LoadContentToStatus.class);
private final ActiveObjects ao;
public LoadContentToStatus(ActiveObjects ao) {
this.ao = ao;
}
public void importDataToStatus() {
log.info("Importing data to Status table...");
// Assuming you have a method to get your data
List<String> titles = getDataFromDatabase();
for (String title : titles) {
try {
Status status = ao.create(Status.class);
status.setTitle(title);
status.save();
log.info("Saved Status entity with title: " + title);
} catch (Exception e) {
log.error("Error saving Status entity with title: " + title, e);
}
}
}
private List<String> getDataFromDatabase() {
List<String> statuses = new ArrayList<>();
statuses.add("Open");
statuses.add("In Progress");
statuses.add("Incomplete");
statuses.add("Complete");
return statuses;
}
}
Error:
2023-12-10 08:45:19,137 ERROR [lifecycle:thread-30] [confluence.grideditor.Servlets.LoadContentToStatus] importDataToStatus Error saving Status entity with title: Incomplete
-- url: /rest/plugins/1.0/installed-marketplace | userName: admin | referer: https://confluence.i4ware.fi/plugins/servlet/upm | traceId: 3e4a22247bfed511
java.lang.IllegalStateException: plugin [{com.teknologiaplaneetta.confluence.grideditor.agile-application-stack}] invoking ActiveObjects before <ao> configuration module is enabled or plugin is missing an <ao> configuration module. Note that scanning of entities from the ao.model package is no longer supported.
This is my Timesheet for Confluence plugin and I try to do custom database with Active Objects for Timesheet (Time-tracking toll for Atlassian Confluence which have nothing to do with Atlassian Jira). Active Objects works perfect bur when I try to import some content on my App installation to this custom Active Objects database table STATUS it not work after-all. I just try to import task statuses of Open, In Progress, Incomplete and Complete to this STATUS table.
Here is code that work only if STATUS table exist:
<ao key="ao-module">
<description>The module configuring the Active Objects service used by this plugin for Tasks</description>
<entity>com.teknologiaplaneetta.confluence.grideditor.Servlets.Status</entity>
<entity>com.teknologiaplaneetta.confluence.grideditor.Servlets.Timesheet</entity>
<entity>com.teknologiaplaneetta.confluence.grideditor.Servlets.Hours</entity>
<upgradeTask>com.teknologiaplaneetta.confluence.grideditor.Tasks.LoadContentToStatusTask</upgradeTask>
</ao>
package com.teknologiaplaneetta.confluence.grideditor.Tasks;
import com.atlassian.activeobjects.external.ActiveObjects;
import com.atlassian.activeobjects.external.ActiveObjectsUpgradeTask;
import com.atlassian.activeobjects.external.ModelVersion;
import com.teknologiaplaneetta.confluence.grideditor.Servlets.LoadContentToStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoadContentToStatusTask implements ActiveObjectsUpgradeTask {
private static final Logger log = LoggerFactory.getLogger(LoadContentToStatusTask.class);
@Override
public ModelVersion getModelVersion() {
return ModelVersion.valueOf("2");
}
@Override
public void upgrade(ModelVersion modelVersion, ActiveObjects activeObjects) {
log.info("Upgrading data to Status table...");
//System.err.println("Upgrading data to Status table...");
LoadContentToStatus loader = new LoadContentToStatus(activeObjects);
loader.importDataToStatus();
}
}
package com.teknologiaplaneetta.confluence.grideditor.Servlets;
import java.util.ArrayList;
import java.util.List;
import com.atlassian.activeobjects.external.ActiveObjects;
import net.java.ao.Query;
import com.teknologiaplaneetta.confluence.grideditor.Servlets.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoadContentToStatus {
private static final Logger log = LoggerFactory.getLogger(LoadContentToStatus.class);
private final ActiveObjects ao;
public LoadContentToStatus(ActiveObjects ao) {
this.ao = ao;
}
public void importDataToStatus() {
log.info("Importing data to Status table...");
// Assuming you have a method to get your data
List<String> titles = getDataFromDatabase();
for (String title : titles) {
try {
Status status = ao.create(Status.class);
status.setTitle(title);
status.save();
log.info("Saved Status entity with title: " + title);
} catch (Exception e) {
log.error("Error saving Status entity with title: " + title, e);
}
}
}
private List<String> getDataFromDatabase() {
List<String> statuses = new ArrayList<>();
statuses.add("Open");
statuses.add("In Progress");
statuses.add("Incomplete");
statuses.add("Complete");
return statuses;
}
}
Caused by: java.sql.SQLSyntaxErrorException: Table 'i4ware_confluence.AO_3D9901_STATUS' doesn't exist
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:121)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:912)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1054)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1003)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1312)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:988)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)
at net.java.ao.ForwardingPreparedStatement.executeUpdate(ForwardingPreparedStatement.java:45)
at net.java.ao.ParameterMetadataCachingPreparedStatement.executeUpdate(ParameterMetadataCachingPreparedStatement.java:10)
at net.java.ao.DatabaseProvider.executeInsertReturningKey(DatabaseProvider.java:1984)
at net.java.ao.DatabaseProvider.insertReturningKey(DatabaseProvider.java:1848)
at net.java.ao.EntityManager.create(EntityManager.java:399)
at com.atlassian.activeobjects.internal.EntityManagedActiveObjects.create(EntityManagedActiveObjects.java:93)
... 48 more
Where I put this after plugin enabled and AO status table created?