Thread: Re: [jrf-user] setInsertOnly and writeOnce
Brought to you by:
joncrlsn
|
From: Darren S. <DS...@ps...> - 2002-11-18 14:39:19
|
FYI,
The TimeStampColumnSpecDbGen.setInsertOnly() does not seem to work. We
had to do a
code modification to UpdateSQLBuilder.java to correct the issue (we did
this on Friday
last week and so have not submitted this change to the message board
yet).
The problem lies in the fact that the UpdateSQLBuilder does not take
any notice of the
TimeStampColumnSpecDbGen.setInsertOnly() value when building update
statements.
For anyone that is interested our updated code is shown below (this was
a quick fix and
may not be the best solution).....
private String buildSQL(boolean prepared,
PersistentObject aPO,
String tableName,
List columnSpecs)
{
ColumnSpec aColumnSpec = null;
ColumnSpec pkColumnSpec = null;
ColumnSpec lockingColumnSpec = null;
checkPolicy();
StringBuffer sqlBuffer = new StringBuffer();
sqlBuffer.append(" UPDATE ");
sqlBuffer.append(tableName);
sqlBuffer.append(" SET ");
int count = 0;
// Create an assignment expression for each column
boolean isInsertOnly = false;
Iterator iterator = columnSpecs.iterator();
while (iterator.hasNext())
{
isInsertOnly = false;
aColumnSpec = (ColumnSpec) iterator.next();
if (aColumnSpec.isPrimaryKey())
{
pkColumnSpec = aColumnSpec;// save for later
}
else
{// not a primary key
if (aColumnSpec instanceof TimestampColumnSpecDbGen)
{
isInsertOnly =
((TimestampColumnSpecDbGen)aColumnSpec).isInsertOnly();
}
if (!isInsertOnly)
{
if (count > 0)
{// BUG Fix -- PK may not be the first column in the
list.
sqlBuffer.append(", ");
}
count++;
sqlBuffer.append(
aColumnSpec.getColumnName());
sqlBuffer.append(" = ");
if (aColumnSpec.isOptimisticLock())
{
lockingColumnSpec = aColumnSpec;// save for later
if (aColumnSpec instanceof
TimestampColumnSpecDbGen)
{
sqlBuffer.append(i_dbPolicy.timestampFunction());
}
else
{// Assume it's an IntegerColumnSpec
if (prepared)
{
sqlBuffer.append("?");
}
else
{
Integer oldVersion = (Integer)
aColumnSpec.getValueFrom(aPO);
sqlBuffer.append(aColumnSpec.formatForSql(getNewOptimIntColumn(oldVersion),
i_dbPolicy));
}
}
}
else
{// it's not an optimistic lock
// If this is a time stamp column that is only
// stamped on insert, it is NEVER part of an update
statement,
// so skip it.
if (aColumnSpec instanceof
TimestampColumnSpecDbGen)
{
TimestampColumnSpecDbGen tc =
(TimestampColumnSpecDbGen) aColumnSpec;
if (tc.isInsertOnly())
{
continue;
}
}
if (prepared)
{
sqlBuffer.append(aColumnSpec.getPreparedSqlValueString(false,
i_dbPolicy,
i_domain.getSequenceName(),
i_domain.getTableName()));
}
else
{
sqlBuffer.append(
aColumnSpec.getSqlValueFrom(aPO,
i_dbPolicy));
}
}
}
}// else not a primary key
}// while
// Create the WHERE clause
sqlBuffer.append(" WHERE ");
if (prepared)
{
if (pkColumnSpec == null)
{
throw new RuntimeException(
"CRITICAL error: " + tableName + " has no primary
key column spec." + sqlBuffer.toString());
}
sqlBuffer.append(pkColumnSpec.buildPreparedWhereClause(tableName));
}
else
{
sqlBuffer.append(
pkColumnSpec.buildWhereClause(aPO,
ColumnSpec.EQUALS,
tableName,
i_dbPolicy));
}
// Append to WHERE statement if we have an optimistic lock.
if (lockingColumnSpec != null)
{
// If object was changed (probably by someone else) since
last being
// read, this will prevent the update from occurring.
sqlBuffer.append(" AND ");
sqlBuffer.append(
lockingColumnSpec.getFullyQualifiedColumnName(tableName));
sqlBuffer.append(" = ");
if (prepared)
{
sqlBuffer.append(" ? ");
}
else
{
sqlBuffer.append(
lockingColumnSpec.getSqlValueFrom(aPO,
i_dbPolicy));
}
}
return sqlBuffer.toString();
}// buildSQL(PersistentObject)
>>> Tom Miller <tm...@li...> 11/15/02 11:11PM >>>
I would like to know the relationship between
AbstractColumnSpec.writeOnce() in the JRFBaseSchema.dtd used to
generate
database objects and SQL, and
TimeStampColumnSpecDbGen.setInsertOnly().
It appears that these are intended to do the same thing, that is,
write
a column only on insert, such as a date created Timestamp (which is
what
I want to do).
writeOnce is a boolean in
net.sf.jrf.domain.PersistentObjectDynaProperty, so I assume it only
applies if one is using Dynabeans. It does not seem to do anything on
standard domains.
I think what may be missing is an insertOnly attribute for Column in
JRFBaseSchema, and then the code in BaseGenerator to supply
setInsertOnly for the column in the generated domain. Or is there some
other explanation?
--
Tom Miller
Miller Associates, Inc.
tm...@li...
641.469.3535 Phone
413.581.6326 FAX
-------------------------------------------------------
This sf.net email is sponsored by: To learn the basics of securing
your web site with SSL, click here to get a FREE TRIAL of a Thawte
Server Certificate: http://www.gothawte.com/rd524.html
_______________________________________________
jrf-user mailing list
jrf...@li...
https://lists.sourceforge.net/lists/listinfo/jrf-user
|
|
From: Tom M. <tm...@li...> - 2002-11-18 22:24:26
|
I tried your patch. It did seem to get the insertOnly field set properly. The
update SQL gets created properly, omitting the field. However, when I trace
through the framework, invariably, the date_created gets updated along with the
other fields! I'm stumped.
So have you tested for results Darren? Is it working for you? What version of
JRF and what database are you using? I'm using JRF 2.0b4 and mySQL 4.0.3.
Jay, if you're reading the mail, do you have any suggestions?
Thanks
--
Tom Miller
Miller Associates, Inc.
tm...@li...
641.469.3535 Phone
413.581.6326 FAX
Darren Senel wrote:
> FYI,
>
> The TimeStampColumnSpecDbGen.setInsertOnly() does not seem to work. We
> had to do a
> code modification to UpdateSQLBuilder.java to correct the issue (we did
> this on Friday
> last week and so have not submitted this change to the message board
> yet).
>
> The problem lies in the fact that the UpdateSQLBuilder does not take
> any notice of the
> TimeStampColumnSpecDbGen.setInsertOnly() value when building update
> statements.
>
> For anyone that is interested our updated code is shown below (this was
> a quick fix and
> may not be the best solution).....
>
> private String buildSQL(boolean prepared,
> PersistentObject aPO,
> String tableName,
> List columnSpecs)
> {
> ColumnSpec aColumnSpec = null;
> ColumnSpec pkColumnSpec = null;
> ColumnSpec lockingColumnSpec = null;
>
> checkPolicy();
>
> StringBuffer sqlBuffer = new StringBuffer();
> sqlBuffer.append(" UPDATE ");
> sqlBuffer.append(tableName);
> sqlBuffer.append(" SET ");
> int count = 0;
> // Create an assignment expression for each column
> boolean isInsertOnly = false;
> Iterator iterator = columnSpecs.iterator();
> while (iterator.hasNext())
> {
> isInsertOnly = false;
> aColumnSpec = (ColumnSpec) iterator.next();
> if (aColumnSpec.isPrimaryKey())
> {
> pkColumnSpec = aColumnSpec;// save for later
> }
> else
> {// not a primary key
> if (aColumnSpec instanceof TimestampColumnSpecDbGen)
> {
> isInsertOnly =
> ((TimestampColumnSpecDbGen)aColumnSpec).isInsertOnly();
> }
>
> if (!isInsertOnly)
> {
>
> if (count > 0)
> {// BUG Fix -- PK may not be the first column in the
> list.
> sqlBuffer.append(", ");
> }
> count++;
>
> sqlBuffer.append(
> aColumnSpec.getColumnName());
> sqlBuffer.append(" = ");
> if (aColumnSpec.isOptimisticLock())
> {
> lockingColumnSpec = aColumnSpec;// save for later
> if (aColumnSpec instanceof
> TimestampColumnSpecDbGen)
> {
>
> sqlBuffer.append(i_dbPolicy.timestampFunction());
> }
> else
> {// Assume it's an IntegerColumnSpec
>
> if (prepared)
> {
> sqlBuffer.append("?");
> }
> else
> {
> Integer oldVersion = (Integer)
> aColumnSpec.getValueFrom(aPO);
>
> sqlBuffer.append(aColumnSpec.formatForSql(getNewOptimIntColumn(oldVersion),
> i_dbPolicy));
> }
> }
> }
> else
> {// it's not an optimistic lock
>
> // If this is a time stamp column that is only
> // stamped on insert, it is NEVER part of an update
> statement,
> // so skip it.
> if (aColumnSpec instanceof
> TimestampColumnSpecDbGen)
> {
> TimestampColumnSpecDbGen tc =
> (TimestampColumnSpecDbGen) aColumnSpec;
> if (tc.isInsertOnly())
> {
> continue;
> }
> }
> if (prepared)
> {
>
> sqlBuffer.append(aColumnSpec.getPreparedSqlValueString(false,
> i_dbPolicy,
> i_domain.getSequenceName(),
> i_domain.getTableName()));
> }
> else
> {
> sqlBuffer.append(
> aColumnSpec.getSqlValueFrom(aPO,
> i_dbPolicy));
> }
> }
> }
> }// else not a primary key
> }// while
> // Create the WHERE clause
> sqlBuffer.append(" WHERE ");
> if (prepared)
> {
> if (pkColumnSpec == null)
> {
> throw new RuntimeException(
> "CRITICAL error: " + tableName + " has no primary
> key column spec." + sqlBuffer.toString());
> }
>
> sqlBuffer.append(pkColumnSpec.buildPreparedWhereClause(tableName));
> }
> else
> {
> sqlBuffer.append(
> pkColumnSpec.buildWhereClause(aPO,
> ColumnSpec.EQUALS,
> tableName,
> i_dbPolicy));
> }
> // Append to WHERE statement if we have an optimistic lock.
> if (lockingColumnSpec != null)
> {
> // If object was changed (probably by someone else) since
> last being
> // read, this will prevent the update from occurring.
> sqlBuffer.append(" AND ");
> sqlBuffer.append(
>
> lockingColumnSpec.getFullyQualifiedColumnName(tableName));
> sqlBuffer.append(" = ");
> if (prepared)
> {
> sqlBuffer.append(" ? ");
> }
> else
> {
> sqlBuffer.append(
> lockingColumnSpec.getSqlValueFrom(aPO,
> i_dbPolicy));
> }
> }
> return sqlBuffer.toString();
> }// buildSQL(PersistentObject)
>
> >>> Tom Miller <tm...@li...> 11/15/02 11:11PM >>>
> I would like to know the relationship between
> AbstractColumnSpec.writeOnce() in the JRFBaseSchema.dtd used to
> generate
> database objects and SQL, and
> TimeStampColumnSpecDbGen.setInsertOnly().
>
> It appears that these are intended to do the same thing, that is,
> write
> a column only on insert, such as a date created Timestamp (which is
> what
> I want to do).
>
> writeOnce is a boolean in
> net.sf.jrf.domain.PersistentObjectDynaProperty, so I assume it only
> applies if one is using Dynabeans. It does not seem to do anything on
> standard domains.
>
> I think what may be missing is an insertOnly attribute for Column in
> JRFBaseSchema, and then the code in BaseGenerator to supply
> setInsertOnly for the column in the generated domain. Or is there some
> other explanation?
|