Thursday, April 30, 2009

Use of the same entity name twice

I faced an exception while using jpa:

"Use of the same entity name twice"

The exception occured due to the existence of two classes with @Entity have the same name


@Entity ( name="BeanName")
The Entity annotation has attribute called name which is the name of the entity ,its default value is the class name
@table( name="tableName")
The table annotation has attribute called name which is the name of the table ,its default value is the entity name ,and if there is no entity name,then the default will be class name


So the problem in this exception that I used @Entity giving the two entities the same name,and there is problem in that because the container uses the entities names to uniquely identify them and therefore the solution is to use @table and make the two enties use the same table name but use different entity name.

Saturday, April 18, 2009

EGJUG day

Today I have attended the EGJUG day.
First session by Ahmed Hashim was about the EGJUG and its objectives, JDC (Java Developer Conference) and its objectives, how they arrange for it, etc …

Second session was about Spring Security (Acegi), the speaker talked about Spring Security which is a project that introduce services that enhance the jEE security
Then he talked about Spring Security Features like
-Web URL authentication
- Method Authentication Invocation
- Channel Security
- Human user detection
- LDAP support
- JSP Tag Library support
- Support for SSO
- Integration with Servlet container Authentication
Then he talked about Spring Security vs. JEE security. JEE security is container dependant, it is not easy for testing, and advanced authentication is missing.
Then he made simple example using spring security in authentication by user name and password.
Then he made another example about security on methods. This is done by using annotations.

Third session was about Web UI- Dev tools.
Speaker talked about the objectives of these tools which are, Inspecting HTML DOM, Debugging JavaScript, CSS issues, HTML sniffing , Fixing Errors.
He introduced examples of Firefox tools such as FireBug which is a great tool which enable us to test, debug and edit HTML, CSS and JavaScript files, ColorZilla which display the color of the pixel currently under the mouse, JSView which is a tool enable you to see the source code of external files like JS, CSS, etc, Measurelt which draw a ruler across any web page to check the width, height, etc, LiveHttpHeaders which is used for HTTP sniffing.
And also he introduced an IE tool which is IE Dev toolbar (Internet Explorer Developer toolbar).

Fourth session was about AOP (Aspect Oriented Programming).the speaker talked about the need for AOP and that it is used to enable separation of concerns. This is done by breaking down the program into separate parts which are concerns.
He talked about the crosscutting problem. This is when some concern crosscut many parts in the system. Example of this is logging, security.
OOP (Object Oriented Programming) fail with crosscutting problems.
But AOP solve this problem by making separation of concerns.
AOP also solves the problems of low cohesion and tight coupling.
AOP saves the developer time in rewriting the same code.
AOP is a concept and AspectJ is an implementation for that concept.

Monday, December 22, 2008

De facto Standards and De jure Standards


De facto Standards and De jure Standards:


De facto standard: is a standard that is set because it is practically become dominant. It doesn't have formal approval, but widely accepted and followed by the community.


Struts is a de facto .It is an open source framework that is used to create web applications although it is not in the JEE specs of sun.


Other examples of de facto standards are Spring, Hibernate


De Jure standard: it is rules or specifications that are officially set by an organization. It has formal approval.


JSF is a de jure (standard) because it is in JEE spec.


Advantage of being JSF a standard not an implementation is that many companies compete to make good implementation for it


Other examples of de jure standards are EJB, JAF, JAX-WS, JDBC, JMS, JNDI, JPA and JSTL.


Finally, by combining some de facto standards and some de jure standards, we can a build a good system.

Service granularity

Service granularity
Service granularity refers to the scope of functionality a service exposes.


Fine-grained services might be services that provide a small amount of business-process usefulness, such as basic data access.


Coarse-grained services offer a set of related business functions rather than a single function so they are constructed from lower-level services, components, and objects that are intelligently structured to meet specific business needs. These coarse-grained services can be created from one or more existing systems by defining and exposing interfaces that meet business-process requirements.


Services as composite interfaces
Using coarse-grained interfaces, a system of services controls access to the objects referenced by each service. While each service may be implemented as an abstraction on a group of finer-grained objects, the objects themselves can be hidden from public access. Each service can be implemented by grouping objects, components, and fine-grained services, and exposing them as a single unit through the use of facades or interfaces.



Service composition
Service composition allows you to compose applications and processes using services from heterogeneous environments without regard to the details and differences of those environments. Service composition is much more achievable if the services are constructed with coarse-grained interfaces. With effectively designed and composed coarse-grained services, a business expert can productively compose new business processes and applications.



Finally regarding to Web Service s, I want to mention that Web services technology provides a way of defining coarse-grained services that access the right amount of business logic.

Introduction to web services

Life Before Web Services

Traditional distributed architecture before web service is not universally interoperable. Technologies before web service like DCOM or Object Request Brokers (ORBs) based on the CORBA specification were solutions to distributed issues but these technologies has some problems which led to trying to find new technology ,for example:


COM is linked to Microsoft so we need a technology that is not related to any platform.


Corba usually has trouble with firewalls.


COM requires installation on the same machine and DCOM requires installation on the same network. So we need a more distributed model.


Some of these traditional technologies are not suitable for heterogeneous environment. So we need a way of communication between heterogeneous applications.


So there was a need to a technology that resolves these problems and enables application-to-application interaction on the Web. We need away to deal with different communication protocols. So web service uses a technology that solved these issues.


If many applications need a piece of logic .Why make this over and over again? Why there is no such a thing that can offer applications some components that can be used many times. The solution for all that is Web Services.

Advantages of Web Services:

1-Interoperability: This is done by giving different applications a way to link their data. Also any Web service can interact with any other Web services.


2-Reusability: we don't have to recreate business logic that somebody else has already created so it helps us generate our application faster.


3-http-based: Web service based on http and most of the Internet's proxies and firewalls allow HTTP traffic.


4-xml –based: Web services uses xml as a base in its technology, xml is a standard language and easy to use and learn and most widely used.



5-loosely coupled: As it allows the web service to be in a place and the client in another. So changes in web service implementation don't affect the clients.



6-Platform and language independent: so we can use web service to communicate between any types of applications reside in different platforms


Service: is the endpoint of a connection. It is a function that is well defined and does not depend on the state of other services.


Web services: is the integration of some services that are used to make them accessible using standard internet technology. So web service is a piece of software that can be exposed, discovered and consumed.

The major web services technologies


1-xml (Extensible Markup Language)


2-SOAP (Simple Object Access Protocol)


3-WSDL (Web Service Definition Language)


4-UDDI (Universal Description, Discovery and Integration) Directory lookup for web service.

Steps in Web Services communication


1-The service Provider exposes a web service and publishes it to a directory of services (UDDI directory).It uses WSDL to define its web service.


2-The service consumer searches for a service using the UDDI directory


3-The UDDI directory sends a WSDL document to the service consumer .This WSDL document contains information about the service, where to find it and how to call it.


4-The service consumer sends a SOAP message using the xml in the WSDL document .This message contains a request to the service provider.


5-The service provider send a response back to the service consumer.



Complete example on useing stored procedures with hibernate


An Outline of An Example


We want to represent a User in Java. we may define something like:

public class User {
    private String id;
    private String gender;
 
    protected final Logger log = LogManager.getLogger(this.getClass());
 
    public User() {
 
    }
    public void setId(String id) {
        log.info("Set id: " + id);
        this.id = id;
    }
    public String getId() {
         return this.id;
    }
    public void setGender(String gender) {
        log.info("Set gender: " + gender);
        this.gender = gender;
   }
   public String getGender() {
        return this.gender;
   }
}

MySQL Schema Tables


Pretty straightforward. Now, let’s say we have two tables in MySQL that collectively represent the User object:

 
DROP TABLE IF EXISTS User;
CREATE TABLE User  (
    id  VARCHAR (50) NOT NULL,
    PRIMARY KEY(id)
); 
 
DROP TABLE IF EXISTS Pref;
CREATE TABLE Pref  (
    User_id VARCHAR (50) NOT NULL,
    gender VARCHAR (2) NOT NULL,
    PRIMARY KEY (User_id),
    FOREIGN KEY (User_id) REFERENCES User (id)
); 

Although the above example with the gender would be better as a 1-to-1 field within one table (i.e., the User table), one could imagine some other real-world examples using 1:N relationships using phone numbers, usernames, etc. So how can we map and bind these two tables to one object using stored procedures?


Hibernate 3.x Mapping File


First we must provide a mapping file to Hibernate. It looks like the following:

 
 
<hibernate-mapping>
        <class name=”User” table=”User”>
               <id name=”id” column=”id” type=”java.lang.String”>
                       <generator class=”assigned”/>
               </id>
               <property name=”gender” column=”gender” type=”java.lang.String”/>
            <loader query-ref=”getUser”>
            <sql-insert callable=”true”>{call createUser (?,?)}
            <sql-update callable=”true”>{call updateUser (?,?)}
            <sql-delete callable=”true”>{call deleteUser (?)}
        </class>
        <sql-query name=”getUser” callable=”true”>
           <return alias=”user” class=”User”>
              <return-property name=”id” column=”id” />
              <return-property name=”gender” column=”gender” />
           </return>
       { call getUser(?) }
    </sql-query>
</hibernate-mapping>

For anyone who has read older documents on Hibernate notice the lack of OUT parameters to MySQL. Hibernate 3.x apparently uses JDBC and possibly some introspection to figure out row counts, etc.


MySQL Stored Procedures


The stored procedures in the MySQL schema look like the following:

DELIMITER //
 
DROP PROCEDURE IF EXISTS getUser;
//
 
/*
 * Get a user.
 */
CREATE PROCEDURE getUser (IN inId VARCHAR(50))
BEGIN
   SELECT u.id, p.gender FROM User AS u, Pref AS p WHERE u.id = inId AND p.User_id = u.id;
END
//
 
DROP PROCEDURE IF EXISTS createUser;
//
 
/*
 * Create a user profile.
 */
CREATE PROCEDURE createUser (IN inGender VARCHAR(2), IN inId VARCHAR(50))
BEGIN
   INSERT INTO User (id) VALUES (inId);
   INSERT INTO Pref (User_id, gender) VALUES (inId, inGender);
END
//
 
DROP PROCEDURE IF EXISTS updateUser;
//
 
/*
 * Update a user profile.
 */
CREATE PROCEDURE updateUser (IN inGender VARCHAR(2), IN inId VARCHAR(50))
BEGIN
   UPDATE Pref SET gender = inGender WHERE User_id = inId;
END
//
 
DROP PROCEDURE IF EXISTS deleteUser;
//
 
/*
 * Delete the user.
 */
CREATE PROCEDURE deleteUser (IN inId VARCHAR(50))
BEGIN
   DELETE from Pref WHERE User_id = inId;
   DELETE from User WHERE id = inId;
END
//

So what does the code within our data access object in Java look like? Although it uses the Spring Framework HibernateDAOSupport class, more on that in a minute, here is the code:


DAO Java Code

public boolean createUser(User user) {
 
        boolean status = false;
        Session session = this.getSessionFactory().openSession();
 
        session.clear();
        session.beginTransaction();
 
        session.save(user);
 
        session.getTransaction().commit();
        session.close();
 
        status = true;
 
        return status;
    }
    /**
     * Get a user.
     */
    @SuppressWarnings("unchecked")
        public User getUser(User user) {
 
        User u = null;
 
        Session session = this.getSessionFactory().openSession();
 
        Query query = session.getNamedQuery("getUser");
 
        query.setString(0, (String)user.getId());
 
        List result = query.list();
        if (result == null) {
            log.info("Could not retrieve user.");
        } else {
            Iterator i = result.iterator();
 
            if (i.hasNext()) {
                u = (User) i.next();
            }
 
            if (i.hasNext()) {
                log.fatal("DB returned too many users.");
                u = null;
            }
        }
 
        session.close();
        return u;
    } 
 
    /**
     * Update a user profile.
     */
    public boolean updateUser(User user) {
        boolean status = false;
        User luser;
        String gender;
 
        if (user == null) {
            log.error("Cannot process invalid user.");
            return status;
        }
 
        gender = user.getGender();
 
        Session session = this.getSessionFactory().openSession();
 
        session.clear();
        session.beginTransaction();
 
        Query query = session.getNamedQuery("getUser");
 
        query.setString(0, (String)user.getId());
 
        List result = query.list();
 
        if (result == null) {
            log.error("Could not retrieve user.");
            session.close();
            return status;
        } 
 
        Iterator i = result.iterator();
 
        if (i.hasNext()) {
               luser = (User) i.next();
        } else {
               log.error("Could not retrieve user from list.");
               session.close();
               return status;
        }
 
        luser.setGender(gender);
        session.update(luser);
 
        session.getTransaction().commit();
 
        session.close();
 
        status = true;
 
        return status;
    }
 
    /**
     * Delete
     */
    public boolean deleteUser(User user) {
        boolean status = false;
        User luser;
 
        if (user == null) {
            log.error("Cannot process invalid user.");
            return status;
        }
 
        Session session = this.getSessionFactory().openSession();
 
        session.beginTransaction();
 
        Query query = session.getNamedQuery("getUser");
 
        query.setString(0, (String)user.getId());
 
        List result = query.list();
 
        if (result == null) {
            log.error("Could not retrieve user.");
            session.close();
            return status;
        } 
 
        Iterator i = result.iterator();
 
        if (i.hasNext()) {
               luser = (User) i.next();
        } else {
               log.error("Could not retrieve user from list.");
               session.close();
               return status;
        }
 
        log.info("Now deleting user...");
        session.delete(luser);
        session.getTransaction().commit();
 
        session.close();
 
        status = true;
 
        return status;
    }


Using stored procedures with Hibernate

Introdunction

A shortcoming in earlier releases of Hibernate was the lack of support

for stored procedures. Hibernate 3 introduces support for queries via stored procedures and functions. The stored procedure/function must return a resultset as the first out-parameter to be able to work with Hibernate. An example of such a stored function in Oracle 9 and higher is as follows:

CREATE OR REPLACE FUNCTION selectAllEmployments

RETURN SYS_REFCURSOR

AS

st_cursor SYS_REFCURSOR;

BEGIN

OPEN st_cursor FOR

SELECT EMPLOYEE, EMPLOYER,

STARTDATE, ENDDATE,

REGIONCODE, EID, VALUE, CURRENCY

FROM EMPLOYMENT;

RETURN st_cursor;

END;

To use this query in Hibernate you need to map it via a named query.

<sql-query name="selectAllEmployees_SP" callable="true">

<return alias="emp" class="Employment">

<return-property name="employee" column="EMPLOYEE"/>

<return-property name="employer" column="EMPLOYER"/>

<return-property name="startDate" column="STARTDATE"/>

<return-property name="endDate" column="ENDDATE"/>

<return-property name="regionCode" column="REGIONCODE"/>

<return-property name="id" column="EID"/>

<return-property name="salary">

<return-column name="VALUE"/>

<return-column name="CURRENCY"/>

</return-property>

</return>

{ ? = call selectAllEmployments() }

</sql-query>

· Executing the stored procedure is the same as using a named HQL

query:

Query query = session.getNamedQuery("selectAllEmployees_SP");

List results = query.list();

· If your stored procedures take parameters, you can set them using the

Query.setParameter(int, Object) method. Your stored procedures

must return a result set to be usable by Hibernate.

· Notice stored procedures currently only return scalars and entities. <return-join> and

<load-collection> are not supported.

Rules/limitations for using stored procedures with Hibernate

To use stored procedures with Hibernate the procedures/functions have to follow some rules. If they do not follow those rules they are not usable with Hibernate. If you still want to use these procedures you have to execute them via session.connection(). The rules are different for each database, since database vendors have different stored procedure semantics/syntax.

· Stored procedure queries can't be paged with setFirstResult()/setMaxResults().

· Recommended call form is standard SQL92: { ? = call functionName(<parameters>) } or { ? = call procedureName(<parameters>}. Native call syntax is not supported.

There are rules to calling Stored Procedures. They are

1. Only one return value allowed
2. It must be the first out value.
3. The out value must be a reference cursor (This out value returns a result set,in Oracle 9 or 10 this is done by using a
SYS_REFCURSOR and you need to define a REF CURSOR type).

Example on Mapping Stored Procedure:

1- SELECT_USER_BY_RANK procedure

<database-object>

<create>

create or replace procedure SELECT_USERS_BY_RANK

(

OUT_RESULT out SYS_REFCURSOR,

IN_RANK in int

) as

begin

open OUT_RESULT for

select

u.user_id as user_id,

u.name as name,

u.rank as rank

from

AppUser u

where

u.rank >= IN_RANK;

end;

</create>

<drop>

drop procedure SELECT_USERS_BY_RANK

</drop>

</database-object>

2- Mapping Configuration

<sql-query name="loadUserByRank" callable="true">

<return class="core.AppUser">

<return-property name="id" column="USER_ID"/>

<return-property name="name" column="NAME"/>

<return-property name="rank" column="RANK"/>

</return>

{ call SELECT_USERS_BY_RANK(?, :rank) }

</sql-query>

3- Stored Procedure Mapping Example

public static void main(String[] args) {

Configuration config = new Configuration();

SessionFactory factory = config.configure().buildSessionFactory();

Session session = factory.openSession();

Transaction tx = session.beginTransaction();

Query q = session.getNamedQuery("loadUserByRank");

q.setParameter("rank", new Integer(2));

List result = q.list();

System.out.println("Result=" + result.size());

for(int i=0; i<result.size(); i++) {

AppUser user = (AppUser)result.get(i);

System.out.println(user.toString());

}

tx.commit();

session.close();

}