4.7 Java Tools for Accessing Oracle Objects
Oracle provides various ways to integrate Oracle object features with Java.
These interfaces enable you both to access SQL data from Java and to provide persistent database storage for Java objects.
Topics:
4.7.1 JDBC Access to Oracle Object Data
JDBC (Java Database Connectivity) is a set of Java interfaces to the Oracle server.
Oracle provides tight integration between objects and JDBC. You can map SQL types to Java classes with considerable flexibility.
Oracle JDBC:
-
Allows access to objects and collection types (defined in the database) in Java programs through dynamic SQL.
-
Translates types defined in the database into Java classes through default or customizable mappings.
Version 2.0 of the JDBC specification supports object-relational constructs such as user-defined (object) types. JDBC materializes Oracle objects as instances of particular Java classes. Using JDBC to access Oracle objects involves creating the Java classes for the Oracle objects and populating these classes. You can either:
-
Let JDBC materialize the object as a
STRUCT
. In this case, JDBC creates the classes for the attributes and populates them for you. -
Manually specify the mappings between Oracle objects and Java classes; that is, customize your Java classes for object data. The driver then populates the customized Java classes that you specify, which imposes a set of constraints on the Java classes. To satisfy these constraints, you can choose to define your classes according to either the
SQLData
interface or theORAData
interface.See Also:
Oracle Database JDBC Developer's Guide for complete information about JDBC
4.7.2 Data Mapping Strategies
Oracle SQLJ supports either strongly typed or weakly typed Java representations of object types, reference types (REF
s), and collection types (varrays and nested tables) to be used in iterators or host expressions.
Strongly typed representations use a custom Java class that corresponds to a particular object type, REF
type, or collection type and must implement the interface oracle
.sql
.ORAData
. The Oracle JPublisher utility can automatically generate such custom Java classes.
Weakly typed representations use the class oracle
.sql
.STRUCT
(for objects), oracle
.sql
.REF
(for references), or oracle
.sql
.ARRAY
(for collections).
4.7.3 JPublisher
Oracle JPublisher is a utility that generates Java classes to represent the following user-defined database entities in your Java program:
-
Database object types
-
Database reference (
REF
) types -
Database collection types (varrays or nested tables)
-
PL/SQL packages
JPublisher enables you to specify and customize the mapping of database object types, reference types, and collection types (varrays or nested tables) to Java classes, in a strongly typed paradigm.
4.7.3.1 JPublisher Used to Create Java Classes for JDBC and SQLJ Programs
Oracle lets you map Oracle object types, reference types, and collection types to Java classes and preserve all the benefits of strong typing. You can:
-
Use JPublisher to automatically generate custom Java classes and use those classes without any change.
-
Subclass the classes produced by JPublisher to create your own specialized Java classes.
-
Manually code custom Java classes without using JPublisher if the classes meet the requirements stated in Oracle Database JPublisher User's Guide.
We recommend that you use JPublisher and subclass when the generated classes do not do everything you need.
4.7.3.2 What JPublisher Produces for a User-Defined Object Type
When you run JPublisher for a user-defined object type, it automatically creates the following:
-
A custom object class to act as a type definition to correspond to your Oracle object type
This class includes getter and setter methods for each attribute. The method names are of the form
getXxx()
andsetXxx()
for attributexxx
.Also, you can optionally instruct JPublisher to generate wrapper methods in your class that invoke the associated Oracle object methods executing in the server.
-
A related custom reference class for object references to your Oracle object type
This class includes a
getValue()
method that returns an instance of your custom object class, and asetValue()
method that updates an object value in the database, taking as input an instance of the custom object class.
When you run JPublisher for a user-defined collection type, it automatically creates the following:
-
A custom collection class to act as a type definition to correspond to your Oracle collection type
This class includes overloaded
getArray()
andsetArray()
methods to retrieve or update a collection as a whole, agetElement()
method andsetElement()
method to retrieve or update individual elements of a collection, and additional utility methods.
JPublisher-produced custom Java classes in any of these categories implement the ORAData
interface and the getFactory()
method.
4.7.4 Java Object Storage
JPublisher enables you to construct Java classes that map to existing SQL types. You can then access the SQL types from a Java application using JDBC.
You can also go in the other direction. That is, you can create SQL types that map to existing Java classes. This capability enables you to provide persistent storage for Java objects. Such SQL types are called SQL types of Language Java, or SQLJ object types. They can be used as the type of an object, an attribute, a column, or a row in an object table. You can navigationally access objects of such types—Java objects—through either object references or foreign keys, and you can query and manipulate such objects from SQL.
You create SQLJ types with a CREATE TYPE
statement as you do other user-defined SQL types. For SQLJ types, two special elements are added to the CREATE
TYPE
statement:
-
An
EXTERNAL
NAME
phrase, used to identify the Java counterpart for each SQLJ attribute and method and the Java class corresponding to the SQLJ type itself -
A
USING
clause, to specify how the SQLJ type is to be represented to the server. TheUSING
clause specifies the interface used to retrieve a SQLJ type and the kind of storage.
For example:
Example 4-2 Mapping SQL Types to Java Classes
-- Mapping SQL Types to Java Classes example, not sample schema CREATE TYPE full_address AS OBJECT (a NUMBER); / CREATE OR REPLACE TYPE person_t AS OBJECT EXTERNAL NAME 'Person' LANGUAGE JAVA USING SQLData ( ss_no NUMBER (9) EXTERNAL NAME 'socialSecurityNo', name varchar(100) EXTERNAL NAME 'name', address full_address EXTERNAL NAME 'addrs', birth_date date EXTERNAL NAME 'birthDate', MEMBER FUNCTION age RETURN NUMBER EXTERNAL NAME 'age () return int', MEMBER FUNCTION addressf RETURN full_address EXTERNAL NAME 'get_address () return long_address', STATIC function createf RETURN person_t EXTERNAL NAME 'create () return Person', STATIC function createf (name VARCHAR2, addrs full_address, bDate DATE) RETURN person_t EXTERNAL NAME 'create (java.lang.String, Long_address, oracle.sql.date) return Person', ORDER member FUNCTION compare (in_person person_t) RETURN NUMBER EXTERNAL NAME 'isSame (Person) return int') /
SQLJ types use the corresponding Java class as the body of the type; you do not specify a type body in SQL to contain implementations of the type's methods as you do with ordinary object types.
4.7.4.1 Creating SQLJ Object Types
You can create SQLJ object types using SQL statements
The SQL statements to create SQLJ types and specify their mappings to Java are placed in a file called a deployment descriptor. Related SQL constraints and privileges are also specified in this file. The types are created when the file is executed.
Below is an overview of the process of creating SQL versions of Java types/classes:
- Design the Java types.
- Generate the Java classes.
- Create the SQLJ object type statements.
- Construct the JAR file. This is a single file that contains all the classes needed.
- Using the
loadjava
utility, install the Java classes defined in the JAR file. - Execute the statements to create the SQLJ object types.
4.7.4.2 Additional Notes About Mapping
The following are additional notes to consider when mapping of Java classes to SQL types:
-
You can map a SQLJ static function to a user-defined constructor in the Java class. The return value of this function is of the user-defined type in which the function is locally defined.
-
Java static variables are mapped to SQLJ static methods that return the value of the corresponding static variable identified by
EXTERNAL
NAME
. TheEXTERNAL
NAME
clause for an attribute is optional with aSQLData
orORAData
representation. -
Every attribute in a SQLJ type of a SQL representation must map to a Java field, but not every Java field must be mapped to a corresponding SQLJ attribute: you can omit Java fields from the mapping.
-
You can omit classes: you can map a SQLJ type to a non-root class in a Java class hierarchy without also mapping SQLJ types to the root class and intervening superclasses. Doing this enables you to hide the superclasses while still including attributes and methods inherited from them.
However, you must preserve the structural correspondence between nodes in a class hierarchy and their counterparts in a SQLJ type hierarchy. In other words, for two Java classes
j_A
andj_B
that are related through inheritance and are mapped to two SQL typess_A
ands_B
, respectively, there must be exactly one corresponding node on the inheritance path froms_A
tos_B
for each node on the inheritance path fromj_A
toj_B
. -
You can map a Java class to multiple SQLJ types as long as you do not violate the restriction in the preceding paragraph. In other words, no two SQLJ types mapped to the same Java class can have a common supertype ancestor.
-
If all Java classes are not mapped to SQLJ types, it is possible that an attribute of a SQLJ object type might be set to an object of an unmapped Java class. Specifically, to a class occurring above or below the class to which the attribute is mapped in an inheritance hierarchy. If the object's class is a superclass of the attribute's type/class, an error is raised. If it is a subclass of the attribute's type/class, the object is mapped to the most specific type in its hierarchy for which a SQL mapping exists
4.7.4.3 SQLJ Type Evolution
You can evole SQLJ types using the ALTER TYPE
statement.
The ALTER
TYPE
statement enables you to evolve a type by, for example, adding or dropping attributes or methods.
When a SQLJ type is evolved, an additional validation is performed to check the mapping between the class and the type. If the class and the evolved type match, the type is marked valid. Otherwise, the type is marked as pending validation.
Being marked as pending validation is not the same as being marked invalid. A type that is pending validation can still be manipulated with ALTER
TYPE
and GRANT
statements, for example.
If a type that has a SQL representation is marked as pending evaluation, you can still access tables of that type using any DML or SELECT statement that does not require a method invocation.
You cannot, however, execute DML or SELECT
statements on tables of a type that has a serializable representation and has been marked as pending validation. Data of a serializable type can be accessed only navigationally, through method invocations. These are not possible with a type that is pending validation. However, you can still re-evolve the type until it passes validation.
See "Type Evolution".
4.7.4.4 Constraints
For SQLJ types having a SQL representation, the same constraints can be defined as for ordinary object types.
Constraints are defined on tables, not on types, and are defined at the column level. The following constraints are supported for SQLJ types having a SQL representation:
-
Unique constraints
-
Primary Key
-
Check constraints
-
NOT NULL
constraints on attributes -
Referential constraints
The IS
OF
TYPE
constraint on column substitutability is supported, too, for SQLJ types having a SQL representation. See "Constraining Substitutability".
4.7.4.5 Querying SQLJ Objects
SQLJ types can be queried just like ordinary SQL object types.
-
Query SQLJ types just like ordinary object types.
Methods called in a SELECT
statement must not attempt to change attribute values.
4.7.4.6 Inserting Java Objects
You can insert Java objects into tables.
Inserting a row in a table containing a column of a SQLJ type requires a call to the type's constructor function to create a Java object of that type.
-
Use an implicit, system-generated constructor, or define a static function that maps to a user-defined constructor in the Java class.
4.7.4.7 Updating SQLJ Objects
You can update SQLJ objects several ways.
SQLJ objects can be updated by:
-
Using an
UPDATE
statement to modify the value of one or more attributes -
Invoking a method that updates the attributes and returns
SELF
—that is, returns the object itself with the changes made.
For example, suppose that raise()
is a member function that increments the salary
field/attribute by a specified amount and returns SELF
. The following statement gives every employee in the object table employee_objtab
a raise of 1000
:
UPDATE employee_objtab SET c=c.raise(1000);
A column of a SQLJ type can be set to NULL
or to another column using the same syntax as for ordinary object types. For example, the following statement assigns column d
to column c
:
UPDATE employee_reltab SET c=d;
4.7.5 Defining User-Defined Constructors in Java
When you implement a user-defined constructor in Java, the supply the string supplied as the implementing routine must correspond to a static function. For the return type of the function, specify the Java type mapped to the SQL type.
When you implement a user-defined constructor in Java, the string supplied as the implementing routine must correspond to a static function. For the return type of the function, specify the Java type mapped to the SQL type.
Example 4-3 is an example of a type declaration that involves a user-defined constructor implemented in Java.
Example 4-3 Defining a User-Defined Constructor in Java
-- Defining a User-Defined Constructor in Java example, not sample schema CREATE TYPE person1_typ AS OBJECT EXTERNAL NAME 'pkg1.J_Person' LANGUAGE JAVA USING SQLData( name VARCHAR2(30), age NUMBER, CONSTRUCTOR FUNCTION person1_typ(SELF IN OUT NOCOPY person1_typ, name VARCHAR2, age NUMBER) RETURN SELF AS RESULT AS LANGUAGE JAVA NAME 'pkg1.J_Person.J_Person(java.lang.String, int) return J_Person') /
4.7.6 JDeveloper
Oracle JDeveloper is a full-featured, cross-platform, integrated development environment for creating multitier Java applications that is well integrated with Oracle Application Server and Database.
Oracle JDeveloper enables you to develop, debug, and deploy Java client applications, dynamic HTML applications, web and application server components, JavaBean components, and database stored procedures based on industry-standard models.
JDeveloper is also the integrated development environment for ADF and TopLink.
4.7.6.1 Application Development Framework (ADF)
ADF is a framework for building scalable enterprise Java EE applications. Developers can use ADF to build applications where the application data is persisted to Oracle Object tables as well as other schema objects.