Wednesday, September 2, 2009

Oracle-Sun Acquisition Near Approval

Oracle's acquisition of Sun was approved by the US Department of Justice August 20th (see details here ) and according to Bloomberg (see here) European regulators are expected to approve the deal Sept 3rd. European approval is the last hurdle before the acquisition can be finalized.

Thursday, August 27, 2009

Simplifying the Hibernate Inverse Attribute on Associations

Hibernate is a framework to make storing and retrieving persistent objects and their association to one another simpler. While this is generally true, there are aspects of Hibernate configuration and mapping that can be challenging to learn and understand. Perhaps, one of the toughest to teach people is that of the inverse setting on a bi-directional relationship mapping in a one-to-many or many-to-many association. Without an understanding of the objects, the association, and SQL needed to save them, people new to Hibernate often struggle with this setting.


In fact, the inverse attribute on an association mapping can be easily understood with a simple example. So to start, assume there are two entities: BallPlayer and Team. As anyone who has played team sports knows, a team has many players, but a player can be on only one team at anytime. Therefore, the relationship between BallPlayer and Team is a one-to-many relationship, and in this example it is bi-directional. That is, a BallPlayer knows the team he plays for, and the Team knows the players on it. The UML showing the BallPlayer and Team attributes and the ERD diagrams for Player and Team are shown below.


The Hibernate mapping files for both BallPlayer and Team are straightforward.


<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.intertech.domain">
<class name="BallPlayer" table="Player" abstract="true">
<id name="id" access="field">
<generator class="sequence">
<param name="sequence">common_seq</param>
</generator>
</id>
<property name="name" />
<property name="dob" column="date_of_birth" />
<property name="uniformNumber" column="uniform_number" />
<many-to-one name="team" column="team_id" cascade="all"
class="com.intertech.domain.Team" not-null="true" />
</class>
</hibernate-mapping>


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.intertech.domain">
<class name="Team">
<id name="id" access="field">
<generator class="sequence">
<param name="sequence">common_seq</param>
</generator>
</id>
<property name="nickname" />
<property name="founded" />
<set name="players" inverse="true" cascade="all">
<key column="team_id" />
<one-to-many class="com.intertech.domain.BallPlayer" />
</set>
</class>
</hibernate-mapping>

Note the inverse="true" on the <set> element in the Team mapping. When used, the inverse attribute must be set on the collection (in this case the <set> on Team) side of the association rather than the side containing the <many-to-one> element (the BallPlayer in this case). In a many-to-many relationship, the inverse attribute can be placed on the collection element on either side.

OK, but what is this inverse attribute all about? Well, to understand it, examine some test code that exercises the BallPlayer to Team relationship.

Calendar dob = Calendar.getInstance();

dob.set(1942, Calendar.DECEMBER, 13);
BallPlayer fergie = new BallPlayer();
fergie.setName("Ferguson Jenkins");
fergie.setDob(dob);
fergie.setUniformNumber((short) 31);

SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Team cubs = (Team) session.get(Team.class, 1L);
cubs.addPlayer(fergie);
fergie.setTeam(cubs);
transaction.commit();
session.close();

In this Hibernate code, a new BallPlayer (fergie) is created and associated to an already persistent Team (cubs) object. Once the BallPlayer and Team are associated to one another and since Team is already persistent, cascading persistence causes the BallPlayer (fergie) and relationship to the Team (cubs) to be saved.


The SQL issued to the database (shown with show_sql and use_sql_comments all set to true in the Hibernate configuration) when the test code above executes is shown below.


Hibernate: /* load com.intertech.domain.Team */ select team0_.id as id1_0_, team0_.nickname as nickname1_0_, team0_.founded as founded1_0_ from Team team0_ where team0_.id=?

Hibernate: /* load one-to-many com.intertech.domain.Team.players */ select players0_.team_id as team5_1_, players0_.id as id1_, players0_.id as id0_0_, players0_.name as name0_0_, players0_.date_of_birth as date3_0_0_, players0_.uniform_number as uniform4_0_0_, players0_.team_id as team5_0_0_ from Player players0_ where players0_.team_id=?

Hibernate: call next value for common_seq

Hibernate: /* insert com.intertech.domain.BallPlayer */ insert into Player (name, date_of_birth, uniform_number, team_id, id) values (?, ?, ?, ?, ?)

However, when the inverse="true" is removed from the Team mapping file, look how the SQL changes.

Hibernate: /* load com.intertech.domain.Team */ select team0_.id as id1_0_, team0_.nickname as nickname1_0_, team0_.founded as founded1_0_ from Team team0_ where team0_.id=?


Hibernate: /* load one-to-many com.intertech.domain.Team.players */ select players0_.team_id as team5_1_, players0_.id as id1_, players0_.id as id0_0_, players0_.name as name0_0_, players0_.date_of_birth as date3_0_0_, players0_.uniform_number as uniform4_0_0_, players0_.team_id as team5_0_0_ from Player players0_ where players0_.team_id=?

Hibernate: call next value for common_seq

Hibernate: /* insert com.intertech.domain.BallPlayer */ insert into Player (name, date_of_birth, uniform_number, team_id, id) values (?, ?, ?, ?, ?)

Hibernate: /* create one-to-many row com.intertech.domain.Team.players */ update Player set team_id=? where id=?

It might be hard to see at first, but one extra SQL statement got executed. Notice the extra SQL update statement that is called (the last line in italics)? What gives? Why the extra SQL? This is a result of the absences of the inverse attribute on the relationship mapping.

From a database perspective, since only the Player table holds the reference (foreign key) to the Team, only one insert is needed for the relationship to be persisted – an insert into the Player table. However, Hibernate does not detect this fact by default. In the persistence context, all Hibernate knows is that both persistent objects (the BallPlayer called fergie and the Team called cubs) have been created or modified and need to be persisted. Therefore, at the next point of synchronization (transaction commit in this case) with the database, Hibernate attempts to persist both. If inverse attribute is not set to true, Hibernate looks at Team and notices the new BallPlayer.


It inserts the new BallPlayer, and association from cubs-to-fergie. However, it then looks at the new BallPlayer and sees the relationship fergie-to-cubs. Not told that the relationship is the inverse of one it has already taken care of, it thinks an update might be necessary to save this new relationship. Thus the extra "update Player set team_id=? where id=?" SQL is issued.

So, the inverse=true attribute informs Hibernate of the existence of a bidirectional relationship which allows it to ignore the relationship from the Team to BallPlayer direction.


This raises an important issue in your management of Java objects and their association to each other. With inverse="true", Hibernate essentially ignores the association of Team to BallPlayer. Therefore, if you add a BallPlayer to Team, but do not handle the reverse association in your coding, the association is ignored!

// - forget to do this - aPlayer.setTeam(aTeam);
aTeam.addPlayer(aPlayer);
session.save(aTeam);
session.save(aPlayer);

Hibernate manages the persistence of Java objects and their associations to each other into the database, but only if they are physically there! For this reason, good Hibernate developers write methods to update both sides of an entity relationship when either side is updated.

public void addPlayer(BallPlayer aPlayer){
players.add(aPlayer);
aPlayer.setTeam(this);
}

If you still find the invert attribute and associations confusing, I encourage you to download the code for this blog post here and see if it makes more sense after you play with the setting in this simple example.

To learn more about Hibernate, consider taking Intertech's Complete Hibernate class.

Free Learning Event - Globalizing your Java App

My fellow Java Intertech instructor , Jason Shapiro, is providing a talk on Globalizing your Java Application September 11th (one at 9am central time, the other - virtual classroom - at 1pm central time). In this free 2 hour talk, Jason discusses the basic considerations and processes one must follow to create a globalized application; that is how to move text and images into resource bundles, dealing with numbers, dates, and currency, character encoding issues, and localization/internationalization patterns and best practices. Jason is a phenomenal classroom presenter. This talk is well worth your time. Sign up on Intertech's web site for either the in-person or virtual class here.

Tuesday, August 4, 2009

Java 7 - good, bad or somewhere in between

Not sure about the new Java 7 JDK? It seems you would not be alone if you are still wavering on the new JDK (anticipated to be released in early 2010 - see my blog posting on Java 7 and Java EE 6 here). A recent poll on java.net (“The Source for Java Technology Collaboration” as deemed by Sun) indicates that almost half of 488 surveyed in the Java community (203 – 41% to be exact) don’t think it addresses “significant” problems. See the poll results and comments left by others here.


It is not a scientific survey, but the number seemed to capture some attention. In fact, the ServerSide.com noted the survey and mentioned the “Diversity of opinions on JDK 7” in its weekly email newsletter. Have you tried out the new JDK? If so, what are your thoughts? Will your organization move to Java 7 quickly or slowly. Provide your answer to my Java 7 questions at right.

Friday, July 17, 2009

Complete Hibernate – Beta Class at Reduced Price

Intertech has updated its Complete Hibernate class (more material – more days of training) and it is being run for the first time in August. Sign up now to get a 25% reduction in price by participating in the beta run of the class.

JAX-WS and Operation Overloading

Another great group of people this week in my classroom. The topic was Java Web Services with a little JMS thrown in. During the class this week, in the discussion of Java to XML (and back) mapping as provided by JAX-WS and JAXB, I indicated to students that while Java as a programming language supports method (or operation) overloading, it is prohitited in Web services by specification (WSDL) and the WS-I Basic Profile.

During class, we explored the JAX-WS annotations for defining Java Web services. Specifically, we looked at the @WebService annotation on the service endpoint interface (SEI) and implementation bean (SIB) as shown below.
package example;
import
javax.jws.WebService;
@WebService(endpointInterface ="example.SomeService")
public class SomeServiceImpl implements SomeService
{
public int doIt(String str) {
return 0;
}
}

package example;
import
javax.jws.WebService;
@WebService
public interface SomeService {
public
int doIt(String str);
}
When looking at JAX-WS, we also explored the operationName attribute on the @WebMethod annotation for Web service methods. A perceptive and imaginative student (thanks Pat) asked “if you could use the operationName to allow for method overloading at the Java level while preserving unique operation names in the WSDL and SOAP level?” I’ve extended the example to demonstrate below.

package example;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
public interface SomeService {

public int doIt(String str);
@WebMethod(operationName = "doItNow")
public int doIt(int i);
}

package example;
import javax.jws.WebService;
@WebService(endpointInterface = "example.SomeService")
public class SomeServiceImpl implements SomeService {
public int doIt(String str) {
return 0;
}
public int doIt(int i) {
return 0;
}
}
What a great question and one that sent me scrambling to my browser and text books looking for an answer.

The answer is – no, not easily. This will be somewhat dependent on the JAX-WS implementation (for example, take a look at Christophe Hamerling’s example in Apache CXF where overloaded operations and use of the @operationName works) and work-arounds could probably be negotiated (for example, don’t use document/literal wrapped style). However, when using the JAX-WS reference implementation mapping tools there is still going to be problems despite the @WebMethods operationName attribute provides a unique operation name as far as SOAP and WSDL are concerned.

The reason? The wsgen tool has problems creating the default SOAP wrapper classes for the operation inputs and outputs. When you run wsgen with the code above, you get an exception (com.sun.tools.internal.ws.processor.modeler.ModelerException: [failed to localize] Request wrapper bean names must be unique and must not clash with other generated classes.)as shown below.


So thanks again for the great question Pat. Contact Intertech if you would like to sign up for our next Complete Java Web Services class.

Sunday, July 5, 2009

JAX-RS: A new Java Web service API

JAX-RS will be part of Java EE 6 which is due out in final form in September ’09. What is JAX-RS? JAX-RS is the Java API for RESTful Web Services. OK, so what is a RESTful Web service? The term REST (Representation State Transfer) dates to a 2000 doctoral dissertation by Roy Fielding – cofounder of the Apache HTTP server and coauthor of the HTTP and URI standards. REST is the software architecture (or architectural style) for distributed hypermedia (text, graphics, audio, video, etc.) systems. REST is the foundation of the World Wide Web. RESTful Web services, is the application of the REST architectural style to provide information to other systems, process, etc.


At the heart of a RESTful system is a resource. A resource is anything that has an identifier in the form of a URI. Any informational item that can be named can be a resource: stock price, customer, purchase order, calendar of events, etc. The concept of a resource is broad. Here are some examples.

http://www.intertech.com/studentDirectory/students
http://www.intertech.com/studentDirectory/students/jamesBond
http://www.intertech.com/studentDirectory/students/missMoneypenny

Resources have state and it is that state that the requester of the resource is interested. A RESTful Web service requestor or client may request to read the resource’s state. A client may request to update a resource’s state. Behind REST systems is a set of client-invoked operations on resources. While not absolutely required, most have come to accept the set of HTTP methods as the general API for REST operations on resources.

GET - Read a resource
POST - Create/add a new resource from the
HTTP request body
PUT - Update a resource from the HTTP request body
DELETE - Delete a resource

The URI query string might provide amplifying information about the operation.

http://www.intertech.com/studentDirectory/students?lastName=Bond

In a RESTful system, URIs act as nouns (identifying resources) and the HTTP method acts as a verb that specifies the operations on the resources. URIs and HTTP methods provide, while more convention than standard, a terse and uniform style for information exchange.


So Back to JAX-RS. JAX-RS allows for the construction of RESTful services in Java. Using JAX-RS, REST resources are Plain Old Java Objects. The POJOs are annotated with @Path. @Path takes one argument. The argument identifies the relative URI path to which the resource responds.

@Path("/helloworld")
public class HelloWorldResource {
...
}

The URI path is relative to the base URI of the server the resource is deployed, the context root of the WAR, and the URL pattern for an adapter servlet that routes traffic to the resources.

http://:///

So, assuming the resource above was in a MyWebApp WAR, a URL request to this HelloWorldResource might look like the following:

http://localhost:8080/MyWebApp/resources/helloworld

The @Path annotation merely dictates what request traffic is sent to the resource.


Add annotations (@GET, @POST, @PUT, @DELETE, @HEAD) to the resource methods to indicate what should be invoked for each type of HTTP request.

@Path("/helloworld")
public class HelloWorldResource {

@GET
public String sayHello() {
return "Hello
World";
}
}

Methods that are annotated with @GET, @POST, @PUT, @DELETE and @HEAD are called resource methods and allow for the RESTful service clients to retrieve, update, remove, and create new resources.

By default, the resource returns text/plain. However, the @Produces annotation can be used to specify the MIME type of response. The @Produces can annotate the resource to provide the default return type for all resource methods.

@Path("/helloworld")
@Produces("text/html")
public class
HelloWorldResource {
...
}

Resources may offer multiple MIME types for any given request.
Resources may also be sent information (as part of the HTTP request body) by the client. The @Consumes annotation works in a fashion similar to @Produces but for incoming rather than outgoing MIME types. @Consumes specifies which MIME types can be accepted or consumed by the resource.
@POST
@Consumes("text/plain")
public void respondToMessage(String message)
{
...
}
As with all Java specifications, JAX-RS must be implemented. The Jersey project is Sun’s reference implementation of JAX-RS 1.0. You can get Jersey today at https://jersey.dev.java.net. To learn more about JAX-RS and the other APIs of Java Web Services, sign up to take Intertech’s updated Complete Java Web Services class.