More XQuery examples

Before i show you some more xquery examples, i found a page at oracle.com which illustrates the use of xquery without XMLDB. But it looks like it uses a newer release of xquery than available in JDeveloper 10.1.3.2. The xquery library in 10.1.3.2 doesn’t use a XQueryResultSet.

The following example displays how to use variables with xquery:

XQueryContext ctx = new XQueryContext();

String query =
    "declare variable $title external; " +
    "for $i in doc('file:///c:/temp/books.xml')//book " +
    "where $i/title/text() = $title " +
    "return $i";
PreparedXQuery xquery = ctx.prepareXQuery(query);
xquery.setString(new QName("title"), "Xml primer");
XMLSequence seq = xquery.executeQuery();
while (seq.next()) {
    XMLItem item = seq.getCurrentItem();
    item.getNode().print(System.out);
}

Using external variables you can also specify the xml document that you want to query:

XQueryContext ctx = new XQueryContext();

String query =
    "declare variable $doc external; " +
    "declare variable $title external; " +
    "for $i in doc($doc)//book " +
    "where $i/title/text() = $title " +
    "return $i";
PreparedXQuery xquery = ctx.prepareXQuery(query);
xquery.setString(new QName("doc"), "file:///c:/temp/books.xml");
xquery.setString(new QName("title"), "Xml primer");
XMLSequence seq = xquery.executeQuery();
while (seq.next()) {
    XMLItem item = seq.getCurrentItem();
    item.getNode().print(System.out);
}

If you want to query a dom tree:

XQueryContext ctx = new XQueryContext();

String query =
   "declare variable $title external; " +
   "for $i in .//book " +
   "where $i/title/text() = $title " +
   "return $i";
PreparedXQuery xquery = ctx.prepareXQuery(query);
xquery.setString(new QName("title"), "Xml primer");

// parse input document
DOMParser parser = new DOMParser();
parser.parse(new URL("file:///c:/temp/books.xml"));

// set context document
OXMLItem xmlItem = xquery.createItem();
xmlItem.setNode((XMLNode)parser.getDocument().getDocumentElement());
xquery.setContextItem(xmlItem);

// get result
XMLSequence seq = xquery.executeQuery();
while (seq.next()) {
    XMLItem item = seq.getCurrentItem();
    item.getNode().print(System.out);
}

Using Oracle's XQuery without a database

Did you know you can use Oracle’s Java XQuery library without a database? I wasn’t aware that it was possible. All the examples i know show you how to use XQuery in combination with XMLDB. But JDeveloper contains an XQuery library which you can use in any java program. The library you need is ‘Oracle Xquery‘, which is available in $JDEV_HOME/lib/xquery.jar.

Here are some examples how you can use it:

XQueryContext ctx = new XQueryContext();

String query =
   "for $i " +
   "in <doc><row>text1</row><row>text2</row><row>text3</row></doc>//row " +
   "where $i/text() = 'text2' " +
   "return $i";

PreparedXQuery xquery = ctx.prepareXQuery(query);
XMLSequence seq = xquery.executeQuery();

while (seq.next()) {
  XMLItem item = seq.getCurrentItem();
  item.getNode().print(System.out);
}

Here’s another example which queries an external xml document:

XQueryContext ctx = new XQueryContext();

String query =
  "for $i " +
  "in doc('file:///c:/temp/books.xml')//book " +
  "where $i/title/text() = 'Xml primer' " +
  "return $i";

PreparedXQuery xquery = ctx.prepareXQuery(query);
XMLSequence seq = xquery.executeQuery();

while (seq.next()) {
  XMLItem item = seq.getCurrentItem();
  item.getNode().print(System.out);
}

Can't add entity methods to your session bean?

I took me a few minutes this afternoon to figure this one out. JDeveloper can automatically generate EJB3 session beans for you that have methods to work with entity objects by selecting ‘generate session facade methods‘. These are the normal methods you need to insert, remove, and query entities. Later when you’ve added some entity beans you can select ‘edit session facade‘ in the context menu of the session bean, to add facade methods for the new entities.

But somehow, this afternoon, no new methods were displayed for my new entities. Why? All source files compiles, all the required annotations were added to the entities, but no session facade methods were suggested in the ‘specify session facade options‘ window.

Turns out that the persistency unit being used by the session bean ,as specified by the @PersistenceContext(unitName=”model”) annotation, didn’t contain class elements for all the new classes. If you use JPA in-container you don’t have to add all these classes to the persistency unit configuration, but if you have an out-of-container configuration, you need to. Not just at runtime, but also at design time.

So, after adding the new classes to the persistence.xml file, i could use jdeveloper to generate facade methods in my session bean.

What i would like to see in JPA 2

Bert Ertman will be talking about EJB 3.1 and JPA 2.0 tomorrow at the J-Spring. I haven’t looked at the work being done on these new releases, but i sure know what i would like to see in JPA 2.

When you work with larger existing databases implemented on Oracle you know a couple of things: data changes happen outside your java application and C(R)UD operations often have to use stored procedures.

An example of the first situation is when triggers are used to create primary key values using sequences. An example of the second situation are the TAPI packages created by Oracle designer. Stored procedures are a very good place to centralize complex business constraints. All applications wanting to insert or update data need to use these stored procedures. But even for querying data, stored procedures are useful. You can reuse queries in multiple applications, optimize once, and no need for all the different programmers to also know how to create good performing queries.

Currently JPA can’t handle these two situations. You can’t determine the primary key value created using a trigger when you insert a java object using JPA. Toplink has a solution for this, the ReturnInsert annotation. This will make sure the object properties are updated after the object is inserted into the database. And unlike the refresh method of the entity manager, this will also work for primary key columns.


@Id
@ReturnInsert
@Column(nullable = true)
private Long id;

Hibernate has a solution for the second situation as is demonstrated in this article: Agile database refactoring with Hibernate. You can specify in the hibernate mapping file that insert, update and delete operations should call a plsql stored procedure:


<sql-insert callable="true">{call insert_order(?, ?, ?)}</sql-insert>
<sql-update callable="true">{call update_order(?, ?, ?)}</sql-update>
<sql-delete callable="true">{call delete_order(?)}</sql-delete>

Not sure if you can do the same thing with Toplink, but i would like to be able to do it with JPA.

Using jrunscript to test regular expressions

I recently needed to quickly test some regular expression. There are a number of tools and websites that will let you do that, but since scripting is included in java 6 i thought there should be a way to do it with java without actually writing and compiling a java class. I hadn’t used scripting in java until now but after some research i found that you can use jrunscript to start a javascript shell. Java is integrated into the javascript engine in jdk 1.6, so you can use this to test java. Here’s an example:

>jrunscript.exe
js> "!if:companyname[a!=b]".split(":")[0]
!if
js> "abcdef".match(/bc/)[0];
bc
js>

Adding ADF data control drop options

I’m currently in the ADF deep dive session by Duncan Mills at Oracle’s Xtreme PTS. Wasn’t sure if it would be worth attending, as most presentations here have been pretty high level. But Duncan had a nice trick which i didn’t know: you can customize the drop options that are available when you drop data controls on an adf faces page. The options are configured using the file aces_creator_configuration.xml (in $JDEV_HOME/jdev/system/oracle.adfm.dt.faces.10.1.3.40.66/). You can add new options, single components or complex components, to this file. The file uses velocity templates, so you add some expressions to dynamically configure the components as they are dropped on a page.

Duncan Mills

Oracle open sources Toplink

The part of Toplink which implements JPA, Toplink Essentials, was already open source, and part of the JEE 5 reference implementation, but today Oracle announced that it will completely open source Toplink (pressrelease ). Toplink not only implements JPA, it also support JAXB, SDO and JCA, which means that it’s a pretty complete persistency solution. Oracle is also increasing it’s contribution to Eclipse, by joining the board of directors of the Eclipse foundation, and by creating an Eclipse project called Eclipse Persistence Platform based on Toplink (FAQ (pdf)).

What does this mean? That Oracle is still focusing on the open source part of the Java world. They are not converting a lot of java programmers to JDeveloper and ADF, with ADF being tied to JDeveloper. Instead, open source java programmers are targeted through Eclipse, by adding all the Oracle technologies that may interest 3gl java programmers this IDE.

It also means there is less of a barrier to use Toplink extensions on projects. I always prefer to stick to the standards whenever possible. But JPA does have some missing pieces, which Toplink, but also Hibernate, fixes by included some non standard functionality. Support for stored procedures is one example. In the past I’ve hesitated to use these extensions, because it limits you how you can distribute your application. For example, we have a development server virtual appliance we use on most projects, which includes version control, bug database, build server, etc. This is all based on open source, because it allows you to take it to all your customers. Now we can include applications based on Toplink in this vmware machine.

Flex the next Java?

Flex is getting a lot of attention at the moment. During their Engage event Adobe demonstrated what some companies are doing with this technology: Best Apollo Demos. Other companies are also using Flex. SAP is using Flex to create RIAs, and in a WebCenter presentation Oracle also mentioned to be working on integrating Flex solutions into their new Portal (and a lot more) software.

There seems to be some similarity with Java. Not that Flex will replace it, but Flex might become the Java for RIA’s for Companies who do not want to rely too much on Microsoft (Oracle, Sap, etc). Microsoft has .net on the server, most of these other software companies use Java on the server. Microsoft has WPF/e for RIA’s, these other companies may standardize on Flex for RIA’s.

There are also differences: I think Sun was (and still is) a lot more open with Java than Adobe with Flex. Both companies provide free runtimes and free compilers, but Sun actively engaged other parties to participate in creating standards for Java. Adobe is still the only one determining the future direction of Flex.

ADF Training

I just finished giving an Oracle ADF training. This is a 3 day training were people learn to use EJB3, JPA, JSF, ADF Faces and ADF Data Controls and Data Bindings. This is a lot of material for 3 days, next time we’ll probably extend the training to 4 or 5 days.

As always, the students aren’t the only ones who learn a lot during a training. I always find that whenever I’m giving a training I’m learning a lot too. To be able to explain how something works, and how you should use it, means you have to really understand it. Just being able to use it, doesn’t mean you understand it well enough to explain it.

I created the training material myself, which was also quite a challenging task. There’s so much information available about the subjects, what do you put in your slides and what do you skip? In the beginning i just put everything i thought relevant on the slides, but this is not a good way to learn about ADF.

So i turned it around, it’s not the slides nor the information that is important. What is important is that the students learn how to use the tools to create the applications that they need. This means that the core of the training should be the exercises. If a student can complete an exercises it means he’s able to use the technology. So i created a lot of exercises, and only put in my slides whatever i though necessary for the students to be able to complete the exercises (to be honest, i still have some slides in there that aren’t really necessary for the exercises, these will be removed the next time i give the training).

It’s also important that the exercises slowly become more complex, it’s a step by step process. I read an interesting statement some time ago on a forum which said that you can only learn what you almost know. I think this is very true, and it means that a training needs a lot of exercises that slowly expect more knowledge of the subject.

Another interesting fact i learned during the training is that ADF Business Components and JHeadstart are quite popular. Personally, I prefer to use standard solutions whenever a good standard solution is available. For example, Java Persistency API. Before JPA, java didn’t have a good standard and broadly supported solution for ORM, so better alternatives became mainstream. But in my opinion JPA is good enough for most applications, so for me JPA is the default pick, unless there’s a good reason to use something else. Using standards has the advantage that there’s a lot of information available, and it’s easy to find developers, which is quite important in today’s market. For nonstandard niche solutions it’s a lot harder to find support and developers.

But most of the students in the training had a Oracle Forms Developer and Designer background, and they really like ADF Business Components and JHeadstart. Business Components because it allows them to reuse their extensive SQL knowledge, and JHeadstart because it’s the only tool that gives them the generation productivity similar to Oracle Designer.