The Artima Developer Community
Sponsored Link

Java Community News
EJB 3 Persistence Jumpstart

3 replies on 1 page. Most recent reply: May 8, 2006 1:39 PM by Matthew Zipay

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 3 replies on 1 page
Frank Sommers

Posts: 2642
Nickname: fsommers
Registered: Jan, 2002

EJB 3 Persistence Jumpstart Posted: Apr 19, 2006 8:17 AM
Reply to this message Reply
Summary
A recent article by Jeff Brown provides a hands-on overview of the EJB 3 persistence model. His examples use Hibernate as the EJB 3 persistence provider, and illustrate how Java 5 annotations alleviate the need for XML mapping files.
Advertisement

The EJB 3 persistence model is at the core of J2EE 5, offering a simplier, light-weight model compared with earlier EJB specifications. The new model took into account experience with managed beans in prior J2EE releases, as well as practical advice from the Hibernate and JDO communities.

The most important difference from earlier EJB versions is that the EJB 3 persistence model can be used both within and without a container, and requires only a compatible persistence provider implementation. A J2EE server might offer such an implementation, and Hibernate 3 also happens to be a light-weight EJB 3 persistence provider.

In his recent EJB 3 tutorial, Jeff Brown shows how to persist a POJO, how to map relationships using annotations, and how to query an EJB 3 provider. While his examples use Hibernate, the only Hibernate-related information is in the persistence context descriptor, which is the only XML file required by the persistence model.

Jeff shows that a POJO must meet these four requirements to be persistable in the EJB 3 model:

  • Must have a no-arg constructor
  • Must not have any final methods
  • Its class must not be final
  • The class must be marked with @Entity, or have an associated XML descriptor

The annotation-based model alleviates the need for XML descriptor files. For instance, the article shows that by associating a few annotations with a POJO, an instance of this class can be persisted via any EJB 3 persistence provider:

@Entity
public class Person {

  private String firstName;

  private String lastName;

  private Integer id; // new field to represent identity

  public Person(String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  @Id
  @GeneratedValue
  public Integer getId() {
    return id;
  }

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

  public String toString() {
    return lastName + ", " + firstName;
  }
}

Persisting an instance of this class is as simple as the following code snippet:

 EntityManagerFactory emf = 
      Persistence.createEntityManagerFactory("mycontext", 
            new HashMap());
    EntityManager em = emf.createEntityManager();
    EntityTransaction tx = em.getTransaction();
    tx.begin();
    em.persist(new Person("Ben", "Franklin"));
    tx.commit();
    em.close();

The persistence context descriptor can even define if the persistence manager should create a new table, if one for this entity does not already exist:

<?xml version="1.0" encoding="UTF-8"?>
<persistence>
 <persistence-unit name="mycontext">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>com.persistencedemo.Person</class>
    <properties>
        <property name="hibernate.connection.url" value="jdbc:mysql://localhost/demodb"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
        <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
        <property name="hibernate.connection.password" value="javadude"/>
        <property name="hibernate.connection.username" value="javauser"/>
        <property name="hibernate.hbm2ddl.auto" value="update"/>
    </properties>
  </persistence-unit>
</persistence>

Here, the hibernate.hbm2ddl.auto property is set to update, indicating that a table should be updated to reflect the bean's properties. Again, this is the single XML file required by the persistence model.

What do you think of the EJB 3 persistence model?


Ravi Venkataraman

Posts: 80
Nickname: raviv
Registered: Sep, 2004

Re: EJB 3 Persistence Jumpstart Posted: Apr 19, 2006 5:17 PM
Reply to this message Reply
This is not a comment on EJB3 but a comment on the use of Factory pattern. I see this type pf code very often:
  
EntityManagerFactory emf = 
   Persistence.createEntityManagerFactory(
       "mycontext", new HashMap());
EntityManager em = emf.createEntityManager();


Notice that in order to use the EntityManager class, the user (developer) must be aware of the existence of the EntityManagerFactory class and the Persistence class even though these two classes play no further role in the code. This strong coupling seems unnecessary.

Why should the developer know that there is a factory used to create the EntityManager? Why can't this fact be hidden within the innards of the EntityManager class? We could use code like:

 
EntityManager em = 
   EntityManager.createEntityManager(
      "mycontext", new HashMap());


The EntityManager class can transparently invoke the Factory to get the instance by calling the first line of the code quoted above. Why should the developer be aware of the implementation details of EntityManager class? What benefit does it provide?

In fact, if a new instance of EntityManager were to be provided with every call, why couldn't one simply use the following:
    EntityManager em = 
        new EntityManager("mycontext", new HashMap());


Going to the next step, we'd immediately observe that an overloaded constructor can be created making the invocation even simpler:
 EntityManager em = new EntityManager("mycontext");


Compare this last with the original two lines of code and we can immediately see the simplicity.

I simply do not see the benefit of using the repeated code (shown in the first snippet) again and again when the implementation can be hidden away. Isn't good programming about eliminating duplication and reducing string coupling?

Using the Factory pattern but hiding it within the EntityManager class retains the benefits of using the Factory pattern while reducing the string coupling of the Factory and Persistence classes with the EntityManager class.

Ravi

Ravi Venkataraman

Posts: 80
Nickname: raviv
Registered: Sep, 2004

Re: EJB 3 Persistence Jumpstart Posted: Apr 20, 2006 2:30 AM
Reply to this message Reply
Oops: In the last 2 paragraphs, "string coupling" should of course be "strong coupling"!

Matthew Zipay

Posts: 2
Nickname: mattz
Registered: Oct, 2005

Re: EJB 3 Persistence Jumpstart Posted: May 8, 2006 1:39 PM
Reply to this message Reply
Doesn't the sample Person class violate the first requirement (i.e. "Must have a no-arg constructor")???

My assumption is that simply adding a no-arg constructor to Person will make the example code correct (no other changes necessary). Can someone verify?

Flat View: This topic has 3 replies on 1 page
Topic: EJB 3 Persistence Jumpstart Previous Topic   Next Topic Topic: Managing Conversational State with Seam

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use