Oracle8i Application Developer's Guide - Advanced Queuing Release 2 (8.1.6) Part Number A76938-01 |
|
Creating Applications Using JMS , 3 of 8
A ConnectionFactory
encapsulates a set of connection configuration parameters that has been defined by an administrator. A client uses it to create a Connection with a JMS provider. In this case Oracle JMS, Oracle8i is the JMS Provider.
There are two types of ConnectionFactory
objects
The AQjmsFactory
class can be used to obtain a handle to Queue/Topic
ConnectionFactory
objects.
QueueConnectionFactory
To obtain a queue connection factory, use
AQjmsFactory.getQueueConnectionFactory(...)
The queue connection factory can be created using hostname, port number, SID driver or by using JDBC URL and properties.
TopicConnectionFactory
To obtain a topic connection factory, use
AQjmsFactory.getTopicConnectionFactory(...)
The topic connection factory can be created using hostname, port number, SID driver or by using JDBC URL and properties.
A connection to the database can be created by invoking
createQueueConnection(...) createTopicConnection(...)
and passing the parameters username and password on the QueueConnection- Factory
and TopicConnectionFactory
object respectively.
A JMS Connection is a client's active connection to its JMS provider. A Connection performs several critical services:
A JMS client typically creates a Connection
, Session
and a number of MessageProducers
and MessageConsumers
. In the current version only one open session per connection is allowed.
When a Connection is created it is in stopped mode. In this state no messages can be delivered to it. It is typical to leave the Connection in stopped mode until setup is complete. At that point the Connection's start()
method is called and messages begin arriving at the Connection's consumers. This setup convention minimizes any client confusion that may result from asynchronous message delivery while the client is still in the process of setup.
It is possible to start a Connection and to perform setup subsequently. Clients that do this must be prepared to handle asynchronous message delivery while they are still in the process of setting up. A MessageProducer
can send messages while a Connection is stopped.
Some of the methods that are supported on the Connection object are
start()
- start, or restart, a Connection's delivery of incoming messages.
stop()
- Used to temporarily stop a Connection's delivery of incoming messages. When stopped, delivery to all the Connection's message consumers is inhibited. Also, synchronous receive's block and messages are not delivered to message listener
close()
- close the JMS session and release all associated resources
createQueueSession(true,
0)
- create a queue session. Currently only transacted sessions are allowed.
createTopicSession
(true,
0
) - create a topic session. Currently only transacted sessions are allowed.
A Connection is a factory for Sessions that use its underlying connection to a JMS provider for producing and consuming messages. A JMS Session is a single threaded context for producing and consuming messages. Although it may allocate provider resources outside the Java virtual machine, it is considered a light-weight JMS object.
A Session servrs several purposes:
MessageProducer
s and MessageConsumers
.
MessageListener
s registered with it.
Only one session can be created from one connection. Since a provider may allocate some resources on behalf of a session outside the JVM, clients should close them when they are not needed. Relying on garbage collection to eventually reclaim these resources may not be timely enough. The same is true for the MessageProducers
and MessageConsumer
s created by a session.
Methods on the Session object include:
commit()
- commits all messages performed in this transaction and releases locks currently held
rollback()
- rollsback any messages done in the transaction and release locks currently held
close()
- closes the session
getDBConnection(
...)
- gets a handle to the underlying JDBC connection. This handle can be used to perform other SQL DML operations as part of the same session. The method is Oracle JMS specific.
The following are some of the extensions to JMS made by Oracle. The Session
object has to be cast to AQjmsSession
to use any of the extensions.
QueueTables
and Queues, Topics can be created from the Session object
createQueueTable(
...)
- creates a queuetable
getQueueTable(
...)
- gets a handle to an existing queue table
createQueue(
...)
- creates a Queue
getQueue(
...)
- gets a handle to an existing queue
createTopic(
...)
- creates a topic
getTopic(
...)
- gets a handle to an existing topic
The following code illustrates how some of the above mentioned calls are used.
public static void bol_example(String ora_sid, String host, int port, String driver) { QueueConnectionFactory qc_fact = null; QueueConnection q_conn = null; QueueSession q_sess = null; AQQueueTableProperty qt_prop = null; AQQueueTable q_table = null; AQjmsDestinationProperty dest_prop = null; Queue queue = null; BytesMessage bytes_msg = null; try { /* get queue connection factory */ qc_fact = AQjmsFactory.getQueueConnectionFactory(host, ora_sid, port, driver); /* create queue connection */ q_conn = qc_fact.createQueueConnection("boluser", "boluser"); /* create queue session */ q_sess = q_conn.createQueueSession(true, Session.CLIENT_ACKNOWLEDGE); /* start the queue connection */ q_conn.start(); qt_prop = new AQQueueTableProperty("SYS.AQ$_JMS_BYTES_MESSAGE"); /* create a queue table */ q_table = ((AQjmsSession)q_sess).createQueueTable("boluser", "bol_ship_queue_table", qt_prop); dest_prop = new AQjmsDestinationProperty(); /* create a queue */ queue = ((AQjmsSession)q_sess).createQueue(q_table, "bol_ship_queue", dest_prop); /* start the queue */ ((AQjmsDestination)queue).start(q_sess, true, true); /* create a bytes message */ bytes_msg = q_sess.createBytesMessage(); /* close session */ q_sess.close(); /* close connection */ q_conn.close(); } catch (Exception ex) { System.out.println("Exception: " + ex); } }
Destination
is an object a client uses to specify the destination to which it sends messages, and the source from which it receives messages. Destination
objects are created from a Session
object using domain specific session methods. Destination
objects support concurrent use.
There are two types of destination objects - Queue
and Topic
. In AQ, these would map to a <schema>.<queue>
at a specific database: Queue
maps to Single consumer queue in AQ and Topic
maps to multiconsumer queue in AQ.
Methods on the Destination Object include:
alter(
...)
- alters a queue or topic
schedulePropagation(
...)
- schedules propagation from a source to a destination
unschedulePropagation(
...)
- unschedules a previously scheduled propagation
enablePropagationSchedule (
...)
- enable a propagation schedule
disablePropagationSchedule (
...)
- disable a propagation schedule
start()
- starts a queue or a topic.The queue can be started for enqueue and/or dequeue. The topic can be started for published and/or subscribe.
stop()
- stops a queue or a topic. The queue is stopped for enqueue and/or dequeue. The topic is stopped for publish and/or subscribe.
drop()
- drops a queue or a topic
public static void setup_example(TopicSession t_sess) { AQQueueTableProperty qt_prop = null; AQQueueTable q_table = null; AQjmsDestinationProperty dest_prop = null; Topic topic = null; TopicConnection t_conn = null; try { qt_prop = new AQQueueTableProperty("SYS.AQ$_JMS_BYTES_MESSAGE"); /* create a queue table */ q_table = ((AQjmsSession)t_sess).createQueueTable("boluser", "bol_ship_queue_table", qt_prop); dest_prop = new AQjmsDestinationProperty(); /* create a topic */ topic = ((AQjmsSession)t_sess).createTopic(q_table, "bol_ship_queue", dest_prop); /* start the topic */ ((AQjmsDestination)topic).start(t_sess, true, true); /* schedule propagation from topic "boluser" to the destination dblink "dba" */ ((AQjmsDestination)topic).schedulePropagation(t_sess, "dba", null, null, null, null); /* some processing done here */ /* Unschedule propagation */ ((AQjmsDestination)topic).unschedulePropagation(t_sess, "dba"); /* stop the topic */ ((AQjmsDestination)topic).stop(t_sess, true, true, true); /* drop topic */ ((AQjmsDestination)topic).drop(t_sess); /* drop queue table */ q_table.drop(true); /* close session */ t_sess.close(); /* close connection */ t_conn.close(); } catch(Exception ex) { System.out.println("Exception: " + ex); } }
Oracle8i supports system level access control for all queueing operations. This feature allows application designer or DBA to create users as queue administrators. A queue/topic administrator can invoke all JMS interface (both administration and operation) on any queue in the database. This simplify the administrative work as all administrative scripts for the queues in a database can be managed under one schema, for more information, see:"Security" in Chapter 4, "Managing AQ".
In the BooksOnLine (BOL) application, the DBA creates BOLADM
, the BooksOnLine
Administrator account, as the queue administrator of the database. This allows BOLADM
to create, drop, manage, and monitor any queues in the database.If you decide to create PL/SQL packages in the BOLADM schema that can be used by any applications to enqueue or dequeue, then you should also grant BOLADM
the ENQUEUE_ANY
and DEQUEUE_ANY
system privilege.
CREATE USER BOLADM IDENTIFIED BY BOLADM; GRANT CONNECT, RESOURCE, aq_ administrator_role TO BOLADM; ((AQjmsSession)t_sess).grantSystemPrivilege("ENQUEUE_ANY", "BOLADM", false); ((AQjmsSession)t_sess).grantSystemPrivilege("DEQUEUE_ANY", "BOLADM", false) ;where t_sess is the session object.
In the application, AQ propagators populate messages from the OE (Order Entry) schema to WS (Western Sales), ES (Eastern Sales) and OS (Worldwide Sales) schemas. WS, ES and OS schemas in turn populates messages to CB (Customer Billing) and CS (Customer Service) schemas. Hence the OE, WS, ES and OS schemas all host queues that serve as the source queues for the propagators.
When messages arrive at the destination queues, sessions based on the source queue schema name are used for enqueuing the newly arrived messages into the destination queues. This means that you need to grant schemas of the source queues enqueue privileges to the destination queues.
To simplify administration, all schemas that host a source queue in the BooksOnLine application are granted the ENQUEUE_ANY system privilege.
((AQjmsSession)t_sess).grantSystemPrivilege("ENQUEUE_ANY", "OE", false); ((AQjmsSession)t_sess).grantSystemPrivilege("ENQUEUE_ANY", "WS", false); ((AQjmsSession)t_sess).grantSystemPrivilege("ENQUEUE_ANY", "ES", false); ((AQjmsSession)t_sess).grantSystemPrivilege("ENQUEUE_ANY", "OS", false); where t_sess is the session object
To propagate to a remote destination queue, the login user specified in the database link in the address field of the agent structure should either be granted the 'ENQUEUE ANY' privilege, or be granted the rights to enqueue to the destination queue. However, you do not need to grant any explicit privileges if the login user in the database link also owns the queue tables at the destination.
Oracle8i supports queue/topic level access control for enqueue and dequeue operations. This feature allows the application designer to protect queues/topics created in one schema from applications running in other schemas. You need to grant only minimal access privileges to the applications that run outside the queue/topic's schema. The supported access privileges on a queue/topic are ENQUEUE
, DEQUEUE
and ALL
, for more information see "Security" in Chapter 4, "Managing AQ".
The BooksOnLine application processes customer billings in its CB
and CBADM
schemas. CB (Customer Billing) schema hosts the customer billing application, and the CBADM
schema hosts all related billing data stored as queue tables. To protect the billing data, the billing application and the billing data reside in different schemas. The billing application is allowed only to dequeue messages from CBADM_shippedorders_topic
, the shipped order topic. It processes the messages, and then enqueues new messages into CBADM_billedorders_topic
, the billed order topic.
To protect the queues from other illegal operations from the application, the following two grant calls are made:
/* Grant dequeue privilege on the shipped orders queue to the Customer Billing application. The CB application retrieves orders that are shipped but not billed from the shipped orders queue. */ ((AQjmsDestination)cbadm_shippedorders_topic).grantTopicPrivilege(t_sess, "DEQUEUE", "CB", false); where t_sess is the session /* Grant enqueue privilege on the billed orders queue to Customer Billing application.The CB application is allowed to put billed orders into this queue after processing the orders. */ ((AQjmsDestination)cbadm_billedorders_topic).grantTopicPrivilege(t_sess, "ENQUEUE", "CB", false);
AQ allows users retain messages in the queue-table which means that SQL can then be used to query these message for analysis. Messages often are related to each other. For example, if a message is produced as a result of the consumption of another message, the two are related. As the application designer, you may want to keep track of such relationships. Along with retention and message identifiers, AQ lets you automatically create message journals, also referred to as tracking journals or event journals. Taken together -- retention, message identifiers and SQL queries -- make it possible to build powerful message warehouses.
Let us suppose that the shipping application needs to determine the average processing times of orders. This includes the time the order has to wait in the backed_order topic. Specifying the retention as TRUE
for the shipping queues and specifying the order number in the correlation field of the message, SQL queries can be written to determine the wait time for orders in the shipping application.
For simplicity, we will only analyze orders that have already been processed. The processing time for an order in the shipping application is the difference between the enqueue time in the WS_bookedorders_topic
and the enqueue time in the WS_shipped_orders_topic
.
SELECT SUM(SO.enq_time - BO.enq_time) / count (*) AVG_PRCS_TIME FROM WS.AQ$WS_orders_pr_mqtab BO , WS.AQ$WS_orders_mqtab SO WHERE SO.msg_state = 'PROCESSED' and BO.msg_state = 'PROCESSED' AND SO.corr_id = BO.corr_id and SO.queue = 'WS_shippedorders_topic'; /* Average waiting time in the backed order queue: */ SELECT SUM(BACK.deq_time - BACK.enq_time)/count (*) AVG_BACK_TIME FROM WS.AQ$WS_orders_mqtab BACK WHERE BACK.msg_state = 'PROCESSED' AND BACK.queue = 'WS_backorders_topic';
The Oracle Parallel Server facility can be used to improve AQ performance by allowing different queues to be managed by different instances. You do this by specifying different instance affinities (preferences) for the queue tables that store the queues. This allows queue operations (enqueue/dequeue) or topic operations (publish/subscribe) on different queues/topics to occur in parallel.
The AQ queue monitor process continuously monitors the instance affinities of the queue tables. The queue monitor assigns ownership of a queue table to the specified primary instance if it is available, failing which it assigns it to the specified secondary instance. If the owner instance of a queue table ceases to exist at any time, the queue monitor changes the ownership of the queue table to a suitable instance -- the secondary instance or some other available instance if the secondary instance is also unavailable.
AQ propagation is able to make use of OPS although it is completely transparent to the user. The affinities for jobs submitted on behalf of the propagation schedules are set to the same values as that of the affinities of the respective queue tables. Thus a job_queue_process associated with the owner instance of a queue table will be handling the propagation from queues stored in that queue table thereby minimizing 'pinging'. Additional discussion on this topic can be found under AQ propagation scheduling (see "Schedule a Queue Propagation"in Chapter 9, "Administrative Interface").
For information about Oracle Parallel Server (OPS) see: Oracle8i Parallel Server Setup and Configuration Guide)
In the BooksOnLine example, operations on the OE_neworders_que
and booked_order_topic
at the order entry (OE) site can be made faster if the two topics are associated with different instances. This is done by creating the topics in different queue tables and specifying different affinities for the queue tables in the CreateQueueTable
() command.
In the example, the queue table OE_orders_sqtab
stores queue OE_neworders_que
and the primary and secondary are instances 1 and 2 respectively. For queue table OE_orders_mqtab
stores queue booked_order_topic
and
the primary and secondary are instances 2 and 1 respectively. The objective is to let instances 1 & 2 manage the two queues in parallel. By default, only one instance is available in which case the owner instances of both queue tables will be set to instance1. However, if OPS is setup correctly and both instances 1 and 2 are available, then queue table OE_orders_sqtab will be owned by instance 1 and the other queue table will be owned by instance 2. The primary and secondary instance specification of a queue table can be changed dynamically using the alter_queue_table() command as shown in the example below. Information about the primary, secondary and owner instance of a queue table can be obtained by querying the view USER_QUEUE_TABLES (see "Select Queue Tables in User Schema" in Chapter 10, "Administrative Interface: Views").
/* Create queue tables, topics for OE */ /* createing a queue table to hold queues */ qt_prop = new AQQueueTableProperty("SYS.AQ$_JMS_OBJECT_MESSAGE"); qt_prop.setPrimaryInstance(1); qt_prop.setSecondaryInstance(2); q_table = createQueueTable("OE", "OE_orders_sqtab", qt_prop); /* creating a queue table to hold topics */ qt1_prop = new AQQueueTableProperty("SYS.AQ$_JMS_OBJECT_MESSAGE"); qt1_prop.setMultiConsumer(TRUE); qt1_prop.setPrimaryInstance(2); qt1_prop.setSecondaryInstance(1); q_table1 = createQueueTable("OE", "OE_orders_mqtab", qt1_prop); dest_prop = new AQjmsDestinationProperty(); queue = ((AQjmsSession)q_sess).createQueue(q_table. "OE_neworders_que", dest_prop); dest_prop1 = new AQjmsDestinationProperty(); topic = ((AQjmsSession)q_sess).createTopic(q_table1, "OE_bookedorders_topic", dest_prop1); /* Check instance affinity of OE queue tables from AQ administrative view: */ SELECT queue_table, primary_instance, secondary_instance, owner_instance FROM user_queue_tables; /* Alter Instance Affinity of OE queue tables */ q_table.alter("OE_orders_sqtab", 2, 1); q_table1.alter("OE_orders_mqtabl", 1, 2);
Each instance keeps its own AQ statistics information in its own SGA, and does not have knowledge of the statistics gathered by other instances. Then, when a GV$AQ view is queried by an instance, all other instances funnel their AQ statistics information to the instance issuing the query.
The gv
$ view can be queried at any time to see the number of messages in waiting, ready or expired state. The view also displays the average number of seconds for which messages have been waiting to be processed. The order processing application can use this to dynamically tune the number of order processing processes (see Chapter , "Select the Number of Messages in Different States for the Whole Database" in Chapter 10, "Administrative Interface: Views").
CONNECT oe/oe /* Count the number as messages and the average time for which the messages have been waiting: */ SELECT READY, AVERAGE_WAIT FROM gv$aq Stats, user_queues Qs WHERE Stats.qid = Qs.qid and Qs.Name = 'OE_neworders_que';
JMS Messages are composed of the following parts:
The message header contains the following fields:
JMSDestination
- this field contains the destination to which the message is sent. In AQ this would correspond to the destination queue/topic.
JMSDeliveryMode
- JMS supports two modes of message delivery - PERSISTENT (where messages are logged to stable storage) and NON_PERSISTENT (messages not logged). Oracle AQ support persistent message delivery.
JMSMessageID
- this value uniquely identifies a message in a provider. All message ids must begin with ID:.
JMSTimeStamp
- contains the time the message was handed over to the provider to be sent. This maps to AQ message enqueue time.
JMSCorrelationID
- This field can be used by a client to link one message with another.
JMSReplyTo
- this field contains a Destination supplied by a client when a message is sent. Its the destination where a reply to the message should be sent. Clients must use an AQjmsAgent
to specify the ReplyTo
Destination.
JMSType
- this field contains a message type identifier supplied by a client at send time. For portability it is recommended that the JMSType
be symbolic values.
JMSExpiration
- when a message is sent, its expiration time is calculated as the sum of the time-to-live value specified on the send method and the current GMT. If the time-to-live is specified as zero, expiration is set to zero, which is to say, the message does not expire.
JMSPriority
- This field contain's the message's priority. The permitted values for priority are 0, 1, 2, 3..., 0 being the highest priority.JMS permits an administrator to configure JMS to override the client specified values for JMSDeliveryMode
, JMSExpiration
and JMSPriority
.
Properties are a mechanism to add optional header fields to a message. Properties allow a client, via message selectors, to have a JMS provider select messages on its behalf using application-specific criteria. Property names are Strings and values can be boolean, byte, short, int, long, float, double and string.
JMS defined properties begin with JMSX.
JMSXUserID
- The identity of the user sending the message.
JMSXAppID
- this is the identity of the application sending the message.
JMSXDeliveryCount
- the number of message delivery attempts.
JMSXGroupid
- this field is set by the client refers to the identity of the message group, this message is a part of.
JMSXGroupSeq
- the sequence number of a message within a group.
JMSXRcvTimeStamp
- the time the message was delivered to the consumer (dequeue time)
JMSXState
- message state set by provider. Message can be WAITING
, READY
, EXPIRED
or RETAINED
Oracle JMS specific properties begin with JMS_Oracle
. The following properties are Oracle-specific:
JMS_OracleExcpQ
- queue name to send the message to if it cannot be delivered to the original destination. Only Destinations of type EXCEPTION (described in Section 3.1.2) can be specified in the JMS_OracleExcpQ
property.
JMS_OracleDelay
- time in seconds to delay the delivery of the message. This may affect the order if message delivery
JMS_OracleOriginalMessageId
- if the messages are propagated from one destination to another, this property is set to the message id of the message in the source. If the message is not propagated, this property has the same value as the JMSMessageId
.
A client can add additional header fields to a message by defining properties.These properties can then be used in message selectors to select specific messages.
JMS properties or header fields are set either explicitly by the client or automatically by the JMS provider (these are generally read-only). Some JMS properties are set using the parameters specified send and receive operations.
JMS provides five forms of message body:
java.lang.String.
A StreamMessage is used to send a stream of Java primitives. It is filled and read sequentially. It inherits from Message and adds a stream message body. It's methods are based largely on those found in java.io.DataInputStream
and java.io.DataOutputStream
.
The primitive types can be read or written explicitly using methods for each type. They may also be read or written generically as objects. To use Stream Messages, the user has to create the Queue table with payload type SYS.AQ$_JMS_STREAM_MESSAGE
.
Stream messages support the following conversion table. A value written as the row type can be read as the column type.
boolean | byte | short | char | int | long | float | double | String | byte[] | |
---|---|---|---|---|---|---|---|---|---|---|
boolean |
X |
|
|
|
|
|
|
|
X |
|
byte |
|
X |
X |
|
X |
X |
|
|
X |
|
short |
|
|
X |
|
X |
X |
|
|
X |
|
char |
|
|
|
X |
|
|
|
|
X |
|
int |
|
|
|
|
X |
X |
|
|
X |
|
long |
|
|
|
|
|
X |
|
|
X |
|
float |
|
|
|
|
|
|
X |
X |
X |
|
double |
|
|
|
|
|
|
|
X |
X |
|
String |
X |
X |
X |
X |
X |
X |
X |
X |
X |
|
byte[] |
|
|
|
|
|
|
|
|
|
X |
A BytesMessage is used to send a message containing a stream of uninterpreted bytes. It inherits Message and adds a bytes message body. The receiver of the message supplies the interpretation of the bytes. It's methods are based largely on those found in java.io.DataInputStream
and java.io.DataOutputStream
.
This message type is for client encoding of existing message formats. If possible, one of the other self-defining message types should be used instead.
The primitive types can be written explicitly using methods for each type. They may also be written generically as objects.To use Bytes Messages, the user has to create the Queue table with payloadtype SYS.AQ$_JMS_BYTES_MESSAGE
.
A MapMessage is used to send a set of name-value pairs where names are Strings and values are Java primitive types. The entries can be accessed sequentially or randomly by name. The order of the entries is undefined. It inherits from Message and adds a map message body. The primitive types can be read or written explicitly using methods for each type. They may also be read or written generically as objects.
To use Bytes Messages, the user has to create the Queue table with payloadtype SYS.AQ$_JMS_MAP_MESSAGE
. Map messages support the following conversion table. A value written as the row type can be read as the column type.
boolean | byte | short | char | int | long | float | double | String | byte[] | |
---|---|---|---|---|---|---|---|---|---|---|
boolean |
X |
|
|
|
|
|
|
|
X |
|
byte |
|
X |
X |
|
X |
X |
|
|
X |
|
short |
|
|
X |
|
X |
X |
|
|
X |
|
char |
|
|
|
X |
|
|
|
|
X |
|
int |
|
|
|
|
X |
X |
|
|
X |
|
long |
|
|
|
|
|
X |
|
|
X |
|
float |
|
|
|
|
|
|
X |
X |
X |
|
double |
|
|
|
|
|
|
|
X |
X |
|
String |
X |
X |
X |
X |
X |
X |
X |
X |
X |
|
byte[] |
|
|
|
|
|
|
|
|
|
X |
java.lang.StringBuffer
. It inherits from Message
and adds a text message body. The text information
can be read or written using methods
getText()
and setText(
...)
. To use Text Messages, the user has to create the Queue table with payloadtype SYS.AQ$_JMS_TEXT_MESSAGE
.
An ObjectMessage is used to send a message that contains a serializable Java object. It inherits from Message and adds a body containing a single Java reference. Only serializable Java objects can be used. If a collection of Java objects must be sent, one of the collection classes provided in JDK 1.2 can be used. The objects can be read or written using the methods getObject()
and setObject(
...)
.To use Object Messages, the user has to create the Queue table with payloadtype SYS.AQ$_JMS_OBJECT_MESSAGE
.
public void enqueue_new_orders(QueueSession jms_session, BolOrder new_order) { QueueSender sender; Queue queue; ObjectMessage obj_message; try { /* get a handle to the new_orders queue */ queue = ((AQjmsSession) jms_session).getQueue("OE", "OE_neworders_que"); sender = jms_session.createSender(queue); obj_message = jms_session.createObjectMessage(); obj_message.setJMSCorrelationID("RUSH"); obj_message.setObject(new_order); jms_session.commit(); } catch (JMSException ex) { System.out.println("Exception: " + ex); } }
An AdtMessage is used to send a message that contains a Java object that maps to an Oracle Object type. These objects inherit from Message
and adds a body containing a Java object that implements the CustomDatum
interface. For more information on the CustomDatum
interface refer to the JDBC Developers guide.
To use Adt Messages, the user has to create the Queue table with payload type as the Oracle Object Type. The AdtMessage payload can be read and written using the getAdtPayload
and setAdtPayload
methods.
setProperty
call:
getProperty
call
StreamMessage
, BytesMessage
, ObjectMessage
, TextMessage
, ObjectMessage
JMSXuserID
JMSXAppID
JMSXDeliveryCount
JMSXGroupID
JMSXGroupSeq
JMSXRecvTimeStamp
JMSXState
JMS_OracleExcpQ
JMS_OracleDelay
JMS_OracleOriginalMessageID
JMSXDeliveryCount
JMSXRecvTimeStamp
JMSXState
JMS_OracleExcpQ
JMS_OracleDelay
QueueReceiver
and TopicReceiver
(for queues containing any type of payload - JMS types or ADT)
JMSMessageID
JMSCorrelationID
JMSPriority
(int)
JMSCorrelationID
(String)
JMSTimestamp
(Date)
JMSType
(String)
JMSXUserID
(String)
JMSXAppID
(String)
JMSXGroupID
(String)
JMSXGroupSeq
(int)
Any User defined property
/* * BooksOrder - payload for BooksOnline example * */ import java.lang.*; import java.io.*; import java.util.*; public class BolOrder implements Serializable { int orderno; String status; String type; String region; BolCustomer customer; String paymentmethod; BolOrderItem[] itemlist; String ccnumber; Date orderdate; public BolOrder(int orderno, BolCustomer customer) { this.customer = customer; this.orderno = orderno; } public int getOrderNo() { return orderno; } public String getStatus() { return status; } public void setStatus(String new_status) { status = new_status; } public String getRegion() { return region; } public void setRegion(String region) { this.region = region; } public BolCustomer getCustomer() { return customer; } public String getPaymentmethod() { return paymentmethod; } public void setPaymentmethod(String paymentmethod) { this.paymentmethod = paymentmethod; } public BolOrderItem[] getItemList() { return itemlist; } public void setItemList(BolOrderItem[] itemlist) { this.itemlist = itemlist; } public String getCCnumber() { return ccnumber; } public void setCCnumber(String ccnumber) { this.ccnumber = ccnumber; } public Date getOrderDate() { return orderdate; } public void setOrderDate(Date orderdate) { this.orderdate = orderdate; } } /* * BolOrderItem - order item type for BooksOnline example * */ import java.lang.*; import java.io.*; import java.util.*; public class BolOrderItem implements Serializable { BolBook item; int quantity; public BolOrderItem(BolBook book, int quantity) { item = book; this.quantity = quantity; } public BolBook getItem() { return item; } public int getQuantity() { return quantity; } } /* * BolBook - book type for BooksOnline example * */ import java.lang.*; import java.io.*; import java.util.*; public class BolBook implements Serializable { String title; String authors; String isbn; float price; public BolBook(String title) { this.title = title; } public BolBook(String title, String authors, String isbn, float price) { this.title = title; this.authors = authors; this.isbn = isbn; this.price = price; } public String getISBN() { return isbn; } public String getTitle() { return title; } public String getAuthors() { return authors; } public float getPrice() { return price; } } /* * BolCustomer - customer type for BooksOnline example * */ import java.lang.*; import java.io.*; import java.util.*; public class BolCustomer implements Serializable { int custno; String custid; String name; String street; String city; String state; int zip; String country; public BolCustomer(int custno, String name) { this.custno = custno; this.name = name; } public BolCustomer(int custno, String custid, String name, String street, String city, String state, int zip, String country) { this.custno = custno; this.custid = custid; this.name = name; this.street = street; this.city = city; this.state = state; this.zip = zip; this.country = country; } public int getCustomerNo() { return custno; } public String getCustomerId() { return custid; } public String getName() { return name; } public String getStreet() { return street; } public String getCity() { return city; } public String getState() { return state; } public int getZipcode() { return zip; } public String getCountry() { return country; } }
|
![]() Copyright © 1996-2000, Oracle Corporation. All Rights Reserved. |
|