1 2 3 Previous Next

lancea

40 posts
lancea

test blog 3-16 Blog

Posted by lancea Mar 16, 2011

testing ecto to the new java.net

The Bean Validation specification went final around the same time that the Java EE 6 specifications went final. The Java Persistence 2.0 specification allows for Managed classes (entities, mapped superclasses and embeddable classes) to be configured with Bean Validation constraints.

In this example we are going to use Eclipse Galileowhich you can download and then install from here. You will also need to download the Bean Validation RI and Java DB.  

Once you have installed Eclipse, downloaded the Bean Validation RI and Java DB, you will want to create a JPA project, we called ours JPA-BeanValidation.
We will want to install Eclipselink 2.x in our project. You will do this by:

  • right clicking on the project
  • select properties
  • select Java Persistence
  • click the download library icon and choose Eclipselink 2.x to be installed


Screen shot 2010-05-06 at 9.34.24 AM

Next, you will need to include the Bean Validation RI and the derby jars in your project by:

  • right clicking on the project
  • select Java Build path
  • select add external jars
  • Include the following jars from the Bean Validation RI:
  • Include the following jar(s) from your Java DB install:


Screen shot 2010-05-06 at 9.35.14 AM

To exercise Bean Validation with EclipseLink, we will create the following Entity which specifies that the field name cannot exceed 10 characters and that the id and name fields cannot be null:

package demo;
import java.io.Serializable;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

/**
 * Entity implementation class for Entity: Player
 *
 */
@Entity

public class Player implements Serializable {

        
        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        @NotNull
        private int id;
        
        @NotNull
        @Size(max=10)
        private String name;
        
        public Player() {
        
        }
        public Player(String name) {
                this.setName(name);
        }

        public void setId(int id) {
                this.id = id;
        }

        public int getId() {
                return id;
        }

        public void setName(String name) {
                this.name = name;
        }

        public String getName() {
                return name;
        }
   
}

Create a client application to test that Bean Validation is enabled in Java SE:

package demo;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import demo.Player;

public class Client {
        private EntityManagerFactory emf;
        private EntityManager em;

        public Client() {
                emf = Persistence.createEntityManagerFactory("DerbyEmbeddedPU");
                em = emf.createEntityManager();
        }

        
        public static void main(String[] args) {
                Client pgm = new Client();
                pgm.run();
        }

        private void run() {
                em.getTransaction().begin();
                em.persist(new Player("Lance"));
                em.persist(new Player("Lance Andersen"));
                em.getTransaction().commit();

                List players = em.createQuery("Select p from Player p")
                                .getResultList();
                for (Player p : players) {
                        System.out.println("Player:" + p);
                }

        }

}

Here is the persistence.xml that is being used with the application:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="DerbyEmbeddedPU" transaction-type="RESOURCE_LOCAL">
     <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>     <class>demo.Player</class>     <properties>       <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>       <property name="javax.persistence.jdbc.url"                                 value="jdbc:derby:/file/databases/testDB;create=true"/>       <property name="javax.persistence.jdbc.user" value="APP"/>       <property name="javax.persistence.jdbc.password" value=" APP"/>       <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>       <property name="eclipselink.logging.level" value="FINEST"/>     </properties>   </persistence-unit> </persistence>

We are using the Java DB embedded JDBC driver and our database will be created when the application connects if it does not already exist. You will need to modify the properties to match what is required for your environment.

Validation will be automatically enabled because we added the Bean Validation RI to the classpath of our project. When we run the application we will get the following exception:

<[EL Config]: 2010-05-06 12:58:09.63--ServerSession(1464447632)--Thread(Thread[main,5,main])--The access type for the persistent class [class demo.Player] is set to [FIELD].
[EL Config]: 2010-05-06 12:58:09.654--ServerSession(1464447632)--Thread(Thread[main,5,main])--The alias name for the entity class [class demo.Player] is being defaulted to: Player.
[EL Config]: 2010-05-06 12:58:09.656--ServerSession(1464447632)--Thread(Thread[main,5,main])--The table name for entity [class demo.Player] is being defaulted to: PLAYER.
[EL Config]: 2010-05-06 12:58:09.665--ServerSession(1464447632)--Thread(Thread[main,5,main])--The column name for element [field id] is being defaulted to: ID.
[EL Config]: 2010-05-06 12:58:09.667--ServerSession(1464447632)--Thread(Thread[main,5,main])--The column name for element [field name] is being defaulted to: NAME.
log4j:WARN No appenders could be found for logger (org.hibernate.validator.util.Version).
log4j:WARN Please initialize the log4j system properly.
[EL Info]: 2010-05-06 12:58:10.402--ServerSession(1464447632)--Thread(Thread[main,5,main])--EclipseLink, version: Eclipse Persistence Services - 2.0.1.v20100213-r6600
[EL Fine]: 2010-05-06 12:58:11.317--Thread(Thread[main,5,main])--Detected Vendor platform: org.eclipse.persistence.platform.database.JavaDBPlatform
[EL Config]: 2010-05-06 12:58:11.332--ServerSession(1464447632)--Connection(1898052961)--Thread(Thread[main,5,main])--connecting(DatabaseLogin(
        platform=>JavaDBPlatform
        user name=> "APP"
        datasource URL=> "jdbc:derby:/Users/lanceandersen/Java_EE/glassfishv3/databases/testDB;create=true"
))
[EL Config]: 2010-05-06 12:58:11.334--ServerSession(1464447632)--Connection(2062322058)--Thread(Thread[main,5,main])--Connected: jdbc:derby:/Users/lanceandersen/Java_EE/glassfishv3/databases/testDB
        User: APP
        Database: Apache Derby  Version: 10.5.3.0 - (802917)
        Driver: Apache Derby Embedded JDBC Driver  Version: 10.5.3.0 - (802917)
[EL Config]: 2010-05-06 12:58:11.335--ServerSession(1464447632)--Connection(1060766226)--Thread(Thread[main,5,main])--connecting(DatabaseLogin(
        platform=>JavaDBPlatform
        user name=> "APP"
        datasource URL=> "jdbc:derby:/Users/lanceandersen/Java_EE/glassfishv3/databases/testDB;create=true"
))
[EL Config]: 2010-05-06 12:58:11.336--ServerSession(1464447632)--Connection(1062659565)--Thread(Thread[main,5,main])--Connected: jdbc:derby:/Users/lanceandersen/Java_EE/glassfishv3/databases/testDB
        User: APP
        Database: Apache Derby  Version: 10.5.3.0 - (802917)
        Driver: Apache Derby Embedded JDBC Driver  Version: 10.5.3.0 - (802917)
[EL Info]: 2010-05-06 12:58:11.367--ServerSession(1464447632)--Thread(Thread[main,5,main])--file:/Users/lanceandersen/Documents/workspace/JPA-BeanValidation/build/classes/_DerbyEmbeddedPU login successful
[EL Fine]: 2010-05-06 12:58:11.387--ServerSession(1464447632)--Connection(1062659565)--Thread(Thread[main,5,main])--DROP TABLE PLAYER
[EL Fine]: 2010-05-06 12:58:11.674--ServerSession(1464447632)--Connection(1062659565)--Thread(Thread[main,5,main])--CREATE TABLE PLAYER (ID INTEGER GENERATED ALWAYS AS IDENTITY NOT NULL, NAME VARCHAR(255), PRIMARY KEY (ID))
Exception in thread "main" javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:'prePersist'. Please refer to embedded ConstraintViolations for details.
        at org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener.validateOnCallbackEvent(BeanValidationListener.java:90)
        at org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener.prePersist(BeanValidationListener.java:62)
        at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyListener(DescriptorEventManager.java:670)
        at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyEJB30Listeners(DescriptorEventManager.java:613)
        at org.eclipse.persistence.descriptors.DescriptorEventManager.executeEvent(DescriptorEventManager.java:200)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectClone(UnitOfWorkImpl.java:4231)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNotRegisteredNewObjectForPersist(UnitOfWorkImpl.java:4208)
        at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.registerNotRegisteredNewObjectForPersist(RepeatableWriteUnitOfWork.java:424)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4148)
        at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:368)
        at demo.Client.run(Client.java:31)
        at demo.Client.main(Client.java:25)

The error occurs because:

em.persist(new Player("Lance Andersen"));

specifies a value for the name field which exceeds the max length allowed due to the validation constraint specified which indicated that the maximum length was 10.

We can disable validation by adding the validation-mode element to the persistence.xml with a value of NONE:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="DerbyEmbeddedPU" transaction-type="RESOURCE_LOCAL">
     <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>     <class>demo.Player</class>    <validation-mode>NONE</validation-mode>     <properties>       <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>       <property name="javax.persistence.jdbc.url"                                 value="jdbc:derby:/file/databases/testDB;create=true"/>       <property name="javax.persistence.jdbc.user" value="APP"/>       <property name="javax.persistence.jdbc.password" value=" APP"/>       <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>       <property name="eclipselink.logging.level" value="FINEST"/>     </properties>   </persistence-unit> </persistence>

The values that may be specified for the validation-mode element are:

  • AUTO (default if the validatione-mode element is not specified)
  • NONE
  • CALLBACK (enables validation but generates an error if their is no validation provider available)

When we re-run the application, we will no longer see the validation error due to validation being disabled:

[EL Config]: 2010-05-06 12:41:05.792--ServerSession(661272757)--Thread(Thread[main,5,main])--The access type for the persistent class [class demo.Player] is set to [FIELD].
[EL Config]: 2010-05-06 12:41:05.816--ServerSession(661272757)--Thread(Thread[main,5,main])--The alias name for the entity class [class demo.Player] is being defaulted to: Player.
[EL Config]: 2010-05-06 12:41:05.818--ServerSession(661272757)--Thread(Thread[main,5,main])--The table name for entity [class demo.Player] is being defaulted to: PLAYER.
[EL Config]: 2010-05-06 12:41:05.828--ServerSession(661272757)--Thread(Thread[main,5,main])--The column name for element [field id] is being defaulted to: ID.
[EL Config]: 2010-05-06 12:41:05.829--ServerSession(661272757)--Thread(Thread[main,5,main])--The column name for element [field name] is being defaulted to: NAME.
[EL Info]: 2010-05-06 12:41:06.403--ServerSession(661272757)--Thread(Thread[main,5,main])--EclipseLink, version: Eclipse Persistence Services - 2.0.1.v20100213-r6600
[EL Fine]: 2010-05-06 12:41:07.177--Thread(Thread[main,5,main])--Detected Vendor platform: org.eclipse.persistence.platform.database.JavaDBPlatform
[EL Config]: 2010-05-06 12:41:07.192--ServerSession(661272757)--Connection(1377144006)--Thread(Thread[main,5,main])--connecting(DatabaseLogin(
        platform=>JavaDBPlatform
        user name=> "APP"
        datasource URL=> "jdbc:derby:/Users/lanceandersen/Java_EE/glassfishv3/databases/testDB;create=true"
))
[EL Config]: 2010-05-06 12:41:07.194--ServerSession(661272757)--Connection(63323788)--Thread(Thread[main,5,main])--Connected: jdbc:derby:/Users/lanceandersen/Java_EE/glassfishv3/databases/testDB
        User: APP
        Database: Apache Derby  Version: 10.5.3.0 - (802917)
        Driver: Apache Derby Embedded JDBC Driver  Version: 10.5.3.0 - (802917)
[EL Config]: 2010-05-06 12:41:07.195--ServerSession(661272757)--Connection(1278499651)--Thread(Thread[main,5,main])--connecting(DatabaseLogin(
        platform=>JavaDBPlatform
        user name=> "APP"
        datasource URL=> "jdbc:derby:/Users/lanceandersen/Java_EE/glassfishv3/databases/testDB;create=true"
))
[EL Config]: 2010-05-06 12:41:07.196--ServerSession(661272757)--Connection(1278255007)--Thread(Thread[main,5,main])--Connected: jdbc:derby:/Users/lanceandersen/Java_EE/glassfishv3/databases/testDB
        User: APP
        Database: Apache Derby  Version: 10.5.3.0 - (802917)
        Driver: Apache Derby Embedded JDBC Driver  Version: 10.5.3.0 - (802917)
[EL Info]: 2010-05-06 12:41:07.227--ServerSession(661272757)--Thread(Thread[main,5,main])--file:/Users/lanceandersen/Documents/workspace/JPA-BeanValidation/build/classes/_DerbyEmbeddedPU login successful
[EL Fine]: 2010-05-06 12:41:07.245--ServerSession(661272757)--Connection(1278255007)--Thread(Thread[main,5,main])--DROP TABLE PLAYER
[EL Fine]: 2010-05-06 12:41:07.486--ServerSession(661272757)--Connection(1278255007)--Thread(Thread[main,5,main])--CREATE TABLE PLAYER (ID INTEGER GENERATED ALWAYS AS IDENTITY NOT NULL, NAME VARCHAR(255), PRIMARY KEY (ID))
[EL Fine]: 2010-05-06 12:41:07.615--ClientSession(1171248050)--Connection(1278255007)--Thread(Thread[main,5,main])--INSERT INTO PLAYER (NAME) VALUES (?)
        bind => [Lance]
[EL Fine]: 2010-05-06 12:41:07.749--ClientSession(1171248050)--Connection(1278255007)--Thread(Thread[main,5,main])--values IDENTITY_VAL_LOCAL()
[EL Fine]: 2010-05-06 12:41:07.772--ClientSession(1171248050)--Connection(1278255007)--Thread(Thread[main,5,main])--INSERT INTO PLAYER (NAME) VALUES (?)
        bind => [Lance Andersen]
[EL Fine]: 2010-05-06 12:41:07.774--ClientSession(1171248050)--Connection(1278255007)--Thread(Thread[main,5,main])--values IDENTITY_VAL_LOCAL()
[EL Fine]: 2010-05-06 12:41:08.019--ServerSession(661272757)--Connection(1278255007)--Thread(Thread[main,5,main])--SELECT ID, NAME FROM PLAYER
Player:demo.Player@3db158db
Player:demo.Player@4631ff23

Eclipselink 2.0 includes an annotation processor for generating the static metamodel classes from your Entity classes for use with the Criteria API which is one of the new features in JPA 2.0.

Here is an example of generating the metamodel classes from the command line using the Eclipselink annotation processor:


javac -processor org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor -sourcepath src -d src -classpath /ace2_apps/eclipselink/jlib/eclipselink.jar:.:/ace2_apps/eclipselink/jlib/JPA/javax.persistence_2.0.0.v200911271158.jar -proc:only -Aeclipselink.persistencexml=src/META-INF/persistence.xml src/demo/*.java
Note: Creating the metadata factory ...
Note: Building metadata class for round element: demo.Item
Note: Building metadata class for round element: demo.Order
Note: Found Option : eclipselink.persistencexml, with value: src/META-INF/persistence.xml
Note: File was not found: META-INF/orm.xml
Note: File was not found: META-INF/eclipselink-orm.xml
Note: Found Option : eclipselink.persistencexml, with value: src/META-INF/persistence.xml
Note: File was not found: META-INF/orm.xml
Note: File was not found: META-INF/eclipselink-orm.xml
warning: The following options were not recognized by any processor: '[eclipselink.persistencexml]'


In the above example, the metamodel classes demo.Item_.java and demo.Order_.java were generated and placed in the demo directory where the Entity classes reside.


Netbeans 6.8 has recently been released which provides support for many Java EE 6 features. Unfortunately, there is no support for generating the metamodel classes at this time.


However, it is easy to update your project to provide this support following these steps:


1. Add the following target to your projects build.xml file:

<target name="generate-metamodel" depends="init">
<property name="metaPackage" value="metamodel"/>
<delete>
    <fileset dir="${src.dir}"  includes="**/*_.java"/>
</delete>
<echo message="generating MetaData "/>
<javac   srcdir="${src.dir}" verbose="false"
    destdir="${src.dir}"
    excludes="demo/**"
    classpath="${javac.classpath}">
    <compilerarg line=" -processor org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor" />
    <compilerarg line=" -proc:only" compiler="javac1.6" />

</javac>

</target>

A couple of notes about the target above:

  • Each time you want to regenerate the metamodel classes, you must delete the previous ones or you will receive an error.
  • The target excludes running the annotation processor against the directory that has the code which references the metamodel classes (demo in the target) otherwise you will see some errors yet the metamodel classes will still be generated.

Once you have added the target to the build.xml, you will want to add a menu option to make it easier to invoke the target. You can do this by:

1. Right clicking on the name of the target and "Create Shortcut"


CreateMenuItem.JPG

2. Indicate that you are adding a "Menu Item"


Wizard1.JPG

3. Select "Refactor" for where to add the Menu Item.


Wizard2.JPG

Now you are ready to use the new target which you can access from the refactor menu:


ShowMenuItem.JPG

The Netbeans project, CriteriaStaticMetaModelDemo, provides a simple set of examples on how to use the Criteria AP. The queries that are provided access the metamodel dynamically and statically as well as demonstrate String based navigation.

The code for using the static metamodel example looks like:

private void staticMetaModel() {
System.out.println("***Running static metamodel Example*****"); 

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<League> cq = cb.createQuery(League.class);
Root<League> league = cq.from(League.class);
cq.select(league);
ParameterExpression<Gender> genderType =
cb.parameter(Gender.class, "gender");

cq.where(cb.equal(league.get(League_.gender), genderType));

TypedQuery<League> tq = em.createQuery(cq);
tq.setParameter(genderType, Gender.Mixed);
List<League> rs = tq.getResultList();
displayLeagues(rs);

CriteriaQuery<String> cq2 = cb.createQuery(String.class);
Root<Team> team = cq2.from(Team.class);
cq2.select(team.get(Team_.name)).where(cb.like(team.get(Team_.name), "Longfellow%"));
TypedQuery tq2 = em.createQuery(cq2);
List<String> teamNames = tq2.getResultList();
displayTeamNames(teamNames);
}


The example creates two queries using the Criteria API. The first query will select all leagues whose gender is equal to "Mixed". Gender is a Enum.

The 2nd query will return all teams whose name begins with "Longfellow".

The static metamodel classes are generated by appending an "_" to the name of the entity. In the example above, League_ and Team_ are the static metamodel classes that were generated for the entities League and Team.

Both queries are quite trivial but show how you can create strongly typed queries using the static metamodel.


For more information on JPA 2.0:

[1] JPA 2.0 Specification

[2]Eclipselink metamodel Annotation Processor Documentation

[3] CriteriaStaticMetaModelDemo

One of the many cool new features in Java EE 6, is support for the DataSourceDefinition annotation.

The DataSourceDefinition annotation provides a way to define a DataSource and register it with JNDI. The annotation provided annotation elements for the commonly used DataSource properties. Additional standard and vendor specific properties may also be specified.

So let us look at an example:

@DataSourceDefinition(name = "java:global/MyApp/myDS",
className = "org.apache.derby.jdbc.ClientDataSource",
portNumber = 1527,
serverName = "localhost",
databaseName = "testDB",
user = "lance",
password = "secret",
properties = {"createDatabase=create"}) )

The data source will be registered using the value specified in the name element and can be defined in any valid Java EE name space and that will determine the accessibility of the data source from other components.

The properties element is used to specify less frequently used standard DataSource properties as well as vendor-specified properties using the format :

{"property1=value", "property2=value" ...}

Using the newly defined DataSource is as simple as:

  @Resource(lookup = "java:global/MyApp/myDS")
  private DataSource ds;

You can also define multiple DataSources using the DataSourceDefinitions annotation:

@DataSourceDefinitions({
  @DataSourceDefinition(name = "java:global/MyApp/myDS",
  className = "org.apache.derby.jdbc.ClientDataSource",
  portNumber = 1527,
  serverName = "localhost",
  databaseName = "testDB21",
  user = "lance",
  password = "secret",
  properties = {"createDatabase=create"}),
  @DataSourceDefinition(name = "java:global/MyApp/myDS2",
  className = "com.mysql.jdbc.jdbc2.optional.MysqlDataSource",
  portNumber = 3306,
  serverName = "localhost",
  databaseName = "dogDB",
  user = "luckyDog",
  password = "shhh",
  properties = {"pedantic=true"})
})

So let's look at a simple web application, DataSourceDefWebApp, which utilizes the DataSourceDefinition. The application is provided as a NetBeans project that was created with NetBeans 6.8.

The application when deployed, will create a DataSource for Java DB.

When you go to run the application, you will need to make sure that you have the Java DB client JDBC driver accessible to your appserver, which it will be for Glassfish V3 and the Java DB server started.

To run the application after you have deployed it, go to the following URL using your favorite browser:

http://<host>:<port>/DataSourceDefWebApp

When you first run the application, you will see the following menu. Select the menu option "Initialize the Database", to create the Java DB database and create two initial contacts.

AdminMenu.JPG

After initializing the database you can select "Add a Contact" to add a new contact to your database.

AddContact.JPG

When you click the "Add Contact", button you will be taken to the displayContacts page.

DisplayDerby.JPG ,  

The application defines the DataSource in the DataSourceDefServlet:

@DataSourceDefinition(name = "java:global/MyApp/myDS",
className = "org.apache.derby.jdbc.ClientDataSource",
portNumber = 1527,
serverName = "localhost",
databaseName = "testDB",
user = "lance",
password = "secret",
properties = {"createDatabase=create"})
@WebServlet(name = "DataSourceDefServlet", urlPatterns = {"/DataSourceDefServlet", "/displayContacts", "/addContact", "/initDB"})
public class DataSourceDefServlet extends HttpServlet {

  private ServletContext context;
  @Resource(lookup = "java:global/MyApp/myDS")
  private DataSource ds;


The DataSourceDefinition annotation is specified above the class declaration. The Resource annotation is then used specifying the JNDI name that was defined in DataSourceDefinition.
The Stateless Session bean, DemoBean, also uses the Resource annotation to access the same DataSource via:

@Resource(lookup = "java:global/MyApp/myDS")
  private DataSource ds;

You can also override the settings that you have specified in the DataSourceDefinition annotation by adding the data-source element to your web.xml. For example, in order to use a MySQL database instead of Java DB, you can create a web.xml and add the following (remember to adjust the properties as necessary):

    <data-source>

        <description>DataSource for MySQL</description>
        <name>java:global/MyApp/myDS</name>
        <class-name>com.mysql.jdbc.jdbc2.optional.MysqlDataSource</class-name>
        <server-name>localhost</server-name>

        <port-number>3306</port-number>
        <database-name>testDB</database-name>
        <user>lance</user>
        <password>secret</password>

        <property>
            <name>x</name>
            <value>y</value>
        </property>
        <property>

            <name>y</name>
            <value>x</value>
        </property>
        <login-timeout>500</login-timeout>

        <transactional>false</transactional>
        <isolation-level>TRANSACTION_READ_COMMITTED</isolation-level>
        <initial-pool-size>2</initial-pool-size>
        <max-pool-size>5</max-pool-size>

        <min-pool-size>1</min-pool-size>
        <max-idle-time>500</max-idle-time>
        <max-statements>100</max-statements>
    </data-source>


In the top level directory of the DataSourceDefinitionWebApp, you will find a web.xml that you can move to the web/WEB-INF folder of the project. Adjust the properties for the data-source to correctly point to your MySQL database, then rebuild and deploy.

When you go to display the data, you will notice that the the output from displayContacts indicates thatthe database that is being used in MySQL

OverrideWithMysql.JPG 

The DataSourceDefinition annotation is a simple yet powerful addition to Java EE 6. Enjoy!

References:

A gentle guide to getting started with OpenJDK and Mercurial on Solaris

Technorati Tags: Mercurial, OpenJDK

As I am about ready to start checking in some bug fixes and enhancements to the JDBC and RowSet code in Java SE, i figured i should finally spend some time configuring my Solaris 10 box for Mercurial. It was a bit of an adventure, so I hope the following will help you avoid a few of the pitfalls that I encountered.

I decided that I wanted to avoid building Mercurial myself, figuring using pre-built version would be the way to go. The Mercurial web site suggests to download the binary from sunfreeware.com or blastwave.orgfor Solaris. I decided to get the software from sunfreeware.com. As I am running on Solaris 10, i need to go to the Solaris 10 section on sunfreeware.com. In order to install Mercurial, you will need to get the following packages (assuming you did not have them installed):

After downloading the packages, su toroot and execute the following commands:

gunzip mercurial-1.1.2-sol10-sparc-local.gz 
gunzip libgcc-3.4.6-sol10-sparc-local.gz 
gnuzip python-2.5.1-sol10-sparc-local.gz 
pkgadd -d mercurial-1.1.2-sol10-sparc-local
pkgadd -d libgcc-3.4.6-sol10-sparc-local 
pkgadd -d python-2.5.1-sol10-sparc-local
pkgadd -d openssl-0.9.8k-sol10-sparc-local

Note: Please make sure you grab the correct version of openssl as the build differs based on your platform.

Everything installed cleanly and an hg versionseemed to work fine. So next i was ready to install the Forest Extension which is required by OpenJDK(Note: I would create a directory to host your Mercurial extensions and workspaces and cd to it prior to running the following hg command):

However, when I went to run the above command, i encountered the following error:

ace2 183 =>/usr/local/bin/hg clone
http://bitbucket.org/pmezard/hgforest-crew
real URL is http://bitbucket.org/pmezard/hgforest-crew/
destination directory: hgforest-crew
Traceback (most recent call last):
File "/usr/local/bin/hg", line 20, in 
  mercurial.dispatch.run()
File "/usr/local/lib/python2.5/site-packages/mercurial/dispatch.py",
line 20, in run
  sys.exit(dispatch(sys.argv[1:]))
File "/usr/local/lib/python2.5/site-packages/mercurial/dispatch.py",
line 29, in dispatch
  return _runcatch(u, args)
File "/usr/local/lib/python2.5/site-packages/mercurial/dispatch.py",
line 79, in _runcatch
  except revlog.RevlogError, inst:
File
"/usr/local/lib/python2.5/site-packages/mercurial/demandimport.py", line
74, in __getattribute__
  self._load()
File
"/usr/local/lib/python2.5/site-packages/mercurial/demandimport.py", line
46, in _load
  mod = _origimport(head, globals, locals)
File "/usr/local/lib/python2.5/site-packages/mercurial/revlog.py",
line 20, in 
  _compress = zlib.compress
File
"/usr/local/lib/python2.5/site-packages/mercurial/demandimport.py", line
74, in __getattribute__self._load()
File
"/usr/local/lib/python2.5/site-packages/mercurial/demandimport.py", line
46, in _loadmod = _origimport(head, globals, locals)
ImportError: ld.so.1: python: fatal: relocation error: file
/usr/local/lib/python2.5/lib-dynload/zlib.so: symbol inflateCopy:
referenced symbol not found

I would also encounter the same error above if I did the following:

/opt/csw/bin/python -c "import zlib"

Googling did not shed a whole lot of light outside of others have seen this before. I was able to get past the error above by putting /usr/local/bin at the front of myPATH variable and unsetting myLD_LIBRARY_PATH variable. However, i then encountered the following error when I tried again to get the Forest Extension:


abort: could not import module _md5!

You will encounter this error if you have not installed openssl.

As I did not find out at the time that I needed openssl, I decided to give up and try installing using the binaries from blastwave.org. The installation instructions can be found here. However, here are the basic steps(Note: you must be logged in asroot):

First you must get pkgutil installed:

  • pkgadd -d http://blastwave.network.com/csw/pkgutil_`/sbin/uname -p`.pkg (select default )
  • mkdir /etc/opt/csw
  • cp -p /opt/csw/etc/pkgutil.conf.CSW /etc/opt/csw/pkgutil.conf
  • /opt/csw/bin/pkgutil --catalog
  • /opt/csw/bin/pkgutil --install gnupg textutils (selectY)
  • /opt/csw/bin/gpg --keyserver pgp.mit.edu --recv-keys A1999E90
  • /opt/csw/bin/gpg --list-keys
  • /opt/csw/bin/gpg --edit-key A1999E90 (selectTrust and then option 5)
  • vi /etc/opt/csw/pkgutil.conf and uncomment outuse_gpg and use_md5

Now we are ready to install the packages:

  • pkgutil --install common
  • pkgutil --install python
  • pkgutil --install mercurial

Set your PATH so that/opt/csw/bin is at the front of yourPATH:

setenv PATH /opt/csw/bin:${PATH}

or

PATH=/opt/csw/bin:${PATH};export PATH

Let us see if we can get hg going after our install:

# /opt/csw/bin/hg
Traceback (most recent call last):
File "/opt/csw/bin/hg", line 11, in 
  from mercurial import demandimport; demandimport.enable()
ImportError: No module named mercurial

Googling indicated that I would need to possibly setPYTHONPATH to where mysite-packages directory was:

PYTHONPATH=/opt/csw/lib/python/site-packages/

OK, let us try again:

hg version
Mercurial Distributed SCM (version 1.1.2)

Copyright (C) 2005-2008 Matt Mackall  and others
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Success!

Now, one thing that I noticed was that when I did the install of mercurial and python, I ended up with apython and python2.5 directory in/opt/csw/lib. The sole contents ofpython was the site-packagesdirectory and this directory was for some reason not in thepython2.5 directory. I decided to create a symbolic link so that the site-packages was accessible via the python2.5 directory and then unset the PYTHONPATH variable and see if I had better luck with hg and I did. I had a fully working mercurial environment!

Next it was time to try to bring over the latest Forest Extension again via (remember to cd to where you want to install the forest extension):

hg clone http://bitbucket.org/pmezard/hgforest-crew/

This worked fine. Next, in my home directory, I created a.hgrc file which looks like:

[ui]
username=lancea
[extensions]
forest=/ace2_apps/openjdk/hgforest-crew/forest.py
fetch=

The username property is set to what I want my checkin comments to use as my name. The forestproperty is set to where I installed the Forest Extension.

Next I want to make sure that hg can see the Forest Extension that I just configured in my .hg file:

ace2 193 =>hg
Mercurial Distributed SCM

basic commands:

add        add the specified files on the next commit
annotate   show changeset information per file line
clone      make a copy of an existing repository
commit     commit the specified files or all outstanding changes
diff       diff repository (or selected files)
export     dump the header and diffs for one or more changesets
fclone     make a clone of an existing forest of repositories
fpull      pull changes from the specified forest
fpush      push changes to the specified forest.
fstatus    show changed files in the working forest
fupdate    update working forest
init       create a new repository in the given directory
log        show revision history of entire repository or files
merge      merge working directory with another revision
parents    show the parents of the working dir or revision
pull       pull changes from the specified source
push       push changes to the specified destination
remove     remove the specified files on the next commit
serve      export the repository via HTTP
status     show changed files in the working directory
update     update working directory

use "hg help" for the full list of commands or "hg -v" for details

If your .hgrc is set up correctly you should see commands such as fclone andfupdate in the list of basic hg commands.

Now you are ready to create a clone an OpenJDK 6 or OpenJDK 7 project. For OpenJDK 7, I am going to clone the tlproject forest as this is where the JDBC code lives using thefclone command:

If you want to clone the OpenJDK 6 project, you would do the following:

There is also a sandbox play area within the OpenJDK project are so that you can get familiar with mercurial and you can clone a copy using the following commands:

This is a great way to get familiar with hg commands.

In order to push back changesets you will need to generate an ssh key and email it tokeys@openjdk.java.net. Use the ssh-keygen command and make sure to specify a passphrase:

  • ssh-keygen -t rsa -b 4096

This will generate a ~/.ssh/id_rsa.pub text file containing the public ssh key which you will email to keys@openjdk.java.net. In order to be able to push changesets back to OpenJDK projects, you must be granted permission. Please see Producing a Changset and How to Contribute for details.

I hope you found this blog useful and hopefully it will help you overcome a few of the the speed-bumps that I encountered. I also want to thank Kelly O'Hair who helped keep me sane and made sure that I was not missing the obvious.

May I also suggest that you check out Project Kenai, a new Sun sponsored web site for hosting your Open Source projects that also supports Mercurial. This is where the JavaMail RI and the Corba Glassfish V3 RI projects reside.

Additional resources on Mercurial and OpenJDK can be found at:

  1. Mercurial: The Definitive Guide
  2. OpenJDK Developer's Guide
Giri, has done a very nice job creating a tutorial on using MySQL Connector/C++

This Connector is modeled after JDBC making it very easy to access MySQL using C++.

MySQL 5.1 and MySQL 5.1 Connector/J 5.1 have been officially released. Connector/J 5.1 adds support for JDBC 4.0. You can download Connector/J and find out additional info regarding JDBC 4.0 support here.  
Check out Knut Anders Hatlen's blogon how to specify your own collator allowing you to have more control over the ordering of data in Apache Derby and Java DB.  

The MySQL Connector/C++ Connector project has successfully reached its first major milestone by releasing its Alpha version.

The Connector provides a C++ implementation modeled after JDBC. This allows developers who have worked with JDBC to quickly take advantage of this Connector minimizing the learning curve.

The current release provides support for many of the methods found in the following JDBC interfaces:

  • java.sql.Connection
  • java.sql.DatabaseMetaData
  • java.sql.Driver
  • java.sql.PreparedStatement
  • java.sql.ResultSet
  • java.sql.ResultsetMetaData
  • java.sql.Savepoint
  • java.sql.Statement

Examples of using MySQL Connector/C++

Here is an example which connects to a MySQL Server, creates a table and then inserts a row into the table

      sql::mysql::MySQL_Driver *driver;
      sql::Connection *con;
      sql::Statement *stmt

       driver = sql::mysql::get_mysql_driver_instance();
       con = driver->connect("tcp://localhost:3306", "user", "password");

       stmt = con->createStatement();
       stmt->executeUpdate("DROP TABLE IF EXISTS CONTACTS");
       stmt->executeUpdate("CREATE TABLE CONTACTS(ID INT NOT NULL AUTO_INCREMENT, FNAME VARCHAR(25), LNAME VARCHAR(25), PHONE VARCHAR(12))");
       stmt->executeUpdate("INSERT INTO CONTACTS( FNAME, LNAME, PHONE) VALUES ('Bruce', 'Wayne', '555 555-5555')");

       delete stmt;
       delete con;

This example uses a PreparedStatement to insert a couple of rows

        sql::mysql::MySQL_Driver *driver;
        sql::Connection *con;
        sql::PreparedStatement *pstmt
        driver = sql::mysql::get_mysql_driver_instance();
        con = driver->connect("tcp://localhost:3306", "user", "password");
               
        pstmt = con->prepareStatement("INSERT INTO CONTACTS( FNAME, LNAME, PHONE) VALUES ( ?, ?, ?)");
        
        pstmt->setString(1, "Dick");
        pstmt->setString(2, "Grayson");
        pstmt->setString(3, "222 222-2222");
        pstmt->executeUpdate();
        
        pstmt->setString(1, "Clark");
        pstmt->setString(2, "Kent");
        pstmt->setString(3, "333 333-3333");
        pstmt->executeUpdate();
        
        delete pstmt;
        delete con;

This example uses a uses a PreparedSatement to execute a query and then process a ResultSet. Notice that you can reference the columns via an ordinal or a column name

        sql::mysql::MySQL_Driver *driver;
        sql::Connection *con;
        sql::PreparedStatement *pstmt;
        sql::ResultSet *rs;

        driver = sql::mysql::get_mysql_driver_instance();
        con = driver->connect("tcp://localhost:3306", "user", "password");
               
        pstmt = con->prepareStatement("SELECT * FROM CONTACTS WHERE ID= ?");      
        pstmt->setInt(1, 2);     
        rs= pstmt->executeQuery();

        while (rs->next()) {  
           cout << "ID = "  << rs->getInt(0);
           cout <<", First Name = '"  <<rs->getString("FNAME")  << "'";
           cout <<", Last Name = '"  <<rs->getString("LNAME")  << "'";
           cout <<", Phone = '"  <<rs->getString(3)  << "'"  << endl;

        }

        delete rs;                  
        delete pstmt;
        delete con;

As you can see from the above examples, the MySQL Connector/C++ connector provides a simple API modeled on JDBC for accessing your MySQL data.

The MySQL Connector/C++ connector is being used today by MySQL Workbench and theMySQL/OpenOffice.org Connector. We hope you give it a go and let us know what you think.

For more information on MySQL Connector/C++, please refer to the following sites:

Technorati Tags: databases, JDBC, mysql

With Glassfish V3 and Netbeans 6.5, it is easy to move applications which run on Tomcat using Toplink/EclipseLink to Glassfish v3 Prelude.

The sample application contained in the zip file JPAWeb_TC6_Toplink-1.zip, is a simple web app using JSTL, Servlet, JSP and TopLink Essentials to store contact information into a MySQL database.

To Deploy and run the application on Tomcat, you need place a copy of the MySQL JDBC driver in $TOMCAT_HOME/lib and have a MySQL database which is accessible and that you have permissions to create tables in.

The application uses JNDI to access a Data Source defined on Tomcat (in our case via the context.xml). This requires you to use specify the Toplink property toplink.session.customizer in your persistence.xml indicating that a SessionCustomizer will be used so that the lookup type on the JNDI connector will be a STRING_LOOKUP instead of Composite :

 
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="JPAContactJNDIPU" transaction-type="RESOURCE_LOCAL">
    <provider>oracle.toplink.essentials.PersistenceProvider</provider>
 <non-jta-data-source>java:comp/env/jdbc/mysqlTestDB</non-jta-data-source>
    <class>demo.entity.Contact</class>
    <properties>
      <property name="toplink.session.customizer" value="demo.JNDITopLinkSessionCustomizer"/>
      <property name="toplink.logging.level" value="FINE"/>
    </properties>
  </persistence-unit>
</persistence>

The code for JNDITopLinkSessionCustomizer is:

package demo;

import javax.naming.Context;
import javax.naming.InitialContext;
import oracle.toplink.essentials.jndi.JNDIConnector;
import oracle.toplink.essentials.sessions.Session;
import oracle.toplink.essentials.tools.sessionconfiguration.SessionCustomizer;


/**
*
* @author Owner
*/
public class JNDITopLinkSessionCustomizer implements SessionCustomizer {

  /**
   * Get a dataSource connection and set it on the session with lookupType=STRING_LOOKUP
   */
  public void customize(Session session) throws Exception {
      JNDIConnector connector = null;
             Context context = null;
      try {
          context = new InitialContext();
          if (null == context) {
              throw new Exception("JNDIEclipseLinkSessionCustomizer: Context is null");
          }
          connector = (JNDIConnector) session.getLogin().getConnector(); // possible CCE
          // Change from Composite to String_Lookup
          connector.setLookupType(JNDIConnector.STRING_LOOKUP);
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
}

You will also have to modify the context.xml to point to your database:

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/JPAWeb_TC6_Toplink_To_V3">
<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" maxActive="100" maxIdle="30" maxWait="10000" name="jdbc/mysqlTestDB" password="bar" type="javax.sql.DataSource" url="jdbc:mysql://localhost:3306/mysqltest?autoReconnect=true" username="foo"/>
</Context>

You can now deploy the application using Netbeans to Tomcat and enter some simple data.

Deploytc

Run Tc

Moving the Application to Glassfish v3 Prelude

 

Moving the application from Tomcat to Glassfish v3 Prelude is very easy to do:

1. Make a copy of the application in Netbeans by right clicking on the project and selecting copy(call the copy of the project JPAWeb_TC6_Toplink_To_V3).

Copyproject

2. Under the project properties, indicate that you are going to deploy to Glassfish V3 Prelude:

Preludeprops

3. Add a JNDI Resource Entry to the sun-web.xml:

Sun-Web

4. Place the MySQL JDBC driver in $GLASSFISH_V3_HOME/glassfish/domains/domain1/lib.ext

5. Start Glassfish V3 Prelude and add a Connection Pool which points to your MySQL server and database

Connpool
Connpool2-1

5. Add JDBC Resource which uses the Connection Pool

Jdbc Resource

6. Deploy the application to Glassfish v3 Prelude

Deployv3

7. Run the application deployed on Glassfish

Run V3

Migrating from Toplink to Eclipselink

It is very easy to change your application to run with EclipseLink.

1. Add the EclipseLink library to your Netbean's project and remove the Toplink Library

Eclipselibrary

2. Change your persistence.xml to use EclipseLink (note: that the Design view of persistence.xml will allow you to change Persistence Provider, however it currently does not modify the property names when going from Toplink to Eclipselink )

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="JPAContactJNDIPU" transaction-type="RESOURCE_LOCAL">
  <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
  <non-jta-data-source>java:comp/env/jdbc/mysqlTestDB</non-jta-data-source>
  <class>demo.entity.Contact</class>
  <properties>
    <property name="eclipselink.logging.level" value="FINEST"/>
    <property name="eclipselink.session.customizer" value="demo.JNDIEclipseLinkSessionCustomizer"/>
  </properties>
</persistence-unit>
</persistence>

3. You will need to change the imports for your SessionCustomizer since EclipseLink is being used (note I changed the name of the class for clarity) JNDIEclipseLinkSessionCustomizer :

package demo;
import javax.naming.Context;
import javax.naming.InitialContext;
import org.eclipse.persistence.config.SessionCustomizer;
import org.eclipse.persistence.sessions.JNDIConnector;
import org.eclipse.persistence.sessions.Session;
/**
 *
 * @author Owner
 */
public class JNDIEclipseLinkSessionCustomizer implements SessionCustomizer {

   /**
     * Get a dataSource connection and set it on the session with lookupType=STRING_LOOKUP
     */
    public void customize(Session session) throws Exception {
        JNDIConnector connector = null;
       
        Context context = null;
        try {
            context = new InitialContext();
            if (null == context) {
                throw new Exception("JNDIEclipseLinkSessionCustomizer: Context is null");
            }
           connector = (JNDIConnector) session.getLogin().getConnector(); // possible CCE
            // Change from Composite to String_Lookup
            connector.setLookupType(JNDIConnector.STRING_LOOKUP);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

You can now run and deploy the application using EclipseLink for your persistence provider.

Doing a little more clean up if you are only going to run on Glassfish v3 Prelude



If you are just going to run on Glassfish v3 Prelude, you can make a few additional minor tweaks to your application:

1. Simplify your persistence.xml by removing the eclipselink.session.customizer (only needed for JNDI look ups on Tomcat) and simplifying your non-jta-datasource entry (you must specify java:comp/env/ when using Tomcat):

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="JPAContactJNDIPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
  <non-jta-data-source>jdbc/mysqlTestDB</non-jta-data-source>
  <class>demo.entity.Contact</class>
  <properties>
    <property name="eclipselink.logging.level" value="FINEST"/>
  </properties>
</persistence-unit>
</persistence>

2. Streamline your context.xml entry to omit the DBCP properties which are not used by Glassfish:

<Resource
      name="jdbc/mysqlTestDB"
      auth="Container"
      type="javax.sql.DataSource"/>

Technorati Tags: Glassfish, V3

In the blog "Using P6Spy and the GlassFish Connection Pool to Trace Database Operations", Jagadesh shows you how to use P6Spy. 

If you are using the Datadirect or the Sun OEM version of the Datadirect JDBC drivers, it is extremely easy to start tracing and logging the JDBC driver's database operations using DataDirect Spy.

The steps are quite simple:

  • include the spy.jar or smspy.jar (Sun OEM Datadirect drivers) in $AS_HOME/lib or $AS_HOME/domains/domain1/lib/ext, the location where you installed the JDBC drivers.
  • add the property spyAttributes to your DataSource configuration indicating the path to log the trace output to. The value specified takes the form of: log=(file)<path_to_filename>

Here is an example setting the DataDirect JDBC driver properties for Sybase:

spyproperties.GIF

When you run your application a file, in our case: /tmp/ase15.trace will be generated with the trace output for any JDBC driver access to the database.

Here is a sample of the output:

spy>> DataSource.getConnection()
spy>> Connection[9].getMetaData()
spy>> OK (DatabaseMetaData[9])
spy>> DatabaseMetaData[9].getURL()
spy>> OK (jdbc:sun:sybase://caseylou2.east:5000;CONNECTIONRETRYCOUNT=5;ALTERNATESERVERS=;DATABASENAME=lance;INITIALIZATIONSTRING=;PREPAREMETHOD=storedProcIfParam;BATCHPERFORMANCEWORKAROUND=false;AUTHENTICATIONMETHOD=UserIdPassword;CONVERTNULL=1;USEALTERNATEPRODUCTINFO=false;ERRORBEHAVIOR=Exception;RESULTSETMETADATAOPTIONS=0;TRANSACTIONMODE=explicit;SELECTMETHOD=direct;JAVADOUBLETOSTRING=false;LOADLIBRARYPATH=;SERVICEPRINCIPALNAME=;CONNECTIONRETRYDELAY=1;QUERYTIMEOUT=0;INSENSITIVERESULTSETBUFFERSIZE=2048;MAXPOOLEDSTATEMENTS=0;WORKAROUNDS=0;CODEPAGEOVERRIDE=;LOADBALANCING=false)
  spy>>DatabaseMetaData[9].getDriverName()
spy>> OK (Sybase)
spy>> DatabaseMetaData[9].getDriverVersion()
spy>> OK (3.60.23 (023730.010811.009520))
spy>> DatabaseMetaData[9].getDatabaseProductName()
spy>> OK (Adaptive Server Enterprise)
spy>> DatabaseMetaData[9].getDatabaseProductVersion()
spy>> OK (Adaptive Server Enterprise/15.0.2/EBF 14332/P/NT (IX86)/Windows 2000/ase1502/2486/32-bit/OPT/Thu May 24 04:10:36 2007)
spy>>Connection Options :
spy>> CONNECTIONRETRYCOUNT=5
spy>> ALTERNATESERVERS=
spy>> DATABASENAME=lance
spy>> INITIALIZATIONSTRING=
spy>> PREPAREMETHOD=storedProcIfParam
spy>> BATCHPERFORMANCEWORKAROUND=false
spy>> AUTHENTICATIONMETHOD=UserIdPassword
spy>> CONVERTNULL=1
spy>> USEALTERNATEPRODUCTINFO=false
spy>> ERRORBEHAVIOR=Exception
spy>> RESULTSETMETADATAOPTIONS=0
spy>> TRANSACTIONMODE=explicit
spy>> SELECTMETHOD=direct
spy>> JAVADOUBLETOSTRING=false
spy>> LOADLIBRARYPATH=
spy>> SERVICEPRINCIPALNAME=
spy>> CONNECTIONRETRYDELAY=1
spy>> QUERYTIMEOUT=0
spy>> INSENSITIVERESULTSETBUFFERSIZE=2048
spy>> MAXPOOLEDSTATEMENTS=0
spy>> WORKAROUNDS=0
spy>> CODEPAGEOVERRIDE=
spy>> LOADBALANCING=false
spy>> Driver Name = Sybase
spy>> Driver Version = 3.60.23 (023730.010811.009520)
spy>> Database Name = Adaptive Server Enterprise
spy>> Database Version = Adaptive Server Enterprise/15.0.2/EBF 14332/P/NT (IX86)/Windows 2000/ase1502/2486/32-bit/OPT/Thu May 24 04:10:36 2007
spy>> OK (Connection[9])
spy>> Connection[2].setAutoCommit(boolean autoCommit)
spy>> autoCommit = false
spy>> OK
spy>> Connection[2].createStatement()
spy>> OK (Statement[1])
spy>> Statement[1].executeUpdate(String sql)
spy>> sql = delete from ctstable2
spy>> OK (0)
spy>> Statement[1].close()
spy>> OK
spy>> Connection[2].createStatement()
spy>> OK (Statement[2])
spy>> Connection[2].prepareStatement(String sql) V spy>> sql = insert into ctstable1 values(?, ?)
spy>> OK (PreparedStatement[1])
spy>> PreparedStatement[1].setInt(int parameterIndex, int x)
spy>> parameterIndex = 1
spy>> x = 1
spy>> OK
spy>> PreparedStatement[1].setString(int parameterIndex, String x)
spy>> parameterIndex = 2
spy>> x = Type-1
spy>> OK
spy>> PreparedStatement[1].executeUpdate()
spy>> OK (1)

Of course this is just one additional arrow in your quill for analyzing the problem. You might need to look at the wire level protocol for a given backend. For example, you can use the Riboutility, to dump out the TDS packets sent to Sybase ASE. You might also need to analyze the performance of the queries being executed and then adjust your indexes or various other database tuning parameters.

lancea

Welcome MySQL! Blog

Posted by lancea Jan 15, 2008

As you have probably have heard by now, MySQL is becoming the lastet member of the Sun family. Jonathan's blog discusses this exciting event in detail.

I am looking forward to this new adventure as i have had nothing but positive experiences when working with the MySQL engineering team.

See the following blog on the acquisition from the MySQL community.

Technorati Tags: databases, mysql

The following is the current list of available JDBC 4.0 drivers: 

 

Java DB, Sun's supported distribution of Apache Derby, has been upgraded from Java DB 10.1.3.1 which was bundled with Glassfish V1, to Java DB 10.2.2. 

The new release of Java DB includes many new features and improvements including:

You can find the complete list of new features in Java DB 10.2.2 here.

For more information on Java DB, check out the following resources:

Glassfish v2 is now available for download.

Filter Blog

By date: