+1 from me as well. Storing opaque things in the database restricts the flexibility of the system. -----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: Thursday, October 05, 2000 10:31 AM To: jBoss Subject: Re: [jBoss-User] Suggestion for CMP persistant entity fields stored as serialized handle in database "+1" from me! This is the way Orion does things by default--it's pretty slick....in fact you don't actually code anything special. Just declare a variable of whatever type you want (like another entity bean), and it stores the key (simple) into the database...I've coded around this with getters and setters, but it's definitely not optimal... -Jason Fr�d�ric FANIEN <[EMAIL PROTECTED]> 10/05/00 09:10 AM Please respond to jBoss To: jBoss <[EMAIL PROTECTED]> cc: Subject: [jBoss-User] Suggestion for CMP persistant entity fields stored as serialized handle in database I would like to suggest a way to avoid the problem of CMP persistant entity beans fields stored as serialized dandles in the database. I think this is really not a convenient solution in particular when using tables in the database outside a jboss application (with jdbcexplorer for example) First, the easiest solution is to declare simple typed CMP primary key fields for each entity field you want to be persistant and declare the cmp field transient. ex: public class OrderBean { transient Customer customer; // CMP field not persistant in database String pkCustomer; // persistant in database } then you declare the persistant fields in jaws.xml: <cmp-field> <field-name>pkCustomer</field-name> <column-name>CUSTOMER</column-name> <sql-type>VARCHAR(256)</sql-type> <jdbc-type>VARCHAR</jdbc-type> </cmp-field> You have also to instanciate pkCustomer in the create method pkCustomer = (customer=null) ? null : (String) customer.getPrimaryKey(); and you synchronize pkCustomer and customer with the load and store methods: public void ejbLoad() throws RemoteException { try { customer = (pkCustomer==null) ? null : customerHome.findByPrimaryKey(pkCustomer); } catch(FinderException ex) { throw new RemoteException("error cannot find customer"); } } public void ejbStore() throws RemoteException { pkCustomer = (customer==null) ? null : (String) customer.getPrimaryKey(); } The big problem is the use of finder methods which have entity beans as parameters : public interface OrderHome extends EJBHome { public java.util.Collection findByCustomer(Customer customer) throws FinderException RemoteException; if you write the following where-clause in jaws.xml : <finder> <name>findByCustomer</name> <query>CUSTOMER={0}</query> <order></order> </finder> it will not work, because jboss try to compare a VARCHAR field with a serialized object. That's why I modified the JDBCDefinedFinderCommand class to make jboss compare the primary key instead of the entity object itself. Now {0} refers to customer.getPrimaryKey() In conclusion, this method gives the user a convenient way of accessing entities as persistant fields, but is not the best. The smartest way would be jboss stores itself the primary key of persistant entities fields instead of its serialized handle, why not in a new version? Here is the modified JDBCDefinedFinderCommand.java /* * jBoss, the OpenSource EJB server * * Distributable under GPL license. * See terms of license at gnu.org. */ package org.jboss.ejb.plugins.jaws.jdbc; import java.util.ArrayList; import java.util.StringTokenizer; import java.sql.PreparedStatement; import org.jboss.ejb.plugins.jaws.metadata.FinderMetaData; /** * JAWSPersistenceManager JDBCDefinedFinderCommand * * @see <related> * @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a> * @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a> * @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a> * @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a> * @version $Revision: 1.4 $ */ public class JDBCDefinedFinderCommand extends JDBCFinderCommand { // Attributes ---------------------------------------------------- private int[] parameterArray; // Constructors -------------------------------------------------- public JDBCDefinedFinderCommand(JDBCCommandFactory factory, FinderMetaData f) { super(factory, f.getName()); // Replace placeholders with ? String query = ""; StringTokenizer finderQuery = new StringTokenizer(f.getQuery(),"{}", true); ArrayList parameters = new ArrayList(); while (finderQuery.hasMoreTokens()) { String t = finderQuery.nextToken(); if (t.equals("{")) { query += "?"; String idx = finderQuery.nextToken(); // Remove number parameters.add(new Integer(idx)); finderQuery.nextToken(); // Remove } } else query += t; } // Copy index numbers to parameterArray parameterArray = new int[parameters.size()]; for (int i = 0; i < parameterArray.length; i++) parameterArray[i] = ((Integer)parameters.get(i)).intValue(); // Construct SQL // BEGIN CODE String sql=null; if (query.toUpperCase().startsWith("SELECT")) { System.out.println("..... query starts with SELECT"); sql = query; } else if (query.toUpperCase().startsWith("FROM")) { System.out.println("..... query starts with FROM"); sql = "SELECT " + getPkColumnList() + (f.getOrder() == null || f.getOrder().equals("") ? "" : ","+f.getOrder()) + " "+query; } else // END CODE sql = "SELECT " + getPkColumnList() + (f.getOrder() == null || f.getOrder().equals("") ? "" : ","+f.getOrder()) + " FROM " + jawsEntity.getTableName() + " WHERE " + query; if (f.getOrder() != null && !f.getOrder().equals("")) { sql += " ORDER BY "+f.getOrder(); } System.out.println("..............constructed sql="+sql); setSQL(sql); } // JDBCFinderCommand overrides ------------------------------------ protected void setParameters(PreparedStatement stmt, Object argOrArgs) throws Exception { Object[] args = (Object[])argOrArgs; for (int i = 0; i < parameterArray.length; i++) { // BEGIN CODE Object obj = args[parameterArray[i]]; if (javax.ejb.EJBObject.class.isInstance(obj)) { System.out.println("..... Getting primary key for "+obj); obj = ((javax.ejb.EJBObject) obj).getPrimaryKey(); } // END CODE // COMMENTED stmt.setObject(i+1, args[parameterArray[i]]); stmt.setObject(i+1, obj); } } } -- -------------------------------------------------------------- To subscribe: [EMAIL PROTECTED] To unsubscribe: [EMAIL PROTECTED] Problems?: [EMAIL PROTECTED] -- -------------------------------------------------------------- To subscribe: [EMAIL PROTECTED] To unsubscribe: [EMAIL PROTECTED] Problems?: [EMAIL PROTECTED] -- -------------------------------------------------------------- To subscribe: [EMAIL PROTECTED] To unsubscribe: [EMAIL PROTECTED] Problems?: [EMAIL PROTECTED]
