Search

EJB 2.0 Drawbacks

  • Complex Products
  • Unmaintainable System
  • Non-portable, frame-work committed business components
  • Unpredictable System
  • Why EJB 2.0 is complex / complicated?
    • Session bean - to write say hello method

      in EJB 2.x, you need to write
      home interface
      component interface
      bean

      in EJB 3.x, you need to write
      interface (with annotation)
      bean (with annotation)

      EJB 2.x; lookup is the only way to get server object/resource
      EJB 3; DI (dependency injection) & lookup are the available way


      there are more points. But basically, with EJB 3 responsibility of container is heavy & responsibility of developer is light weight; so that development is less & maintenance is easy.

Seam, EJB and Hibernate useful tips



 
Here are some tips I have gathered during our Seam project.

@Create - Signals that this method should be called upon instantiation of the JavaBean.

@Stateless - Makes an EJB3 object

@Stateful - (SESSION) Caches in memory between server requests

@In - These variables will automatically be set by Seam through injection of the variables labeled by the annotation. i.e
String zipCode; (Behind the curtain: zipCode = request.getParameter("zipCode"); )

@Out - Same as above. This variable is also automatically set by Seam. Behind the curtain this variable is set in the HttpSession object.
( request.setAttribute("bestRestaurant", restaurant); )
What you also must remember is that if you want to use the outjected object, you only call it with its name. Not component name first.
i.e. If you stateful session bean is named @Name("someName") and you have a @Out String test, then when you use it in the view, you must write #{test} and not #{someName.test}
You can also say @Out(required = false) which means that the Object can be null. Otherwize it cannot.

@DataModel annotation exposes an attribute of type java.util.List to the JSF page as an instance of javax.faces.model.DataModel. This allows us to use the list in a JSF with clickable links for each row. The DataModel is made available in a session context variable named the variable name.

@PersistenceContext(type=EXTENDED)
EntityManager em;
This stateful bean has an EJB3 extended persistence context. The messages retrieved in the query remain in the managed state as long as the bean exists, so any subsequent method calls to the stateful bean can update them without needing to make any explicit call to the EntityManager.
Remember, its a good idea to clear the entitymanager once in a while if you do lots of searches

@Factory("messageList")
public void findMessages() {
messageList = em.createQuery("from Message msg order by msg.datetime desc").getResultList();
}
The first time we navigate to the JSP page, there will be no value in the messageList context variable. The @Factory annotation tells Seam to create an instance of MessageManagerBean and invoke the findMessages() method to initialize the value. We call findMessages() a factory method for messages.

@Remove
@Destroy
public void destroy() {}
All stateful session bean Seam components must have a method with no parameters marked @Remove that Seam uses to remove the stateful bean when the Seam context ends, and clean up any server-side state.

@NamedQuery(name="findProeveByAddress",
query = "SELECT p " +
"FROM Proeve p, PersonAdresseAdressetype paa "
+ "WHERE paa.person = p.person "
+ "AND (lower(p.person.fornavn) like :fornavn OR lower(p.person.mellomnavn) like :fornavn) "
+ "AND (lower(p.person.etternavn) like :etternavn) "
+ "AND (lower(p.person.foedselsnummer) like :foedselsnr) "
+ "AND (lower(paa.adresse.adressefelt1) like :adresse) "
+ "AND (lower(p.kommune.navn) like :kommunenavn) "
+ "order by p.person.etternavn, p.avlagt desc"
)

@Lob - Used for storing large string/byte objects. Becomes text or blob.

Join Fetch - Makes the fetch eager. Be careful using join fetch. What I mean with that is that you should only use fetch when you are going to call methods
on the object being fetched. Otherwize it will be a performance issue.

@Enumerated(EnumType.STRING) - Makes the enum as string in the database

@Observer("proeveSearchDirty")
public void clear() {
proeveSokList = null;
}
With the observer annotation you can call on methods by giving it a name from other seam components.
For instance you can raise event which will call the observer method after an persist is made

@RaiseEvent("proeveSearchDirty")
public String persist() {
return super.persist();
}

If you want to override the default "Successfully created/updated/removed" from Seam and your EntityHome objects, then you can either override the methods
in the Home class. i.e
@Override
public String getCreatedMessage() {
return "Saved";
}

@Override
public String getUpdatedMessage() {
return "Updated";
}

@Override
public String getDeletedMessage() {
return "Removed";
}
Or you can put it in the messages.properties file with the notation:
*EntityName*.created. For instance:
Adresse_created=Lagret
Adresse_updated=Oppdatert
Adresse_deleted=Slettet
The messages.properties will be the default even if you have overrided the methods in your Home objects.

Hibernate Introduction

Hibernate is a Object relational mapping framework. What it will help us is in saving the objects into the relational world.

Employee.java

public class Employee {

private String Name;

private int Emp_Id;

private String Designation;

private String Reportee;

private int Access_Carad_No;

    

    public String getName() {

        return Name;

    }

    public void setName(String name) {

        Name = name;

    }

    public int getEmp_Id() {

        return Emp_Id;

    }

    public void setEmp_Id(int emp_Id) {

        Emp_Id = emp_Id;

    }

    public String getDesignation() {

        return Designation;

    }

    public void setDesignation(String designation) {

        Designation = designation;

    }

    public String getReportee() {

        return Reportee;

    }

    public void setReportee(String reportee) {

        Reportee = reportee;

    }

    public int getAccess_Carad_No() {

        return Access_Carad_No;

    }

    public void setAccess_Carad_No(int access_Carad_No) {

        Access_Carad_No = access_Carad_No;

    }


 


 

}


 

Now we have the domain class definition with us. Now we will put a mapping file which will map this class to the data model in the database. We are not creating the table in the database as we will use hibernate to generate the data model. Though in real life application you would have your data model already created and placed in the database.

Employee.hbm.xml

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>    

<class name="Employee.java" table="Employee" schema="hiberpract">

<id name="Emp_Id" column="EMP_ID">

<generator class="increment"></generator>

</id>


 

<property name="Name" column="NAME"></property>

<property name="Designation" column="DESIGNATION"></property>

<property name="Reportee" column="REPORTEE"></property>

<property name="Access_Carad_No" column="ACCCESS_CARD_NO"></property>


 


 

</class>

</hibernate-mapping>

Now we will provide hibernate the details to connect to the database. Similar to JDBC coding, the connection details and drivers need to be provided to Hibernate. This is done in a XML file

Hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<!-- Database connection settings -->

<property name="connection.driver_class">com.mysql.jdbc.Driver </property>

<property name="connection.url">jdbc:mysql://localhost:3306/Hiberpract </property>

<property name="connection.username">root</property>

<property name="connection.password">root</property>


 

<!-- JDBC connection pool (use the built-in) -->

<property name="connection.pool_size">1

</property>


 

<!-- SQL dialect - This tells the SQL grammer to be used -->

<property name="dialect">org.hibernate.dialect.HSQLDialect

</property>


 

<!-- Enable Hibernate's automatic session context management -->

<property name="current_session_context_class">thread</property>


 

<!-- Disable the second-level cache -->

<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider

</property>


 

<!-- Log out all the sql that hibernate is issuing to datbase.

This is very useful for debugging -->

<property name="show_sql">true</property>


 

<!-- Create the table looking at class and mapping. Very useful in development

Use validate in production environments. -->

<property name="hbm2ddl.auto">create</property>

        <property name="format_sql">true</property>

<!-- Mapping file. -->

<mapping resource="Employee.hbm.xml"/>


 

</session-factory>

</hibernate-configuration>

Now we will write a utility class which will start the session factory of hibernate, if it is not started and will return the Session factory. This is the most used pattern of boot strapping Hibernate. Session factory contains all the configuration information at runtime. A Session is retrieve from the Session factory. A session is a light weight object which provide services to interact with database. You can think of Session like JDBC connection, thought it may not open the database connection if not required.

HiberUtil.java:

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;


 


 


 

public class HiberUtil

    {


 

        private static SessionFactory sessionFactory;


 

        static{

            try{

                //By default it will look for hibernate.cfg.xml in the class path

                sessionFactory=new Configuration().configure().buildSessionFactory();

            }catch(Throwable ex){

                throw new ExceptionInInitializerError(ex);

            }

        }


 

        public static SessionFactory getSessionFactory(){

            return sessionFactory;

        }


 

        public static void shutdown(){

            //Close caches and connection pool

            getSessionFactory().close();

        }


 

    }


 


Now Let's create the base class having main method..

HiberBase.java

import org.hibernate.Session;

import org.hibernate.Transaction;


 


 

public class HiberBase {


 

    public static void main(String[] args) {


 

        //Get the session from the Session factory

        Session session = HiberUtil.getSessionFactory().openSession();


 

        Transaction tx= session.beginTransaction();


 

        Employee Emp = new Employee();

        Emp.setName("Utkarsh");


 

        session.save(Emp);


 

        //System.out.println(studentId);


 

        tx.commit();

        session.close();

    }

}

In the above example we saw how to configure hibernate using XML mapping.