Search in Entity Bean

Discussions

EJB design: Search in Entity Bean

  1. Search in Entity Bean (12 messages)

    Hi,
     How do i implement a search functionality in an EntityBean?
    Lets say, there is a database table that has got 10-15 fields. I'm representing this table as an EntityBean, now, i want to have a search method that should accept any combination of search criteria.

    For eg,
    Lets say, i've a person entity bean for a person table,
    and the columns are like,

    PERSON_ID NUMBER(10);
    LASTNAME VARCHAR2(255);
    FIRSTNAME VARCHAR2(255);
    DOB DATE;
    etc.,

    Now, the different search criteria would be,

    Search Criteria 1:
    PERSON_ID > 300 AND LASTNAME LIKE '%s%' OR FIRSTNAME ='RICH'

    Search Criteria 2:
     DOB > SYSDATE;

    the combination might be many more based on the number of attributes in Entity bean.

    Now, if i have to implement this in CMP Bean, how do i do it?
    If i've to go for BMP whats the easy way to do it?

    Thanx,

    vijay

    Threaded Messages (12)

  2. Search in Entity Bean[ Go to top ]

    You have to use Entity Beans but Bean Managed NOT Container. So, you must implements that method in your Bean.
  3. Search in Entity Bean[ Go to top ]

    Hi,
     Could you pls elaborate on what you have said, my question was, how to define a finder method, if i don't know what would be the exact search criteria at the deployment time!

    thanx,
    vijay
  4. Search in Entity Bean[ Go to top ]

    Hi,
    I guess u can do this in CMP also.
    as far as weblogic app server is considered
    u can place finder queries written WLQL in
     weblogic-cmp-rdbms-jar xml file.
    for more details go to weblogic.com

    regards.
    suresh rachuru

  5. Search in Entity Bean[ Go to top ]

    Hi Vijay,
      I wud suggest u to look into the following aspects before making any conclusions.

    1. How many records wud each of such a search return. If they r going to return many records, u have to consider the option of using plain JDBC from ur session bean.

    2. Which server r u using? With EJB1.1 spec. for CMP entity beans, there is no uniform way of specifying the query logic for the finder methods. The query logic is server dependent. for eg. weblogic provides its own way of specifying the query using WLQL.

    3. How complicated are ur search querries? U got to check out whether ur server's query features are sufficient enough. things like subqueries are generally not provided in the query language. In such a case u have no option other than to use BMP or JDBC.

    thx,
    Manohar (manoharm at planetasia dot com)
  6. Search in Entity Bean[ Go to top ]

    Thanx.
    Ok, I guess I framed my question wrong. I've been getting wrong answers...

    Here is the scenario..

    Lets say, I have a Person HTML Form
    <HTML>
    Name : <textbox>
    Gender : <textbox>
    Address 1 :<textarea>
    Address 2:<textarea>
    Phone : <textbox>
    ...
    ...

    <search button>
    </HTML>

    (with some 15 form fields).

    Now, If i give an option to the user for searching on any of the field lets say, user enters 'M' in the "Name" field
    and presses "Search button" at this point the search criteria would be "WHERE NAME LIKE '%M%'"

    If the user enters '001-531-2523465' along with the above criteria, then, the search search criteria would be,
    "WHERE NAME LIKE '%M' AND PHONE_NO='001-531-2523465'.

    Likewise,the search combination can be of anything... More the number of attributes more would be the search combinations right?

    In my project i've 30-40 forms like this that maps to entity beans with more than 10 persistant fields..
    (for simplicity lets assume that there is no complex joins)

    I want to know how others people implement this adhoc type queries in Entity bean.

    What would be the route if i follow CMP and what would be the route if i follow BMP?

    Am i clear now?

    thanx,
    vijay

  7. Search in Entity Bean[ Go to top ]

    I guess u have to build query dynamically depend upon user entry, so in CMP u cannot define dynamic query, u have to go for BMP and develop query and execute it.

    Hope this will help

    Ram
  8. Search in Entity Bean[ Go to top ]

    I suggest bulding the dynamic query through session bean, this we can do by performing some logic like building the query string and executing it.

    ** IMPORTANT ** Get only primary keys that match that crieteria and have an upper limit / no.-of-records-per-page limit. Keep these primary keys in any collection object and then in the web/presentation layer, recursively pass these primary keys and find the entity beans through findByPrimaryKey() of the Home. You can get the records matching the crieteria.
    Here the upper limit of the result set is a **key performance factor**, Please keep this in mind while designing the system as you already told that this kind of searches exist in many screens in your project. This, if not taken care will be fatal for the project.
    ** Note that Entity Beans are best for Insert/update operations rather than analytical/search operations. Keep these abstractions away from entity bean, if possible.

    Regards,
    Vamsi Kalyan Poondla
  9. Search in Entity Bean[ Go to top ]

    Hi vamsi,
     I agree with you infact thats what the way i had in my mind.. But why do you insist in Session bean, I feel i can do the same in the entity bean itself. Regarding the query build logic, i thought of using Map for mapping criteria for as many as columns. In the web application layer, i could construct the Map and pass it on to the EJB remote method..
      Why i'm insisting in entity bean is that, for the search operation i don't have to find a new home object and create a new remote object reference... instead i can use the remote object of entity bean itself... Am i wrong by saying this?
     Above all, everything boils to return the primary keys.. so if it is in entity bean /session bean how does that matter...
     Incase of complex joins i agree with usage of session bean... but in the scenario i've given above, i still believe that entity bean should be fine for search operation. Pls clarify.
     Thanx for the tip about setting upperlimit of the resultset. I'll keep that in my mind.(Regarding the page limit, i'm using the STRUTS framework for displaying records page by page.. so, it won't be a problem on the client side..)

    cheers,
    vijay
  10. Search in Entity Bean[ Go to top ]

    Hi,

    I have faced in this sennario. And my solution is that, I have write a method call Search in the BMP, the parameter i pass through this method from remote call is an array of parameter: which each element is separate by: "fieldname:value",

    here is the detail code:


    /**
     * SEInstrumDAO.java
     * Writer Doan
     */
    protected Connection dbConnection=null;
    //you can change the returned value to the enumeration of
    // primary key in the Entity bean
    public CachedRowSet getRecs(String[] args) throws Exception {
    CachedRowSet crs=new CachedRowSet();
    String sql_query="SELECT * FROM "+DatabaseNames.EINSTRUM_TABLE;
    String whereStr=makeCondition(args);
    if (whereStr.trim().length()!=0)
    {
    sql_query+=(" WHERE "+whereStr);
    }
    try
    {
    dbConnection=getConnection();
    Statement stmt=dbConnection.createStatement();
    ResultSet rs=stmt.executeQuery(sql_query);
    System.out.println(sql_query);
    crs.populate(rs);
    rs.close();
    stmt.close();
    dbConnection.close();
    }
          catch (Exception e)
          {
    System.err.println("getRecs() function"+e.toString());
          }
    return crs;
    }
    /**
    * Get number of records
    */
    /*********************************************************** Make Where Clause
    ******************/
    private String makeCondition(String[] args) {
    int n=args.length;
    String whereStr="";
    String fieldName;
    String value;
    for (int i=0;i<n ;i++ )
    {
    fieldName=leftArg(args[i]).trim();
    value =rightArg(args[i]).trim();
    if (value.length()!=0)
    {
    if (fieldName.equalsIgnoreCase("ABB")||fieldName.equalsIgnoreCase("NM"))
    {
    if (hasWildChar(value))
    {
    value=replaceStartWildChar(value);
    value=replaceEndWildChar(value);
    if (whereStr.trim().length()!=0)
    whereStr+=(" AND "+fieldName+" LIKE '"+value+"' ");
    else
    whereStr+=(fieldName+" LIKE '"+value+"' ");
    }
    else
    {
    if (whereStr.trim().length()!=0)
    whereStr+=(" AND "+fieldName+" = '"+value+"' ");
    else
    whereStr+=(fieldName+" = '"+value+"' ");
      }

    }
    else
    {
    if (whereStr.trim().length()!=0)
    whereStr+=(" AND "+fieldName+" = '"+value+"' ");
    else
    whereStr+=(fieldName+" = '"+value+"' ");
    }
    }
    }//for
    return whereStr;
    }
    /********************************************************************
    * Get field name of the condition element
    **********************************************************************/
    private String leftArg(String arg) {
    int Mid=arg.indexOf(":");
    return arg.substring(0,Mid);
    }
    /********************************************************************
    * Get value of field in the array element
    **********************************************************************/
    private String rightArg(String arg) {
    int argLength=0;
    argLength=arg.length();
    int Mid=arg.indexOf(":");
    return arg.substring(Mid+1,argLength);
    }
    /***************************************************
    Find if the condition contain wild character
    ******************/
    private boolean hasWildChar(String str) {
    if (str.startsWith("*")||str.endsWith("*"))
    return true;
    else
    return false;
    }

    /***************************************************
    * remove wild characters in a String
    **********/
    private String replaceStartWildChar(String str) {
    String temp=str.trim();
    if (temp.startsWith("*"))
    {
    temp=str.substring(1,temp.length());
    temp="%"+temp;
    }
    return temp;
    }
    private String replaceEndWildChar(String str) {
    String temp=str.trim();
    if (temp.endsWith("*"))
    {
    temp=str.substring(0,temp.length()-1);
    temp+="%";
    }
    return temp;
    }
     }

    Hope this is the right solution.

    Any your suggestion you can mail to me at:
    lddoan99 at yahoo dot com

    Many thanks.
  11. Search in Entity Bean[ Go to top ]

    Hi ronal,
     What you have done seems to be correct.
     I have few suggestions,
     Wouldn't be better to deal with Maps instead of strings? I guess, string mainpulation is costlier than using maps... Am i wrong?
     And how about encapsulating this logic of forming the WHERE into a simple java bean? Will it have any implications. Incase of joins, how are you framing the where clause?

    vijay
  12. Search in Entity Bean[ Go to top ]

    N.,

    What implementation of CachedRowSet did you use? Is it the Early Access Release from Sun?

    I was considering that solution, but I don't feel comfortable using it in a production environment with that "Early Access" label.

    -Matt
  13. Search in Entity Bean[ Go to top ]

    Hi,

    Right.
    CachedRowSet is an disconnected ResultSet. It have many feature for sending an resltset to client, support batch update(that resultset does'nt).

    To use it you can see/download the rowset.jar from sun.

    Thanks