You can create a LiveCycle service managed transaction (SMT)
component that interacts with a relational database. A SMT component lets
you specify application logic within your LiveCycle component that
manages transactions. Transactions allow you to commit the result
of multiple SQL operations to a database as a single unit. This
action ensures that all operations complete successfully before
committing your data to the database.
Assume, for example, that a department manager updates an employee table
with new employee data. The manager also wants to update a contact
table with employee data. However, the manager does not want to
update the contact table without ensuring that the employee table
was updated. If the contact table is updated without the employee
table being updated, the data can become invalid. By using a transaction,
the Contact table cannot be updated without the Employee table
being successfully updated.
In addition to executing multiple SQL statements as a single
transaction, transactions also help ensure data integrity. When
using transactions, you can perform rollback operations. For example,
assume that an exception is thrown when the manager creates an employee
record. In this situation, a rollback operation can restore the
values to what they were before the exception was thrown. You can
add functionality in your SMT component to support rollback functionality.
Creating a SMT component is useful to replace a process that
performs separate database updates. Consider the following LiveCycle process that updates the Employee table
and the Contact table.
If an exception occurs when the Contact table
is updated, the update to the Employee table is
still made. To ensure that updates are committed only if all updates
are successfully committed, create your SMT component so that updates
are made in a single SQL transaction. That way, if any of the updates
fail, then the entire transaction can be rolled back.
To create a SMT component that manages transactions, you use
a Java API to programmatically interact with your enterprise database.
The Java classes used in Creating Transaction-Based Database Components belong
to the java.sql.* package. Like other custom components, there
are no required LiveCycle libraries required to create a
SMT component. The following illustration shows a SMT component
updating an enterprise database using transactions.
Note: A SMT component can perform database operations
such as creating records, retrieving records, updating records,
and deleting records.
The SMT component that is created updates the following tables
using a transaction:
The Employee table consists of the following fields:
EMPLOYEE_ID: An auto generated field that
serves as the primary key.
FIRST_NAME: A string value that stores the employee’s
first name.
LAST_NAME: A string value that stores the employee’s
last name.
EMAIL: A string value that stores the employee’s
e-mail address.
PHONE: A string value that stores the employee’s
phone number.
TITLE: A string value that stores the employee’s
job title.
COMPANY_ID: An integer value that stores
the identifier value of the company.
The Contact table consists of the following fields:
CONTACT_ID: An auto generated value that
serves as the primary key.
FIRST_NAME: A string value that stores the employee’s
first name.
LAST_NAME: A string value that stores the employee’s
last name.
EMAIL: A string value that stores the employee’s
e-mail address.
PHONE: A string value that stores the employee’s
phone number.
ADDRESS: A string value that stores the employee’s
address.
CITY: A string value that stores the city
in which the employee lives.
STATE: A string value that specifies the
state in which the employee lives.
ZIP: A string value that specifies the ZIP
code that belongs to the employee.
COUNTRY: A string value that specifies the country
in which the employee lives.
NOTES: A string value that specifies additional information
about the employee.
The SMT component created in Creating Transaction-Based Database Components updates
both of these tables in a single transaction. As a result, both
tables are updated or neither table is updated.
Note: The database used in Creating Transaction-Based
Database Components is an open source database named HSQLDB. For
information, see http://hsqldb.org/.
To follow along with the code examples, download the hsqldb database,
and create the Employee and Contact tables.
Important: If you create a SMT component that uses
another database, ensure that the database driver you use supports
transactions. Otherwise the SMT component cannot use transactions
to update a database.
Working with transactionsBy default, when a connection is established,
it is in auto-commit mode. That is, each SQL statement is handled
as a separate transaction and is committed after it is executed.
This means that the Employee table can be updated
while the Contact table is not. To satisfy the
requirements of the workflow introduced in Creating Transaction-Based Database Components,
both tables are updated or neither table is updated.
To disable
the auto-commit mode, create a java.sql.Connection object
and invoke its setAutoCommit method. Pass the value false,
as shown in the following code example.
//Perform updates to Contact table and Employee table as a single transaction
Class.forName("org.hsqldb.jdbcDriver");
// Specify an URL to MySQL
String url = "jdbc:hsqldb:hsql://localhost:9002/flexdemodb";
//Create a Connection object
java.sql.Connection con = DriverManager.getConnection(url);
//Set the auto-comment property to false - necessary to perform a transaction
con.setAutoCommit(false);
After the auto-commit mode
is set to false, SQL statements are not committed
until you invoke the java.sql.Connection object’s commit method.
The following code example shows Java application logic that updates
both the Employee table and Contact table
using a transaction.
try{
//Perform updates to Contact table and Employee table as a single transaction
Class.forName("org.hsqldb.jdbcDriver");
// Specify an URL to MySQL
String url = "jdbc:hsqldb:hsql://localhost:9002/flexdemodb";
// Create a Connection object
java.sql.Connection con = DriverManager.getConnection(url);
//set auto-comment to false - necessary to perform a transaction
con.setAutoCommit(false);
//Populates data fields required by both the Employee table and Contact table
String FIRST_NAME = "Tony"; // common to both tables
String LAST_NAME ="Blue"; //common to both tables
String EMAIL="tblue@noserver.com"; // common to both tables
String PHONE="555-555-5555"; // common to both tables
String TITLE ="Developer"; // required for employee table
int COMPANY_ID = 1; // required for employee table
String ADDRESS = "1 NoWhere Dr" ; //required for contact table
String CITY = "New York" ; //required for contact table
String STATE = "NY" ; //required for contact table
String ZIP = "55555" ; //required for contact table
String COUNTRY = "USA" ; //required for contact table
String Notes = "New Employee" ; //required for contact table
//Update the Employee table using a Prepared Statement
PreparedStatement psEmployee = con.prepareStatement(
"INSERT INTO employee " +
"(FIRST_NAME, LAST_NAME, EMAIL, PHONE, " +
"TITLE, COMPANY_ID) " +
"VALUES (?,?,?,?,?,?)");
//Set the field values
psEmployee.setString(1,FIRST_NAME);
psEmployee.setString(2,LAST_NAME);
psEmployee.setString(3,EMAIL);
psEmployee.setString(4,PHONE);
psEmployee.setString(5,TITLE);
psEmployee.setInt(6,COMPANY_ID);
//Update the Contact table using a Prepared Statement
PreparedStatement psContact = con.prepareStatement(
"INSERT INTO contact " +
"(FIRST_NAME, LAST_NAME, EMAIL, PHONE, " +
"ADDRESS, CITY,STATE,ZIP,COUNTRY,Notes) " +
"VALUES (?,?,?,?,?,?, ?,?,?,?)");
//Set the field values
psContact.setString(1,FIRST_NAME);
psContact.setString(2,LAST_NAME);
psContact.setString(3,EMAIL);
psContact.setString(4,PHONE);
psContact.setString(5,ADDRESS);
psContact.setString(6,CITY);
psContact.setString(7,STATE);
psContact.setString(8,ZIP);
psContact.setString(9,COUNTRY);
psContact.setString(10,Notes);
// Insert new employee record
psEmployee.executeUpdate();
// Insert new Contact record
psContact.executeUpdate();
//commit these updates to the database
con.commit();
con.close(); }
catch (Exception ee)
{
ee.printStackTrace();
}
Rolling back transactionsYou can add the ability to roll back
transactions within your SMT component. For example, assume that
an exception is thrown when an update is made. You can roll back
the transaction to restore database values. To roll back a transaction,
create a java.sql.Savepoint instance. Next, invoke
the java.sql.Connection object’s rollback method
and pass the java.sql.Savepoint instance.
The
following Java application logic updates the Employee and Contact tables.
If an exception is thrown, the transaction is roll backed.
public static void main(String[] args) {
java.sql.Connection con = null;
Savepoint mySavePoint = null;
try{
//Perform updates to Contact table and Employee table as a single transaction
Class.forName("org.hsqldb.jdbcDriver");
// Specify an URL to MySQL
String url = "jdbc:hsqldb:hsql://localhost:9002/flexdemodb";
// Create a Connection object
con = DriverManager.getConnection(url);
//set auto-comment to false - necessary to perform a transaction
con.setAutoCommit(false);
//Populates data fields required by both the Employee table and Contact table
String FIRST_NAME = "Tony"; // common to both tables
String LAST_NAME ="Blue"; //common to both tables
String EMAIL="tblue@noserver.com"; // common to both tables
String PHONE="555-555-5555"; // common to both tables
String TITLE ="Developer"; // required for employee table
int COMPANY_ID = 1; // required for employee table
String ADDRESS = "1 NoWhere Dr" ; //required for contact table
String CITY = "New York" ; //required for contact table
String STATE = "NY" ; //required for contact table
String ZIP = "55555" ; //required for contact table
String COUNTRY = "USA" ; //required for contact table
Sring Notes = "New Employee" ; //required for contact table
// set a savepoint
mySavePoint = con.setSavepoint("sp1");
//Update the Employee table using a Prepared Statement
PreparedStatement psEmployee = con.prepareStatement(
"INSERT INTO employee " +
"(FIRST_NAME, LAST_NAME, EMAIL, PHONE, " +
"TITLE, COMPANY_ID) " +
"VALUES (?,?,?,?,?,?)");
//Set the field values
psEmployee.setString(1,FIRST_NAME);
psEmployee.setString(2,LAST_NAME);
psEmployee.setString(3,EMAIL);
psEmployee.setString(4,PHONE);
psEmployee.setString(5,TITLE);
psEmployee.setInt(6,COMPANY_ID);
//Update the Contact table using a Prepared Statement
PreparedStatement psContact = con.prepareStatement(
"INSERT INTO contact " +
"(FIRST_NAME, LAST_NAME, EMAIL, PHONE, " +
"ADDRESS, CITY,STATE,ZIP,COUNTRY,Notes) " +
"VALUES (?,?,?,?,?,?, ?,?,?,?)");
//Set the field values
psContact.setString(1,FIRST_NAME);
psContact.setString(2,LAST_NAME);
psContact.setString(3,EMAIL);
psContact.setString(4,PHONE);
psContact.setString(5,ADDRESS);
psContact.setString(6,CITY);
psContact.setString(7,STATE);
psContact.setString(8,ZIP);
psContact.setString(9,COUNTRY);
psContact.setString(10,Notes);
// Insert new employee record
psEmployee.executeUpdate();
// Insert new Contact record
psContact.executeUpdate();
//commit these updates to the database
con.commit();
con.close(); }
}
//If an exception is thrown during the update - roll back the transaction
catch (Exception ee)
{
try
{
ee.printStackTrace();
//Rollback the transaction
con.rollback(mySavePoint);
con.close();
}
catch (Exception ex1)
{
ex1.printStackTrace();
}
}
}
}
Note: The SMT component created in Creating
Transaction-Based Database Components uses this application logic
to update the Employee and Contact tables. The difference is that
the data values are passed in as input parameters for the SMT component
as opposed to being hard coded.
Summary of stepsTo develop a LiveCycle SMT component,
perform the following steps:
Set up your development
environment.
Create your application logic.
Define the component XML file.
Deploy the component to LiveCycle.
Test your component.
After you deploy a SMT
component to LiveCycle, you can use it to create a process
using Workbench. You can also invoke the component’s services by
using an invocation method such as the Java API, (Deprecated for AEM forms) LiveCycle Remoting,
or web services. For information about invoking services, see Service container.
Setting up your development environment to create the SMT componentThe first step to create a SMT component is to set up your
development environment by creating an Eclipse Java project. The
version of Eclipse that is supported is 3.2.1 or later.
The SMT component created in Creating Transaction-Based Database Components updates
an open source database named HSQLDB. To successfully update
this database using a SMT component, add the hsqldb.jar file to
your project’s class path. This JAR file can be retrieved from the
HSQLDB database install directory. For information, see http://hsqldb.org/.
Creating application logic to create the SMT componentDefine the DatabaseTransaction interfaceA service implementation is a Plain Old Java Object (POJO)
that you develop by creating a Java interface. This interface defines
the service’s operations (public methods), input values, and return
values. The public methods that are defined within the Java interface
become operations that the service exposes. You do not need to implement
any Adobe-specific Java libraries when creating a service interface.
The SMT component that is developed exposes an operation named UpdateDatabase that
is defined in the component interface. The following Java code example
shows the DatabaseTransaction interface.
package com.adobe.sample.database;
public interface DatabaseTransaction{
//Create an operation to update the Employee and Contact tables
public int UpdateDatabase(
String firstName,// common to both tables
String lastName, //common to both tables
String email, // common to both tables
String phone, // common to both tables
String title, // required for the employee table
String compId,// required for the employee table
String address,//required for the contact table
String city, //required for the contact table
String state, //required for the contact table
String zip, //required for the contact table
String country, //required for the contact table
String notes); //required for the contact table
}
The DatabaseTransaction interface belongs to
a package named com.adobe.sample.database.
Defining the DatabaseTransactionImpl classCreate a service implementation class that implements DatabaseTransaction.
A service implementation conforms to the following restrictions:
The implementation class must have a public no-argument constructor.
The service implementation class must be stateless.
Input parameters, output parameters, and exceptions must
be serializable.
The business logic that LiveCycle executes when the operation
is invoked must be specified in the corresponding methods. For example,
consider the UpdateDatabase method that is defined
in the DatabaseTransaction interface. Create business
logic within the UpdateDatabase method that updates
the HSQLDB database using transactions.
The UpdateDatabase method requires the following
string arguments:
firstName: Specifies the first name
of the employee.
lastName: Specifies the last name of the employee.
email: Specifies the email address of the employee.
phone: Specifies the phone number of the employee.
title: Specifies the job title of the employee.
compId: Specifies the company identifier value.
address: Specifies the address of the employee.
city: Specifies the city in which the employee lives.
state: Specifies the state in which the employee
lives.
zip: Specifies the zip code of the employee.
country: Specifies the country in which
the employee lives.
notes: Specifies additional information associated
with the employee.
The following Java code shows the Java implementation class named DatabaseTransactionImpl that
implements DatabaseTransaction. Notice that this
class is located within a Java package named com.adobe.sample.database.
The UpdateDatabase method returns the value 1 if
the update was successful. If an exception was thrown and a rollback
operation occurred, this method returns the value -1.
package com.adobe.sample.database;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Savepoint;
public class DatabaseTransactionImpl implements DatabaseTransaction {
public int UpdateDatabase(String firstName, String lastName, String email,
String phone, String title, String compId, String address,
String city, String state, String zip, String country, String notes) {
//Declare a Connection and Sharepoint object
java.sql.Connection con = null;
Savepoint mySavePoint = null;
//Create a return value that indicates if the operation was successful
int returnVal = 0;
try{
//Perform updates to Contact table and Employee table as a single transaction
Class.forName("org.hsqldb.jdbcDriver");
// Specify an URL to the HSQLDB database
String url = "jdbc:hsqldb:hsql://scottm-xp:9002/flexdemodb";
// Create a Connection object
con = DriverManager.getConnection(url);
//set auto-comment to false - necessary to perform a transaction
con.setAutoCommit(false);
//Populates data fields required by both the Employee table and Contact table
String FIRST_NAME = firstName; // common to both tables
String LAST_NAME = lastName; //common to both tables
String EMAIL=email; // common to both tables
String PHONE=phone; // common to both tables
String TITLE =title; // required for employee table
int COMPANY_ID = Integer.parseInt(compId); // required for employee table
String ADDRESS = address ; //required for contact table
String CITY = city; //required for contact table
String STATE = state ; //required for contact table
String ZIP = zip ; //required for contact table
String COUNTRY = country ; //required for contact table
String Notes = notes ; //required for contact table
// set a savepoint
mySavePoint = con.setSavepoint("sp1");
//Update the Employee table using a Prepared Statement
PreparedStatement psEmployee = con.prepareStatement(
"INSERT INTO employee " +
"(FIRST_NAME, LAST_NAME, EMAIL, PHONE, " +
"TITLE, COMPANY_ID) " +
"VALUES (?,?,?,?,?,?)");
//Set the field values
psEmployee.setString(1,FIRST_NAME);
psEmployee.setString(2,LAST_NAME);
psEmployee.setString(3,EMAIL);
psEmployee.setString(4,PHONE);
psEmployee.setString(5,TITLE);
psEmployee.setInt(6,COMPANY_ID);
//Update the Contact table using a Prepared Statement
PreparedStatement psContact = con.prepareStatement(
"INSERT INTO contact " +
"(FIRST_NAME, LAST_NAME, EMAIL, PHONE, " +
"ADDRESS, CITY,STATE,ZIP,COUNTRY,Notes) " +
"VALUES (?,?,?,?,?,?, ?,?,?,?)");
//Set the field values
psContact.setString(1,FIRST_NAME);
psContact.setString(2,LAST_NAME);
psContact.setString(3,EMAIL);
psContact.setString(4,PHONE);
psContact.setString(5,ADDRESS);
psContact.setString(6,CITY);
psContact.setString(7,STATE);
psContact.setString(8,ZIP);
psContact.setString(9,COUNTRY);
psContact.setString(10,Notes);
// Insert new employee record
psEmployee.executeUpdate();
// Insert new Contact record
psContact.executeUpdate();
//commit these updates to the database
con.commit();
con.close();
returnVal = 1;
}
//If an exception is thrown during the update - roll back the transaction
catch (Exception ee)
{
try
{
ee.printStackTrace();
//Rollback the transaction
con.rollback(mySavePoint);
con.close();
returnVal = -1;
return returnVal;
}
catch (Exception ex1)
{
ex1.printStackTrace();
}
}
return returnVal;
}
}
Defining the component XML file for the SMT componentYou create a component XML file to deploy a SMT component
to LiveCycle. A component XML file exists for each component
and provides metadata about the component. You can use the component
XML file to customize your component to meet your requirements.
For example, you can specify an icon that is visible to Workbench
users who build processes using the SMT component.
LiveCycle supports three transaction values:
Container: a LiveCycle operation expects the
service container to automatically manage the start, commit, and
rollback of the transaction. When using this value, you do not need
to create application logic to manage the transaction.
Service: a LiveCycle operation manages its
own transactions. You can create application logic within the custom
component that manages the transaction. The component created in Creating Transaction-Based Database Components demonstrates
how to create application logic to manage transactions. This value
is used to craete a SMT component.
None: a LiveCycle operation has no transactional requirements
(this is the default value).
Note: A transaction value is specified within a the
component XML file’s transaction-type element. For information about
this element as well as other elements, see the Component XML Reference.
The component XML file that is used for the SMT component contains
the following XML elements:
component-id: Specifies a unique identifier value
for the component.
version: Specifies the component version.
class-path: Specifies JAR files that the component
requires. JAR files must be specified within this element for a
component to use them. For example, because the hsqldb.jar is required
to update a hsqldb database, add this JAR to this XML element.
services: Specifies the services that are part of
this component. This element can contain one or many service elements.
For a single service component, specify one service element.
service: Specifies the name of the service. For example,
you can specify DatabaseTransactionService.
implementation-class: Specifies the name of the implementation
class for the service.
operations: Specifies the operations that are part
of this service. This element can contain one or many operation elements.
operation: Specifies the operation name. For example,
you can specify UpdateDatabase.
input-parameter: Specifies the name and type of the
input parameter for this specified operation. An input parameter
element must exist for each parameter that corresponds to the operation.
Also, each parameter’s data type must be specified using the type attribute.
output-parameter: Specifies the name and type of the output
parameter for this specified operation.
transaction-type: Specifies the LiveCycle transaction support. Supported values are Container, Service,
and None.
The following component.xml file is used for the SMT component.
Notice that the service name is DatabaseTransactionService and
the transaction-type element is Service.
<component xmlns="http://adobe.com/idp/dsc/component/document">
<!-- Unique id identifying this component -->
<component-id>com.adobe.sample.database.DatabaseComponent</component-id>
<!-- Version -->
<version>1.0</version>
<class-path>hsqldb.jar</class-path>
<!-- Start of the Service definition -->
<services>
<!-- Unique name for service descriptor.
The value is used as the default name for
deployed services -->
<service name="DatabaseTransactionService">
<!-- service implementation class definition -->
<implementation-class>com.adobe.sample.database.DatabaseTransactionImpl</implementation-class>
<!-- description -->
<description>Updates the Employee and Contact tables using a transaction</description>
<!-- automatically deploys the service and starts it after installation -->
<auto-deploy service-id="DatabaseTransactionService" />
<operations>
<operation name="UpdateDatabase">
<input-parameter name="firstName" title="firstName" type="java.lang.String"></input-parameter>
<input-parameter name="lastName" title="lastName" type="java.lang.String"></input-parameter>
<input-parameter name="email" title="email" type="java.lang.String"></input-parameter>
<input-parameter name="phone" title="phone" type="java.lang.String"></input-parameter>
<input-parameter name="title" title="title" type="java.lang.String"></input-parameter>
<input-parameter name="compId" title="compId" type="java.lang.String"></input-parameter>
<input-parameter name="address" title="address" type="java.lang.String"></input-parameter>
<input-parameter name="city" title="city" type="java.lang.String"></input-parameter>
<input-parameter name="state" title="state" type="java.lang.String"></input-parameter>
<input-parameter name="zip" title="zip" type="java.lang.String"></input-parameter>
<input-parameter name="country" title="country" type="java.lang.String"></input-parameter>
<input-parameter name="notes" title="notes" type="java.lang.String"></input-parameter>
<output-parameter name="outValue" title="outValue" type="java.lang.Integer"></output-parameter>
<transaction-type>Service</transaction-type>
<faults>
<fault name="Exception" type="java.lang.Exception"/>
</faults>
</operation>
</operations>
</service>
</services>
</component>
Deploying your SMT componentAfter you finish creating your SMT component, package it
into a JAR file and then deploy it to LiveCycle.
Packaging the SMT component into a JAR fileTo deploy the SMT component to LiveCycle, package
your Eclipse project into a JAR file. Ensure that external JAR files
that the component’s business logic depends on, such as hsqldb.jar
(applicable to this SMT component), are also included. As well,
the component XML file must be present. The component.xml file and
external JAR files must be located at the root of the JAR file.
The following illustration shows the Eclipse project’s content,
which is packaged into the component’s JAR file.
Note: In the previous illustration, notice that JAVA
files are listed. Once packaged into a JAR file, the corresponding
CLASS files are also part of the component JAR file. Without the
CLASS files, the component does not work. Also, ensure that the
compression option is turned off.
Deploying the SMT componentYou can use Workbench to deploy the SMT component by performing
the following steps:
Start Workbench.
Log in to Workbench.
Select Window,Show Views, Components.
This action adds the Components view to Workbench.
Right-click the Components icon and select Install Component.
Select the JAR file that represents your component by using
the file browser and click Open.
Notice that there
is a red square next to the new com.adobe.sample.database.DatabaseTransactionService.
Expand com.adobe.sample.database.DatabaseTransactionService.
Select Service Descriptors, and then right-click DatabaseTransactionService and
select Activate Service.
Right-click on the component name and select Start Component.
Expand the Active Services and right-click DatabaseTransactionService and
select Start Component. A green arrow appears next to the
name if it succeeds.
Testing your SMT componentAfter you deploy the SMT component to LiveCycle,
you can create a process by using Workbench or you can programmatically
invoke it.
Note: The SMP component created in this section will
work with LiveCycle ES 8.x versions. However, to build a process
that uses the component, consult the documentation that corresponds
to your Workbench version.
Creating a process using the SMT componentThe following illustration shows a process named MyApplication/UpdateHSQLDatabase that updates
the Employee and Contact tables
by using the SMT component.
The following illustration shows the property editor that lets
you specify input values that the SMT component requires.
Notice that these input values correspond to the parameters that
belong to the UpdateDatabase method that is defined
in the DatabaseTransaction interface. For information,
see Define the DatabaseTransaction interface.
These values are string process variables that you specify when
you invoke the process. To create a process that uses the SMT component,
perform the following steps in Workbench:
Start Workbench.
Under the Application tab in Workbench, select MyApplication.
Right click and select New > Process.
In the New Process dialog box, specify UpdateHSQLDatabase for
the process name and click Finish.
Using the Activity picker, select the SetValue operation.
Create a string process variable for each input parameter defined by
the UpdateDatabase operation.
Using the Activity picker, select the UpdateDatabase operation
that belongs to DatabaseTransactionService.
Click the Process Properties tab. Under the Input
option, there are default property-editors for each input parameter.
Select the process variable that corresponds to the input parameter.
Assign a process variable for each input parameter.
Create an output process variable to handle the return value
of the UpdateDatabase method. Ensure that the data
type for the output variable is int. Under the Output option, specify
the output process variable in the OutValue field.
Under the Application tab in Workbench, select MyApplication.
Right click and select Deploy.
Invoke the process from within Workbench by selecting MyApplication/UpdateHSQLDatabase.
Right click and select invoke.
In the Check In Assets dialog box, select Check in all files
and click OK.
Specify input parameter values for the fields and click OK.
If the updates are made, the value 1 is returned. If an exception
is thrown and a rollback occurs, the value -1 is returned.
Note: For information creating processes using Workbench,
see Using Workbench.
Invoking the SMT component using the Java Invocation APIYou can programmatically invoke the DatabaseTransactionService (which
belongs to the SMT component) by using the Java API. That is, you
can invoke the UpdateDatabase operation by using
the Java Invocation API. For more information, see Invoking LiveCycle using the Java API.
You can invoke the DatabaseTransactionService defined
in the SMT component by performing the following tasks:
Include client JAR files, such as the adobe-livecycle-client.jar,
in your Java project’s class path. For information about the location
of these files, see Including LiveCycle Java library files.
Set connection properties that are required to invoke a service.
For information, see Setting connection properties.
Create a ServiceClientFactory object by
invoking the ServiceClientFactory object’s static createInstance method
and passing the java.util.Properties object that
contains connection properties. A ServiceClientFactory object
is a Java singleton responsible for creating a ServiceClient instance
and maintaining connection settings.
Create a ServiceClient object by invoking the ServiceClientFactory object’s getServiceClient method.
A ServiceClient object lets you invoke a service operation.
It handles tasks such as locating, dispatching, and routing invocation
requests.
Create a java.util.HashMap object.
Invoke the java.util.HashMap object’s put method
for each parameter required to execute the service. You invoke this
method 12 times to correspond to the parameters specified in the UpdateDatabase method
that is defined in the DatabaseTransaction interface.
For information, see Define the DatabaseTransaction interface.
Create an InvocationRequest object by invoking
the ServiceClientFactory object’s createInvocationRequest method
and passing the following values:
A string value that
specifies DatabaseTransactionService (the name
of the service to invoke).
A string value that specifies UpdateDatabase (the
name of the operation to invoke).
The java.util.HashMap object that contains
the parameter values that the service operation requires.
A Boolean value where the value true creates
a synchronous request and the value false creates
an asynchronous request. Pass the value true.
Send the invocation request to the service by invoking the ServiceClient object’s invoke method
and passing the InvocationRequest object.
Retrieve the return value of the invoke method.
This method returns an instance of com.adobe.idp.dsc.InvocationResponse.
Retrieve the return value of the UpdateDatabase operation
by invoking the InvocationResponse object’s getParameter method.
Pass the string value outValue, which corresponds
to the name of the return value as specified in the component XML
file. The data type of this value is java.lang.Integer.
Ensure that you cast the return value to java.lang.Integer.
The following Java example invokes the UpdateDatabase operation
that belongs to the DatabaseTransactionService by
using the Java invocation API. If the value 1 is returned, the update
to the Employee and Contact tables
was successfully performed. If the value -1 was returned, the updates
were not made to these tables and a rollback operation was performed.
package com.adobe.update.database;
import com.adobe.idp.dsc.InvocationRequest;
import com.adobe.idp.dsc.InvocationResponse;
import com.adobe.idp.dsc.clientsdk.ServiceClientFactory;
import com.adobe.idp.dsc.clientsdk.ServiceClient;
import com.adobe.idp.dsc.clientsdk.ServiceClientFactoryProperties;
import java.util.Properties;
import java.util.Map;
import java.util.HashMap;
public class InvokeDatabaseTransactionService {
public static void main(String[] args) {
try{
//Set connection properties required to invoke LiveCycle
Properties connectionProps = new Properties();
connectionProps.setProperty(ServiceClientFactoryProperties.DSC_DEFAULT_EJB_ENDPOINT, "jnp://hiro-xp:1099");
connectionProps.setProperty(ServiceClientFactoryProperties.DSC_TRANSPORT_PROTOCOL,ServiceClientFactoryProperties.DSC_EJB_PROTOCOL);
connectionProps.setProperty(ServiceClientFactoryProperties.DSC_SERVER_TYPE, "JBoss");
connectionProps.setProperty(ServiceClientFactoryProperties.DSC_CREDENTIAL_USERNAME, "administrator");
connectionProps.setProperty(ServiceClientFactoryProperties.DSC_CREDENTIAL_PASSWORD, "password");
//Create a ServiceClientFactory object
ServiceClientFactory myFactory = ServiceClientFactory.createInstance(connectionProps);
//Create a ServiceClient object
ServiceClient myServiceClient = myFactory.getServiceClient();
//Create a Map object to store the parameter value
Map params = new HashMap();
//Populate the Map object with parameter values
//required to invoke the UpdateDatabase operation
params.put("firstName", "Tony");
params.put("lastName", "Blue");
params.put("email","tblue@nomailserver.com");
params.put("phone", "555-555-5555");
params.put("title", "Developer");
params.put("compId", "10");
params.put("address", "1 NoWhere Dr");
params.put("city", "New York");
params.put("state", "NY");
params.put("zip", "55555");
params.put("country", "USA");
params.put("notes", "New Employee");
//Create an InvocationRequest object
InvocationRequest request = myFactory.createInvocationRequest(
"DatabaseTransactionService", //Specify the service name
"UpdateDatabase", //Specify the operation name
params, //Specify input values
true); //Create a synchronous request
//Send the invocation request and get back the response
InvocationResponse resp = myServiceClient.invoke(request);
java.lang.Integer updateStatus = (java.lang.Integer)resp.getOutputParameter("outValue");
int intVal = updateStatus.intValue();
if (intVal == 1)
System.out.println("The updates were successfully made");
else
System.out.println("The updates were not made - a rollback was performed");
}catch (Exception e) {
e.printStackTrace();
}
}
}
|
|
|