Andrej Koelewijn

10/30/2003

Oracle pageflow diagrammer

Filed under: — andrejk @ 11:09 pm

Jdeveloper 10g has a very usefull pageflow diagrammer, which allows you to diagram the different pages in your web application. You can drag struts actions on the diagram and connect them to jsp pages. Setting up a struts jsp application is a no brainer this way. Jsp pages, struts actions, and the struts config file are generated based on your model.

If you edit a jsp, for example an edit form, and set the action attribute of the form to point to some action that will handle updating the data to the database, this relationship between the jsp page and the action will not automatically be displayed in the pageflow diagram. If you select ‘refresh diagram from all pages’ these links will be displayed in the diagram. Nice!

10/29/2003

Using oracle ref cursors in java

Filed under: — andrejk @ 9:31 pm

I’ve noticed in my  web logs that the item i wrote about ref cursors gets a lot of hits from google. As this item is only a link to a dutch article, i thought it might be usefull to provide a translation:

There are different methods  to get data out of your Oracle database when using java. The most common method is to use JDBC. Other options include Oracle business components for java (BC4J) and Toplink.  Database communication can also be handled by a j2ee container, when you use container managed persistence for entity beans. A disadvantage of using jdbc is that the programmer needs java and sql knowledge.

The example below shows how jdbc is usually used. You instantiate a statement object for a query, you specify the parameter values, execute the query and then you loop through the rows in the resultset.

String usersSql = "select username, user_id, created from all_users";
PreparedStatement stmt = _connection.prepareStatement(usersSql);
ResultSet rset = stmt.executeQuery();

while (rset.next())
{
String username = rset.getString(1);
BigDecimal userId = rset.getBigDecimal(2);
Date created = rset.getDate(3);
}
rset.close();
stmt.close();

As mentioned, a disadvantage of this approach is that the programmer needs to know both sql and java. And to write performing queries, the programmer needs database specific knowledge, for example about oracle hints which can be using in queries.

By using pl/sql ref cursors you can avoid that the java programmer needs to have a lot of sql knowledge. All queries can be defined in oracle package in the database, and the java programmer can use these queries by calling pl/sql stored procedures. The stored procedure will return a  ref cursor.  The result of the ref cursor can be read by normally looping of  a resultset.

The example below shows how a ref cursor is defined in a pl/sql package. The result of calling the pl/sql function getusers is a pointer to a cursor.

CREATE OR REPLACE PACKAGE cursors_pkg
IS
TYPE refcursortype IS REF CURSOR;
FUNCTION getusers RETURN refcursortype;
END;
/

CREATE OR REPLACE PACKAGE BODY cursors_pkg IS
FUNCTION getusers RETURN refcursortype IS
alluserscursor refcursortype;
BEGIN
OPEN alluserscursor FOR
SELECT username
, user_id
, created
FROM all_users;
RETURN alluserscursor;
END;
END;

After the ref cursor has been defined, it can easily be used by java, as the following example shows:

String usersSql = "{ ? := cursors_pkg.getUsers; }";
CallableStatement stmt = _connection.prepareCall(usersSql);
stmt.registerOutParameter(1,OracleTypes.CURSOR);
stmt.execute();
ResultSet rset =((OracleCallableStatement) stmt).getCursor(1);
while (rset.next())
{
String username = rset.getString(1);
BigDecimal userId = rset.getBigDecimal(2);
Date created = rset.getDate(3);
}
rset.close();
stmt.close();

As you can see, the difference with the previous example isn’t very big. We are still using a resultset to loop over all the records. The only difference is that the query has been defined in the pl/sql pacakge. The only sql code you are left with is the function call. This is a lot easier to write than sql queries (no hints needed, no wrong joins possible), and a lot more secure, as you don’t have to hand out direct access to tables, only access to the pl/sql code.

The example uses oracle specific java classes, but you can also rewrite it, so that it doesn’t use anything oracle specific.  Postgresql, for example, also supports ref cursors, so if you want portable java code, be sure not to use the oracle specific classes.

In the example above, a weakly typed cursor was used. You can also use strongly typed cursors, e.g., by specifying a record type in the package specification. This is shown in the following example:

CREATE OR REPLACE PACKAGE cursors_pkg IS
TYPE userstype IS RECORD
( username VARCHAR2(30)
, userid NUMBER
, created DATE );
TYPE userscursortype IS REF CURSOR RETURN userstype;
FUNCTION getusers RETURN userscursortype;
END;

I’ve done some tests, to see if using ref cursors has a negative impact on performance. This doesn’t seem to be the case. So using ref cursors seems to be usefull when you have a team with java specific and oracle specific programmers.

10/23/2003

Using eclipse to debug your tomcat web application

Filed under: — andrejk @ 11:27 am

Got this question again today. Usually i’d say: use the tomcat plugin, but in this case tomcat 3.2.4 is used, as that’s the tomcat version the web server is still using. The eclipse tomcat plugin only supports tomcat 3.3 and up.



Here’s what you do:


  • Start java with remote debugging enabled. You do this by modifying tomcat.bat (assuming you’re on windows). You have to add some parameters when starting java. If you start tomcat from a cmd box, look for the line “echo Starting Tomcat in new window” in tomcat.bat. Add the following line:
    set JAVA_X_OPTS=-Xdebug -Xnoagent
    -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5000

    And modify the star t java line as follows:
    _STARTJAVA TOMCAT_OPTS -Dtomcat.home="TOMCAT_HOME"
    org.apache.tomcat.startup.Tomcat %2 %3 %4 %5 %6 %7 %8 %

    Now you can start tomcat by typing startup.bat in your cmd box.

  • Click on the debug button in your eclipse toolbar. Select the “Debug…” item. This will open a debug window. Under configurations you’ll find an entry “Remote Java Application”. Select this and then press the new button. Choose a project, leave the connection type to “standard (socket attach)” and for connection properties choose “localhost” and “5000” (change these if you’re using a different port or a different machine to run tomcat). Now press apply and debug.




That’s it. You can now set breakpoints in your code, and inspect what your application is doing.

10/22/2003

Borland to own JBoss

Filed under: — andrejk @ 8:54 pm

I guess it’s just a mistake in internetnews.com’s article Borland Works To Evolve Java but it seems to imply that Borland owns JBoss. According to this article:

As Paolini explained, the JBuilder X product boasts advanced Web application development support that includes a standards-based visual designer for the Apache Struts framework, as well as comprehensive support for Borland’s popular open source application server, JBoss.

Even if it’s not true, this is good advertisement for JBoss.

10/21/2003

A PooledConnection is not a pool of connections

Filed under: — andrejk @ 3:20 pm

I ran into this problem again today as the naming of these objects is quite confusing.



It’s a quite common mistake to use an OracleConnectionPoolDataSource when you need a pool of database connections. However, OracleConnectionPoolDataSource represents one poolable physical database connection. Usually you’ll want to use an OracleConnectionCacheImpl. This object will provide a pool of reusable connection. You can specify the minimum and maximum number of physical database connection you want, and what you want to do when all physical database connections are in use.



The following example shows how you can use the OracleConnectionPoolDataSource.



/*

* Created on Oct 21, 2003 */
package org.ako.testoraclepool;

import oracle.jdbc.pool.*;
import java.sql.*;

/**

* @author akoelewi */
public class Main {

/*

* Thread to run query */
class QueryThread extends Thread {
Connection connection;
int id;
public QueryThread (String name , Connection _connection , int _id) {
super(name);
connection = _connection;
id = _id;
}
public void run() {
try {
queryUser(this.connection, this.id);
} catch (Exception e) {
e.printStackTrace();
}
}
private void queryUser(Connection _connection , int _id)
throws SQLException {

System.out.println("Starting query: " + _id);
PreparedStatement stmt =
_connection.prepareStatement(
"select * from v$session"

+ " where machine like 'akoelewi%' " + " and program like 'JDBC%' " + " order by program ");
ResultSet rset = stmt.executeQuery();
while (rset.next()) {
System.out.println(
"Query #"
+ _id
+ ", osuser: "
+ rset.getString("OSUSER")
+ ", machine: "
+ rset.getString("MACHINE")
+ ", program: "
+ rset.getString("PROGRAM")
+ ", sid: "
+ rset.getString("SID")
+ ", serial: "
+ rset.getString("SERIAL#"));
}

_connection.close();
System.out.println("Done query: " + _id);
}
}

public Main() throws Exception {

OracleConnectionCacheImpl ods =

new OracleConnectionCacheImpl();
ods.setURL("jdbc:oracle:thin:@machine:port:sid");
ods.setUser("username");
ods.setPassword("password");
ods.setMaxLimit(4);
ods.setMinLimit(2);
ods.setCacheScheme (OracleConnectionCacheImpl.FIXED_WAIT_SCHEME);

for (int i = 0; i < 10; i++) {
QueryThread queryThread =
new QueryThread("query" + i

, ods.getConnection(), i);
queryThread.start();
}

}

public static void main(String[] args) throws Exception {
Main main = new Main();
}
}

10/20/2003

Apparently oracle is more amazing than i ever realized

Filed under: — andrejk @ 7:46 pm

According to Oracle 9i is already generations ahead and shows a .NET flaw the oracle database is a lot better than sqlserver. I never worked with sqlserver, only with Oracle and some open source databases like mysql, and postgresql, but it’s strange to see how some things that you take for granted can be some amazing…

10/16/2003

More on utplsql

Filed under: — andrejk @ 4:42 pm

The entry i wrote on utplsql caused more discussion than i expected. I really can’t continue this discussion without actually trying utplsql, so that’s what i did this afternoon. I installed ounit, and wrote a simple test package. It’s easy to use, and does the job. Just like my bash shell scripts ;-) I might use it on a next project. The problem with unix shell scripts is that there are a lot of pl/sql developers who are not familiar with unix and shell programming. Another advantage of utplsql is that it may become a standard for writing unit tests, which will make it easier to explain developers what to deliver when i want them to produce unit tests.

10/14/2003

utPlsql

Filed under: — andrejk @ 3:21 pm

I just received an email suggesting to look at utplsql for pl/sql unit testing. I actually downloaded utplsql a couple of days ago, but haven’t used it yet. I did see that it requires you to install some packages and tables into your database. I’m currenlty working on a large oracle applications database, not sure if the dba’s will allow me to install all of this in the database. Personally i would prefer some unit test tool which i could use without installing anything. We created some unix shell scripts which use sqlplus to run all the tests. I feel this is good enough for now.

Just to clarify why i think refactoring pl/sql is harder than refactoring java:
1) refactoring java usually doesn’t impact production data, but when refactoring sql you have to think about migrating data in production, which usually means creating a lot of migration scripts. 2) there’s no tool support for pl/sql refactoring. For java i mostly use eclipse, which makes refactoring very easy, just select a method, and use a menu option to move it to it’s own class or to a different class. Or select some java lines, and use a menu option to move it into a new method, eclipse will
determine all the parameters for you. I would really like to see some of this in pl/sql tools.

10/13/2003

We all like to read about Larry…

Filed under: — andrejk @ 11:32 pm

Mark Rittman has listed some books about Larry Ellison and Oracle. He forgot my favorite. Actually, it’s the only book i’ve ever read which is about Larry Ellison. Actually, it’s not about Larry, but he is part of the story: The Proving Ground: The Inside Story of the 1998 Sydney to Hobart Race. It’s a nice read, but it won’t tell you anything about databases :-( Now can anyone recommend me a thriller which includes steve jobs or bill gates?

Rsync

Filed under: — andrejk @ 5:01 pm


We use pvcs here for version control. Problem is that pvcs is only available on a unix server, and i do most of my development using toad on my windows laptop. It’s easy to synchronize two directories, one on my laptop, and one in my home directory on unix with rsync. Rsync is part of cygwin


rsync -auv --rsh="ssh -l <username>" --exclude "*.swp"
--exclude "*.log" --exclude "*~"
<unix_server>:<home_directory>/<project_folder> .


rsync -auv --rsh="ssh -l <username>" --exclude "*.swp"
--exclude "*.log" --exclude "*~"
. <unix_server>:<home_directory>/<project_folder>


This works ok, except for one small problem. When a file doesn’t change, size doesn’t change, and the timestamp doesn’t change, but the file mode access permission do change, these are not synchronized. This happends when i a file out of pvcs to lock it, the file permission change so that it is writable. After using rsync, the file will still be unwritable on my laptop.

10/12/2003

Refactoring (pl)sql is hard

Filed under: — andrejk @ 9:09 pm

When reading through all the articles on oo refactoring you might think that refactoring is fun. Just use some of the functions of your IDE, recompile and retest using junit or something similar.

In my current project, we are doing some serious refactoring. The problem is that we are not using java but sql and oracle pl/sql. I can tell you, refactoring pl/sql & sql is not much fun. It’s a lot of manual work.

The reason we are refactoring is that the application was not flexible enough and the code was a bit of a mess. So the first step was to clean it up. First we redesigned all the functionality, assigned all the code to separate modules based on their responsibility, and made sure we had a layered architecture. I did the design using Poseidon for Uml. Poseidon does have some bugs, but i found it really usefull. It doesn’t do ER diagrams, and it doesn’t generate sql code, but it does allow you to model the design.

I used a class diagram, in which i put packages for all the different modules we had. Per module we have one pl/sql package, and a number of tables and views. I used classes in the module for these, using stereotypes to specify the type (table, view or package). The most important part of this was to layer the modules, avoiding circular dependencies, and define very clearly what the responsibility was for every module. We started coding bottom up, moving the procedures from the old packagse to the correct place (old way: cut and past).

Unit testing is important. We created a test script for every module, testing every function in the module. We didn’t use a unit test tool, a simple (pl/)sql script is good enough. Btw, writing the test script before you start coding the module, also helps you focus on the responsibility the module has.

All of this, refactoring, using layered architectures, unit testing, are normal, everyday activities in the oo world. But they are also very useful for database projects. I guess it’s time toad gets some serious support for UML models, pl/sql unit testing and most important of all, refactoring.

10/6/2003

How not to create an accessible website

Filed under: — andrejk @ 10:43 pm

I just found the website of the city of Assen, a city in the Netherlands. It has a big image on the home page saying ‘visually handicaped’. My first though was, nice, they actually considered handicaped people when designing the page. Now, i’ve never actually worked with a braille translater, and i also don’t have to use very large fonts, but somehow using an image to help the visually handicaped doesn’t seem clever to me. You can’t easily increase the font size of an image, and a braille translater doesn’t show the image at all. Well maybe the alt attribute of the image makes sense? You know what the alt image contains? ‘Press here for a different font’... Does that make sense? Yah baby, show me a different font on my braille translater! The rest of the page also doesn’t make much sense, the actual contents is burried in 8 or 9 levels of tables, and then the paragraph titles don’t use H tags, but are just marked STRONG. That’s not something the braille translater can use to create a table of contents with.

10/2/2003

Jdeveloper ER modelling

Filed under: — andrejk @ 3:44 pm

Jdeveloper 10g finally has a data modelling diagram, which will allow you to create ER models for existing tables in your database. You can also use to it to design a new ER model, and let jdeveloper create a ddl script to create the objects in the database. Jdeveloper can also create an alter script which will update an existing schema with the changes you made in the data modelling diagram. There are still some minor problems with this. For example, if you change an attribute constraint from not null to nullable, this isn’t detected as a change by jdeveloper.
When you want to create an ER diagram for an existing schema you can simple drag the tables from your database connection onto a data modelling diagram. Jdeveloper will also draw the foreign key relationships, but only if you drag the tables involved in this relationship, at the sametime onto the diagram. This doesn’t seem to work if you drag the tables one by one.

10/1/2003

JDeveloper extension manager

Filed under: — andrejk @ 10:00 pm

Brian duff advised me to turn of some of jdeveloper features in the extension manager, to save some memory. I didn’t really look into it, untill i saw the same advice again today . I was pleasantly surprised when i opened the extension manager. It is much more fine grained and complete than i had imagined. You can really turn off and on just about every feature in Jdeveloper. I disabled some features i’m currently not using, restarted jdeveloper, and i think jdeveloper is now using about 30mb less. You can save your extension manager settings btw, using different names, so you create setups for different purposes.
I wonder if all these features that you can enable and disable in the extension manager are plugins following the plugin standard as proposed by oracle?

jdev_preferences.jpg

Powered by WordPress