"+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]