Tuesday Oct 21, 2008

This is a followup to the previous entry Using EJB Timers in GlassFish V3 TP2


All steps described in that blog apply, with the exception that the war file name and location had slightly changed to be <your-installtion>/glassfish/lib/install/applications/ejb-timer-service-app.war (Note that there is now no version present in the name of the war archive).


With V3 Prelude you can now use the EJB Timer Service with the Embedded JavaDB database, as had been available in all prior releases of GlassFish and Sun Application server.
To do so, just install JTS package from the Update Center and restart the server. You need JTS support because the __TimerPool is configured to use XA resources.


As always send us questions or comments to users@glassfish.dev.java.net or dev@glassfish.dev.java.net

Monday May 05, 2008

In this blog I'll explain how you can enable and use EJB Timer support in GlassFish V3 TP2.


If you hadn't done so yet, read first Mahesh's blog about Installing EJB Container in GlassFish V3 and using EJB 3.1 in GlassFish V3 TP2.

Enabling TimerService.


1. Change pool-name for the JDBC resource named jdbc/__TimerPool to point to the same connection pool as the one you are using for the rest of your data. You can do this either by editing the domain.xml file (and restarting the server), or via AdminGUI console (http://localhost:8080/admin/).

2. Start the database (or make sure it is running).

3. Deploy EJB Timer application that is located under <your-installtion>/glassfish/modules/ejb/ejb-timer-service-app-10.0-tp-2-SNAPSHOT.war. The aplication has been set up to use JPA with the default JPA provider, and to create the table on the first access.

4. Test that the TimerService has been started by accessing the following URL: http://localhost:8080/ejb-timer-service-app/timer

If everything went right, you'll see this screen:




Using TimerService.


All EJB 3.0 Timer features are supported with the exception of injection of TimerService using @Resource annotation. You can lookup TimerService via java:comp/TimerService.

Monday Nov 20, 2006

The Java Persistence API defines an EntityManager.close method. After this method is called on an entity manager instance, it is still possible to call methods isOpen and getTransaction on that instance.

While it's clear why the former is allowed, the same requirement for the getTransaction method sounds strange at first glance. For the answer, let's look in the spec itself. In the section 3.1.1 EntityManager Interface, the javadoc for the EntityManager.close contains the following text:


If this method is called when the EntityManager is associated
with an active transaction, the persistence context remains
managed until the transaction completes.

This means that by allowing to call this method on a closed entity manager, the spec allows you to check the status and complete the transaction. (Of course this is all about the resource-local entity manager.)

Let me know, if it's still not clear...

Friday Aug 04, 2006

Today we'll look into the following sections of the spec and see how they can affect us in unexpected way:

3.1.1 EntityManager Interface


/**
* Clear the persistence context, causing all managed
* entities to become detached. Changes made to entities that
* have not been flushed to the database will not be
* persisted.
*/
public void clear();

3.2.2 Removal


The semantics of the remove operation, applied to an entity X are as follows:

  • If X is a new entity, it is ignored by the remove operation.

  • If X is a detached entity, an IllegalArgumentException will be thrown by the remove
    operation (or the transaction commit will fail).




Now let's look at the following code (which does not depend on whether it's executed in a Java EE or in a Java SE environment):


startTransaction();

E e = new E(...);
em.persist(e);

maybeCommitTransaction();

em.clear();
System.out.println(em.contains(e));
// prints 'false'

em.remove(e);

This code will behave quite differently, depending on the actual steps in the method maybeCommitTransaction()!

If maybeCommitTransaction() is a no-op, entity 'e' actually becomes new again after clearing the persistence context, and it's ignored by the remove operation.

If maybeCommitTransaction() is a commit followed by a begin of a new transaction, entity 'e' becomes detached and remove will throw an IllegalArgumentException or commit will fail.

Note: em.contains(e) will return false in both cases.

If you are still confused, think about it in this way: a detached instance has a database state associated with it.

Thursday Jun 29, 2006

Let's look at the following section of the spec:

3.2.3 Synchronization to the Database


The semantics of the flush operation, applied to an entity X are as follows:

  • If X is a managed entity, it is synchronized to the database.
    ...

    • For any entity Y referenced by a relationship from X, where the relationship to Y has
      not been annotated with the cascade element value cascade=PERSIST or cascade=ALL:

      • If Y is new or removed, an IllegalStateException will be thrown by
        the flush operation (and the transaction rolled back) or the transaction commit
        will fail.




The last bullet is an interesting requirement. Please read it carefully (and may be more than once...).


This requirement means that if you have in a transaction entities X and Y with relationship between them, and you remove an entity Y, you must nullify all references to Y, or your transaction will fail. This is true even if Y owns the relationship (i.e. if FK column belongs to the table that Y is mapped to).


It also means that if you have such relationship marked with cascade=ALL, the removal of Y will be reverted (!) - see section 3.2.1 Persisting an Entity Instance on semantics of the persist operation, applied to a removed instance.


Food for thought... Let me know if you need more detailed explanation :)

Tuesday Apr 25, 2006

Yes, I tried it, and it works :)

1. Download the latest bundle from the https://glassfish.dev.java.net/downloads/persistence/JavaPersistence.html page and install it following the instructions. The bundle will be unpacked to ./glassfish-persistence directory.

2. Download the Java SE example from the example page: https://glassfish.dev.java.net/javaee5/persistence/persistence-example.html and unzip it. There are rumors that the link to the zip files does not work, but I couldn't reproduce the problem on Solaris or Windows.

3. Copy classes/META-INF/persistence.xml.template to classes/META-INF/persistence.xml and set your database and driver properties. Create the tables using sql/tables_oracle.sql or modify it for your database

4. Change location to classes directory, and execute the test:
java -cp [driver-location]:. -javaagent:[install-location]/glassfish-persistence/toplink-essentials-agent.jar client.Client

You should see the expected output:

Inserting Customer and Orders... OK
Verifying that all are inserted... OK
Removing all... OK
Verifying that all are removed... OK

Notes:
i) toplink-essentials.jar is automatically added to the classpath by the manifest in the agent jar.
ii) All javax.persistence API and xml schemas are part of the toplink-essentials.jar, which means that you don't need any other jar in the classpath for the compilation.
iii) You can skip the -javaagent call if your environment doesn't allow to plug in the agent - the only side effect is loading all relationship as EAGER.

Thursday Dec 08, 2005

The Example page for Java Persistence in GlassFish now has a Java EE version of the Java SE example with an app client (for the invocations) and a Stateless Session bean (for the business logic).
The page has been slightly redesigned for a better flow of information.

This blog copyright 2009 by marina