Both Josh's suggestions are good, it's up to you to see which one you  
choose.

The simultaneous validations can be solved though. The most standard  
way is to create a table lock in sql (make sure to clear it) before  
checking the existence of the unique row, or start a transaction with  
the highest possible isolation 
(http://rifers.org/docs/api/com/uwyn/rife/database/DbTransactionUser.html#getTransactionIsolation(
 
) - 
http://java.sun.com/j2se/1.5.0/docs/api/java/sql/Connection.html#TRANSACTION_SERIALIZABLE)
 
.

To notify the user of a unicity violation, you can use the Validated  
interface that MyBean normally implements (since MetaData does, and  
its interfaces are merged in) : 
http://rifers.org/docs/api/com/uwyn/rife/site/Validated.html#addValidationError(com.uwyn.rife.site.ValidationError)

You'll probably want to add one or several new instances of 
http://rifers.org/docs/api/com/uwyn/rife/site/ValidationError.UNICITY.html#ValidationError.UNICITY(java.lang.String)

HTH,

Geert

On 26 Jul 2007, at 01:45, Joshua Hansen wrote:

>
> Hi Jeremy,
>
> An ideal method would allow the database to enforce the constraint,
> either via true multi-column uniqueness (then you can use
> ConstrainedBean.unique("col1", "col2")) or some other type of db
> constraint.  I don't know much about db stuff, so I'll defer here.
>
> Maybe you could redesign away the problem.  Perhaps a base class,
> MyBean, then two extensions: MyBeanActive & MyBeanInactive.  Both
> classes have a non-persisted "active" property.  MyBeanActive has the
> constraint of uniqueness on name, while MyBeanInactive does not.  The
> MetaData classes could set the "active" field appropriately using the
> afterRestore() callback.  Or, you could just set it in a veneer or
> helper class you use for retrieving and saving the records.  You'd be
> managing two different tables in this case.
>
> Another way, though non-ideal, is to use the beforeValidate() method  
> of
> the CallbacksProvider interface.  This is workable, but non-ideal  
> since
> it is possible for two simultaneous validations to pass the validation
> before they write a record, then write the record at roughly the same
> time, resulting in two database entries.  It additionally feels
> non-ideal to me because now the MetaData class is 'heavy' -- it  
> depends
> on ContentQueryManager now instead of the validation framework.
>
> An example for doing that follows:
> ====================================
> public class MyBeanMetaData extends MetaData implements  
> CallbacksProvider {
>       ...
>
>       public Callbacks getCallbacks() {
>               return new AbstractCallbacks<MyBean>() {
>                       public boolean beforeValidate(MyBean item) {
>                               try {
>                                       ContentQueryManager<MyBean> mbMgr = new
> ContentQueryManager<MyBean>(getDatsource(), MyBean.class);
>                                       MyBean existingRecord =
> mbMgr.restoreFirst(mbMgr.getRestoreQuery().where("name", "=",
> item.getName()).      where("active","=","Y"));
>                                       if( existingRecord != null ) {
>                                               // Note: How do we indicate the 
> source of the problem back to  
> the
> user?
>                                               return false;
>                                       }
>                                       return true;
>                               } catch (Exception e ) {
>                                       return false;
>                               }
>                       }
>               }
>       }
>       protected Datasource getDatasource() {
>               Config config = Config.getRepInstance();
>               Datasource mDatasource =
> Datasources 
> .getRepInstance 
> ().getDatasource 
> (Config.getRepInstance().getString("MYBEAN_DATASOURCE",
> Config.getRepInstance().getString("DATASOURCE")));
>               return mDatasource;
>
>       }
> }
> ====================================
>
> Josh
> --
> Joshua Hansen
> Up Bear Enterprises
> (541) 760-7685
>
>
>
> Jeremy Whitlock wrote:
>> Hi All,
>>    Right now I'm using the GenericQueryManager and a class extending
>> MetaData to validate new beans for insertion into a database.  What I
>> would like to do is have this validation work on multiple columns and
>> from what I can tell right now, it is not.  Let's talk about an
>> example first then I will post code.
>>
>> Lets say I have a row in the database like this:
>>
>> NAME    ACTIVE
>> ---------   ------------
>> Testing  Y
>>
>> If I created a bean with a NAME="Testing" and an ACTIVE="Y", I would
>> expect the GQM to say the bean is invalid for insertion into the
>> database.  This works right now.  Now, if I had a row like this:
>>
>> NAME    ACTIVE
>> ---------   ------------
>> Testing  N
>>
>> and I created a bean with NAME="Testing" and an ACTIVE="Y", I want  
>> the
>> GQM to say that the bean is valid for insertion to the database.  Now
>> that we know what I want, let me show you some related code:
>>
>> MetaData
>> -------------
>> addConstraint(new ConstrainedProperty("id")
>>      .identifier(true)
>>      .editable(false)
>>        .unique(true)
>> );
>>              
>> addConstraint(new ConstrainedProperty("active")
>>      .notEmpty(true)
>>      .notNull(true)
>>      .maxLength(1)
>>      .regexp("(Y|N){1}")
>>      .unique(true)
>> );
>>
>> addConstraint(new ConstrainedProperty("name")
>>      .notEmpty(true)
>>      .notNull(true)
>>      .maxLength(64)
>>      .regexp("([\\s\\-A-Za-z0-9]*)")
>>      .unique(true)
>> );
>>
>> Here is the code I'm using for the validation, although it  
>> shouldn't matter:
>>
>> SomeElement
>> -------------------
>> ((Validated 
>> )bean).validate(MyAppUtils.getGenericQueryManager(MyClass.class))
>>
>> What do I need to do to my MetaData class to allow for multiple- 
>> column
>> unicity checks, if it is even available?  If it is not available, how
>> would you suggest working around this?  Basically, I've got a table
>> that holds objects in it that can be active or inactive.  If an  
>> object
>> is active, you shouldn't be able to create a new object in that table
>> with the same name.  If an object is inactive, you should be able to
>> create a new object with the same name as the inactive object.
>>
>> Thanks in advance,
>>
>> Jeremy
>>
>>>
>>
>>
>
> >

--
Geert Bevin
Terracotta - http://www.terracotta.org
Uwyn "Use what you need" - http://uwyn.com
RIFE Java application framework - http://rifers.org
Music and words - http://gbevin.com


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"rife-users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/rife-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to