You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-user@db.apache.org by Martin Kalén <mk...@apache.org> on 2005/06/20 11:25:37 UTC

[PB-API] Problem with assertValidPkForDelete and Long(0) as PK

Greetings,
  after updating my local codebase with Jakob's latest fixes for applying
FieldConversion classes internally I am having problems with PB-API delete()
calls.

I have successfully been able to remove all work-arounds for 'manually'
applying FieldConversions when reading trigger-set values back from DB
and in ReportQuery result collections -- the new code simplifies PB-API
usage a lot in these cases (if using FieldConversions)!


However; I got stuck on the following - any hints, ideas or suggestions?

I am storing an object with a composite PK where one column is allowed
to contain numeric 0 values. INSERT and UPDATE are OK but DELETE fails
with "Cannot delete object without valid PKs." because the check
assertValidPkForDelete in BrokerHelper calls representsNull on line 482
and the Long(0) value is considered invalid...

Complete invocation chain for the delete-blocking detection is:
DelegatingPersistenceBroker#delete(Object)
PersistenceBrokerImpl#delete(Object)
PersistenceBrokerImpl#delete(Object, boolean=false)
PersistenceBrokerImpl#doDelete(Object, boolean=false)
BrokerHelper#assertValidPkForDelete(ClassDescriptor, Object)
BrokerHelper#representsNull(FieldDescriptor, Object)

The check that fails is line 273 of BrokerHelper rev 1.57.2.17,
since the object field is a long (ie type=primitive) and value
is instance of Number with longValue=0.

IMO the representsNull definition is wrong, since 0 as PK might very
well be OK. Am I overlooking something?


OJB-version is from CVS, OJB_1_0_RELEASE branch and DB is Oracle9i.

DDL:
  CREATE TABLE G (
	O_ID NUMBER(14,0) NOT NULL,
	G_ID NUMBER(4,0) NOT NULL,
	...
	CONSTRAINT G_PK PRIMARY KEY (GEOMETRI_ID, OBJEKT_ID)
  );

Repository mapping:
  <field-descriptor column="G_ID" name="gId" jdbc-type="NUMERIC" primarykey="true" 
conversion="...NonNullBigDecimal2longFieldConversion"/>
  <field-descriptor column="O_ID" name="oId" jdbc-type="NUMERIC" primarykey="true"/>

Object fields:
  private long oId;
  private long gId;

Field conversion:
  public class NonNullBigDecimal2longFieldConversion implements FieldConversion {

   public Object javaToSql(Object obj) {
     return obj;
   }

   public Object sqlToJava(Object o) {
     if (o == null) {
       return null;
     }
     if (o instanceof Number) {
       return new Long(((Number) o).longValue());
     }
     throw new ConversionException("Error: Couldn´t convert BigDecimal to long");
    }

  }


Regards,
  Martin

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-user-help@db.apache.org


Re: [PB-API] Problem with assertValidPkForDelete and Long(0) as PK

Posted by Martin Kalén <mk...@apache.org>.
Armin Waibel wrote:
> I would suggest to source out the "representsNull" check in a separate 
> pluggable service class to allow user to implement their own checks and 
> to introduce a new attribute "null-value" in field-descriptor to allow 
> user-specific "null values" (e.g. -1, 0, "null", ...).

Sounds good! Following up on the dev-list...

Regards,
  Martin


---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-user-help@db.apache.org


Re: [PB-API] Problem with assertValidPkForDelete and Long(0) as PK

Posted by Martin Kalén <mk...@apache.org>.
Armin Waibel wrote:
>> I was considering the custom attribute, but that felt a bit too much
>> like "untyped" properties and the documentation sort of hints that
>> the custom attributes are used as "property-bag" for extended or
>> specialized FieldDescriptor implementations.
>>
>> Much like RDBMS-specific JDBC-properties set on the connection 
>> descriptor.
> 
> Agree. Nevertheless we can use custom attributes to "test" new 
> features/properties or to introduce a workaround for existing bugs 
> without changing the repository.dtd and integrate these properties as 
> elements/attributes in the next major release.

True, on the other hand people that start using custom attributes
might be annoyed when the setting "moves" to an attribute in the next
release. Hmm... I see a point in both locations now (attribute vs
custom property), but tend to think that a new attribute is still my
preferred choice (it won't break anything for existing users although
it's a DTD change, since it's an addition that has a backwards-
compatible #IMPLIED choice). What's your verdict? :)

> there is one thing I don't understand, you said:
>  > The relaxed version works perfectly for my use-case where a primary
>  > key numeric field is represented by a Java Long, is not nullable
>  > but where id=0 is a valid db-value that should not trigger sequence
>  > autonumbering or any delete/insert checks in OJB.
> 
> I would expect that the current version of #representsNull allows id=0 
> for non-primitive fields (e.g. Long).

I didn't tell the whole truth so it's not so easy to understand...
The thing is that this field is represented in the database (Oracle 9i)
as a NUMBER with a precision that gives a Java BigDecimal
representation. There is an OJB field conversion that takes care of
BigDecimal <=> long conversion, but since FieldConversion requires
an object representation it's an intermediate Long involved.

> For development I use intellij and I simply check out 
> ../branches/OJB_1_0_RELEASE and .../trunk from
> https://svn.apache.org:443/repos/asf

OK, I'll start with commits on /branches/OJB_1_0_RELEASE then.

> But for example I don't know how to "diff" between /trunk and 
> /branches/OJB_1_0_RELEASE in Intellij IDE - I love CVS ;-)

I hope I have figured it out by then. :)
Thanks for the OJB vs SVN primer!

Cheers,
  Martin


---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Re: [PB-API] Problem with assertValidPkForDelete and Long(0) as PK

Posted by Armin Waibel <ar...@apache.org>.
Hi Martin,

Martin Kalén wrote:
> Armin Waibel wrote:
>> Long time no see!
> 
> Yes, it's sure been a while! :)
> 
>>> I know that at least Armin usually does not like more attributes in 
>>> repository.xml, but this time I will try to make you accept an 
>>> exception to the rule. :) Since null-check configuration is very 
>>> similar to conversion, I propose the following DTD change for 
>>> <field-descriptor/>:
>>>
>>>     The null-check attribute contains a fully qualified class name.
>>>     This class must implement the interface
>>>     org.apache.ojb.broker.accesslayer.NullCheck.
>>>     A NullCheck can be used to implement special requirements for
>>>     the definitions of a field's 'null' value as Java representation.
>>>
>>>     null-check CDATA #IMPLIED
>>
>> an alternative would be to use a custom attribute "null-check" in 
>> field-descriptor (then we don't need to change the dtd). But I agree 
>> that a new attribute will be more transparent.
> 
> I was considering the custom attribute, but that felt a bit too much
> like "untyped" properties and the documentation sort of hints that
> the custom attributes are used as "property-bag" for extended or
> specialized FieldDescriptor implementations.
> 
> Much like RDBMS-specific JDBC-properties set on the connection descriptor.

Agree. Nevertheless we can use custom attributes to "test" new 
features/properties or to introduce a workaround for existing bugs 
without changing the repository.dtd and integrate these properties as 
elements/attributes in the next major release.


> 
>> What about OJB's xdoclet module, do we need to adapt the @ojb.field 
>> tag too?
> 
> Yes I think so, I would need help with this (probably Tom's?) as I don't
> know enough about the xdoclet part myself.
> 
> My plan was to:
> 1. discuss the implementation and make appropriate changes in my local 
> codebase
> 2. update OJB-150 and check in code on 1.0.x branch for everything 
> except xdoclet
> 3. get helt to make xdoclet additions
> 4. forward-port to OJB 1.1 branch
> 5. close OJB-150

+1, but there is one thing I don't understand, you said:
 > The relaxed version works perfectly for my use-case where a primary
 > key numeric field is represented by a Java Long, is not nullable
 > but where id=0 is a valid db-value that should not trigger sequence
 > autonumbering or any delete/insert checks in OJB.

I would expect that the current version of #representsNull allows id=0 
for non-primitive fields (e.g. Long).


> 
>> What about the FK fields? These fields have to reflect the same 
>> behavior as the PK fields. Do you expect that the user defines the 
>> same "null-check" attribute in all FK fields of the referenced 
>> objects? If this is the case we should add some kind of "check" (check 
>> if the PK field and FK field use the same NullCheck implementation, if 
>> not log an error msg or throw an exception) when OJB collects the FK 
>> fields of a reference the first time.
> 
> You're right. This needs to be consistent on "both sides" of the FK,
> I will give that some thought and test different approaches on my local
> use-case...
> 

+1


>>> BTW, what's the currently endorsed strategy for additions like this?
>>
>> We don't have a strategy (we decide as the case arises).
> 
> OK, so if my 5-step-plan above seems about right, could you guys give me
> a short "OJB vs. SVN" 101 course? :)
> 
> What should I check out from SVN if I want to make additions that I want 
> included in a future 1.0.5 maintenance release.

Sorry, I'm a rookie in SVN stuff.
Did you prepare your apache account?
http://apache.org/dev/version-control.html

For development I use intellij and I simply check out 
../branches/OJB_1_0_RELEASE and .../trunk from
https://svn.apache.org:443/repos/asf

But for example I don't know how to "diff" between /trunk and 
/branches/OJB_1_0_RELEASE in Intellij IDE - I love CVS ;-)

regards,
Armin


> 
> And later on, what do I check out when I want to merge this with the 1.1 
> branch?
> 
> Locally I have made additions to "db/ojb/tags/OJB_1_0_4" to be able to
> compare with results from 1.0.4 release, but I guess commits there would
> actually update a tag that should be frozen?
> 
> As you have figured out now I'm a bit of a SVN rookie, stuck with CVS...
> 
> Regards,
>  Martin
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-dev-help@db.apache.org
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Re: [PB-API] Problem with assertValidPkForDelete and Long(0) as PK

Posted by Martin Kalén <mk...@apache.org>.
Armin Waibel wrote:
> Long time no see!

Yes, it's sure been a while! :)

>> I know that at least Armin usually does not like more attributes in 
>> repository.xml, but this time I will try to make you accept an 
>> exception to the rule. :) Since null-check configuration is very 
>> similar to conversion, I propose the following DTD change for 
>> <field-descriptor/>:
>>
>>     The null-check attribute contains a fully qualified class name.
>>     This class must implement the interface
>>     org.apache.ojb.broker.accesslayer.NullCheck.
>>     A NullCheck can be used to implement special requirements for
>>     the definitions of a field's 'null' value as Java representation.
>>
>>     null-check CDATA #IMPLIED
> 
> an alternative would be to use a custom attribute "null-check" in 
> field-descriptor (then we don't need to change the dtd). But I agree 
> that a new attribute will be more transparent.

I was considering the custom attribute, but that felt a bit too much
like "untyped" properties and the documentation sort of hints that
the custom attributes are used as "property-bag" for extended or
specialized FieldDescriptor implementations.

Much like RDBMS-specific JDBC-properties set on the connection descriptor.

> What about OJB's xdoclet module, do we need to adapt the @ojb.field tag 
> too?

Yes I think so, I would need help with this (probably Tom's?) as I don't
know enough about the xdoclet part myself.

My plan was to:
1. discuss the implementation and make appropriate changes in my local 
codebase
2. update OJB-150 and check in code on 1.0.x branch for everything 
except xdoclet
3. get helt to make xdoclet additions
4. forward-port to OJB 1.1 branch
5. close OJB-150

> What about the FK fields? These fields have to reflect the same behavior 
> as the PK fields. Do you expect that the user defines the same 
> "null-check" attribute in all FK fields of the referenced objects? If 
> this is the case we should add some kind of "check" (check if the PK 
> field and FK field use the same NullCheck implementation, if not log an 
> error msg or throw an exception) when OJB collects the FK fields of a 
> reference the first time.

You're right. This needs to be consistent on "both sides" of the FK,
I will give that some thought and test different approaches on my local
use-case...

>> BTW, what's the currently endorsed strategy for additions like this?
> 
> We don't have a strategy (we decide as the case arises).

OK, so if my 5-step-plan above seems about right, could you guys give me
a short "OJB vs. SVN" 101 course? :)

What should I check out from SVN if I want to make additions that I want 
included in a future 1.0.5 maintenance release.

And later on, what do I check out when I want to merge this with the 1.1 
branch?

Locally I have made additions to "db/ojb/tags/OJB_1_0_4" to be able to
compare with results from 1.0.4 release, but I guess commits there would
actually update a tag that should be frozen?

As you have figured out now I'm a bit of a SVN rookie, stuck with CVS...

Regards,
  Martin

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Re: [PB-API] Problem with assertValidPkForDelete and Long(0) as PK

Posted by Martin Kalén <mk...@apache.org>.
Armin Waibel wrote:
> What about the FK fields? These fields have to reflect the same behavior 
> as the PK fields. Do you expect that the user defines the same 
> "null-check" attribute in all FK fields of the referenced objects? If 
> this is the case we should add some kind of "check" (check if the PK 
> field and FK field use the same NullCheck implementation, if not log an 
> error msg or throw an exception) when OJB collects the FK fields of a 
> reference the first time.

I'm currently trying to find a good place to implement this check,
but I could use some creative ideas or suggestions.

The PK NullCheck functionality itself is already in place, but the
question is how to implement the "consistency check" so that it
covers all different references in the mapping.

Eg what about a referece-descriptor where the FK of the referenced
class points to a non-PK field of the current class, must one
define the same null-check in both class-descriptors there and should
OJB do consistency checking? Currently I tend to think that's the case,
but haven't found a good way to implement the consistency checking.

Regards,
  Martin

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Re: [PB-API] Problem with assertValidPkForDelete and Long(0) as PK

Posted by Armin Waibel <ar...@apache.org>.
Hi Martin,

Long time no see!

Martin Kalén wrote:
> Greetings Armin and others,
>  now I finally have some allocated time to see this through.
>
> Armin Waibel wrote:
>> Martin Kalén wrote:
>>> I propose that we:
>>> a) reduce the default representsNull semantics in BrokerHelper to a
>>> minimal is null check (if even that)
>>
>> Maybe we should source out all "PK/FK is null" stuff from BrokerHelper 
>> to a pluggable class "NullCheck?"
>>
>> hasNullPKField(ClassDescriptor cld, Object obj)
>> representsNull(FieldDescriptor fld, Object aValue)
>> assertValidPksForStore(FieldDescriptor[] fieldDescriptors, Object[] 
>> pkValues)
>> assertValidPkForDelete(ClassDescriptor cld, Object obj)
>>
>> because BrokerHelper is a conglomeration of "unassigned" methods and 
>> get bigger and bigger, but in this case we can bundle methods into 
>> coherence.
> 
> I have successfully tried a minimalistic approach of this which worked
> very well. The interface is called NullCheck and has only one method:
> 
>     /**
>      * Returns wether the given object value represents 'null' for the 
> specified field.
>      * @param fld descriptor representation of the persistent field
>      * @param aValue the value to check if it represents 'null'
>      * @return true if and only if aValue represents null
>      */
>     boolean representsNull(FieldDescriptor fld, Object aValue);
> 
> Since the other BrokerHelper methods make their definitions based on
> "representsNull" this is the only one that really needs to be factored out.
> 
> 
> I know that at least Armin usually does not like more attributes in 
> repository.xml, but this time I will try to make you accept an exception 
> to the rule. :) Since null-check configuration is very similar to 
> conversion, I propose the following DTD change for <field-descriptor/>:
> 
>     The null-check attribute contains a fully qualified class name.
>     This class must implement the interface
>     org.apache.ojb.broker.accesslayer.NullCheck.
>     A NullCheck can be used to implement special requirements for
>     the definitions of a field's 'null' value as Java representation.
> 
>     null-check CDATA #IMPLIED
> 

an alternative would be to use a custom attribute "null-check" in 
field-descriptor (then we don't need to change the dtd). But I agree 
that a new attribute will be more transparent.
What about OJB's xdoclet module, do we need to adapt the @ojb.field tag too?


> 
> I have create two implementations, NullCheckDefaultImpl containing
> the old code from BrokerHelper (this is the default if @null-check
> is not specified) and NullCheckRelaxedImpl:
>  public boolean representsNull(FieldDescriptor fld, Object aValue) {
>   return aValue == null;
>  }
> 
> The relaxed version works perfectly for my use-case where a primary
> key numeric field is represented by a Java Long, is not nullable
> but where id=0 is a valid db-value that should not trigger sequence
> autonumbering or any delete/insert checks in OJB.
> 
> Any comments on this? I will create a JIRA issue and attach some
> comments and code to track this issue for OJB 1.0.5.
>

What about the FK fields? These fields have to reflect the same behavior 
as the PK fields. Do you expect that the user defines the same 
"null-check" attribute in all FK fields of the referenced objects? If 
this is the case we should add some kind of "check" (check if the PK 
field and FK field use the same NullCheck implementation, if not log an 
error msg or throw an exception) when OJB collects the FK fields of a 
reference the first time.


> BTW, what's the currently endorsed strategy for additions like this?

We don't have a strategy (we decide as the case arises).

regards,
Armin

> This is an old very close-to-1.0.4 patch so I would like to start
> adding it for a 1.0.5 release and then forward-merge to 1.1.
> If OJB 1.1 is close to release I guess this strategy is a
> bit backwards? :)
> 
> Cheers,
>  Martin
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-dev-help@db.apache.org
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Re: [PB-API] Problem with assertValidPkForDelete and Long(0) as PK

Posted by Martin Kalén <mk...@apache.org>.
Greetings Armin and others,
  now I finally have some allocated time to see this through.

Armin Waibel wrote:
> Martin Kalén wrote:
>> I propose that we:
>> a) reduce the default representsNull semantics in BrokerHelper to a
>> minimal is null check (if even that)
> 
> Maybe we should source out all "PK/FK is null" stuff from BrokerHelper 
> to a pluggable class "NullCheck?"
> 
> hasNullPKField(ClassDescriptor cld, Object obj)
> representsNull(FieldDescriptor fld, Object aValue)
> assertValidPksForStore(FieldDescriptor[] fieldDescriptors, Object[] 
> pkValues)
> assertValidPkForDelete(ClassDescriptor cld, Object obj)
> 
> because BrokerHelper is a conglomeration of "unassigned" methods and get 
> bigger and bigger, but in this case we can bundle methods into coherence.

I have successfully tried a minimalistic approach of this which worked
very well. The interface is called NullCheck and has only one method:

     /**
      * Returns wether the given object value represents 'null' for the 
specified field.
      * @param fld descriptor representation of the persistent field
      * @param aValue the value to check if it represents 'null'
      * @return true if and only if aValue represents null
      */
	boolean representsNull(FieldDescriptor fld, Object aValue);

Since the other BrokerHelper methods make their definitions based on
"representsNull" this is the only one that really needs to be factored out.


I know that at least Armin usually does not like more attributes in 
repository.xml, but this time I will try to make you accept an exception 
to the rule. :) Since null-check configuration is very similar to 
conversion, I propose the following DTD change for <field-descriptor/>:

	The null-check attribute contains a fully qualified class name.
	This class must implement the interface
	org.apache.ojb.broker.accesslayer.NullCheck.
	A NullCheck can be used to implement special requirements for
	the definitions of a field's 'null' value as Java representation.

	null-check CDATA #IMPLIED


I have create two implementations, NullCheckDefaultImpl containing
the old code from BrokerHelper (this is the default if @null-check
is not specified) and NullCheckRelaxedImpl:
  public boolean representsNull(FieldDescriptor fld, Object aValue) {
   return aValue == null;
  }

The relaxed version works perfectly for my use-case where a primary
key numeric field is represented by a Java Long, is not nullable
but where id=0 is a valid db-value that should not trigger sequence
autonumbering or any delete/insert checks in OJB.

Any comments on this? I will create a JIRA issue and attach some
comments and code to track this issue for OJB 1.0.5.

BTW, what's the currently endorsed strategy for additions like this?
This is an old very close-to-1.0.4 patch so I would like to start
adding it for a 1.0.5 release and then forward-merge to 1.1.
If OJB 1.1 is close to release I guess this strategy is a
bit backwards? :)

Cheers,
  Martin

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Re: [PB-API] Problem with assertValidPkForDelete and Long(0) as PK

Posted by Armin Waibel <ar...@apache.org>.
Hi Martin,

Martin Kalén wrote:

> I propose that we:
> a) reduce the default representsNull semantics in BrokerHelper to a
> minimal is null check (if even that)
>

Maybe we should source out all "PK/FK is null" stuff from BrokerHelper 
to a pluggable class "NullCheck?"

hasNullPKField(ClassDescriptor cld, Object obj)
representsNull(FieldDescriptor fld, Object aValue)
assertValidPksForStore(FieldDescriptor[] fieldDescriptors, Object[] 
pkValues)
assertValidPkForDelete(ClassDescriptor cld, Object obj)

because BrokerHelper is a conglomeration of "unassigned" methods and get 
bigger and bigger, but in this case we can bundle methods into coherence.

> b) as you suggest, introduce a new repository attribute for
> field-descriptor to define the "PK not initialized" semantics
> given a generic Object signature
>

How does the "PK not initialized"-check act together with the FK fields? 
E.g. if a user define null-check="-1" in the PK field, but does not 
declare a null-check in the FK-field of a 1:n reference? Should OJB 
check this on startup an throw an exception or should OJB "copy/inherit" 
the null-check to all FK fields?

Another part we have to check is the sql-generation. If a user define 
null-check="-1" then
- on insert/update/delete the column have to set to 'null' when the 
field have "-1" value
- when reading the ResultSet a 'null' value have to be "translated" to 
"-1" as field value


> To me "null-value" sounds a bit confusing, maybe something like
> "unset-check", "null-check", "uninitialized-check"?
> Any more clever suggestions? :)
>

Here is my ranking list:

1. null-check
1. unset-check
(+1 for both names)
3. uninitialized-check

regards,
Armin


> 
> I quote the original message below so that people not following the
> user's list can get up to speed:
> 
>> Martin Kalén wrote:
>>
>>> Greetings,
>>>  after updating my local codebase with Jakob's latest fixes for applying
>>> FieldConversion classes internally I am having problems with PB-API 
>>> delete()
>>> calls.
>>>
>>> I have successfully been able to remove all work-arounds for 'manually'
>>> applying FieldConversions when reading trigger-set values back from DB
>>> and in ReportQuery result collections -- the new code simplifies PB-API
>>> usage a lot in these cases (if using FieldConversions)!
>>>
>>>
>>> However; I got stuck on the following - any hints, ideas or suggestions?
>>>
>>> I am storing an object with a composite PK where one column is allowed
>>> to contain numeric 0 values. INSERT and UPDATE are OK but DELETE fails
>>> with "Cannot delete object without valid PKs." because the check
>>> assertValidPkForDelete in BrokerHelper calls representsNull on line 482
>>> and the Long(0) value is considered invalid...
>>>
>>> Complete invocation chain for the delete-blocking detection is:
>>> DelegatingPersistenceBroker#delete(Object)
>>> PersistenceBrokerImpl#delete(Object)
>>> PersistenceBrokerImpl#delete(Object, boolean=false)
>>> PersistenceBrokerImpl#doDelete(Object, boolean=false)
>>> BrokerHelper#assertValidPkForDelete(ClassDescriptor, Object)
>>> BrokerHelper#representsNull(FieldDescriptor, Object)
>>>
>>> The check that fails is line 273 of BrokerHelper rev 1.57.2.17,
>>> since the object field is a long (ie type=primitive) and value
>>> is instance of Number with longValue=0.
>>>
>>> IMO the representsNull definition is wrong, since 0 as PK might very
>>> well be OK. Am I overlooking something?
>>>
>>>
>>> OJB-version is from CVS, OJB_1_0_RELEASE branch and DB is Oracle9i.
>>>
>>> DDL:
>>>  CREATE TABLE G (
>>>     O_ID NUMBER(14,0) NOT NULL,
>>>     G_ID NUMBER(4,0) NOT NULL,
>>>     ...
>>>     CONSTRAINT G_PK PRIMARY KEY (GEOMETRI_ID, OBJEKT_ID)
>>>  );
>>>
>>> Repository mapping:
>>>  <field-descriptor column="G_ID" name="gId" jdbc-type="NUMERIC" 
>>> primarykey="true" 
>>> conversion="...NonNullBigDecimal2longFieldConversion"/>
>>>  <field-descriptor column="O_ID" name="oId" jdbc-type="NUMERIC" 
>>> primarykey="true"/>
>>>
>>> Object fields:
>>>  private long oId;
>>>  private long gId;
>>>
>>> Field conversion:
>>>  public class NonNullBigDecimal2longFieldConversion implements 
>>> FieldConversion {
>>>
>>>   public Object javaToSql(Object obj) {
>>>     return obj;
>>>   }
>>>
>>>   public Object sqlToJava(Object o) {
>>>     if (o == null) {
>>>       return null;
>>>     }
>>>     if (o instanceof Number) {
>>>       return new Long(((Number) o).longValue());
>>>     }
>>>     throw new ConversionException("Error: Couldn´t convert BigDecimal 
>>> to long");
>>>    }
>>>
>>>  }
> 
> 
> Regards,
>  Martin
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-dev-help@db.apache.org
> 
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Re: [PB-API] Problem with assertValidPkForDelete and Long(0) as PK

Posted by Martin Kalén <mk...@apache.org>.
Armin Waibel wrote:
> I would suggest to source out the "representsNull" check in a separate 
> pluggable service class to allow user to implement their own checks and 
> to introduce a new attribute "null-value" in field-descriptor to allow 
> user-specific "null values" (e.g. -1, 0, "null", ...).

This sounds like the best solution! It's in line with other OJB functional
areas, ie it fits nicely together with the FieldConversion concept.

I propose that we:
a) reduce the default representsNull semantics in BrokerHelper to a
minimal is null check (if even that)

b) as you suggest, introduce a new repository attribute for
field-descriptor to define the "PK not initialized" semantics
given a generic Object signature

To me "null-value" sounds a bit confusing, maybe something like
"unset-check", "null-check", "uninitialized-check"?
Any more clever suggestions? :)


I quote the original message below so that people not following the
user's list can get up to speed:

> Martin Kalén wrote:
> 
>> Greetings,
>>  after updating my local codebase with Jakob's latest fixes for applying
>> FieldConversion classes internally I am having problems with PB-API 
>> delete()
>> calls.
>>
>> I have successfully been able to remove all work-arounds for 'manually'
>> applying FieldConversions when reading trigger-set values back from DB
>> and in ReportQuery result collections -- the new code simplifies PB-API
>> usage a lot in these cases (if using FieldConversions)!
>>
>>
>> However; I got stuck on the following - any hints, ideas or suggestions?
>>
>> I am storing an object with a composite PK where one column is allowed
>> to contain numeric 0 values. INSERT and UPDATE are OK but DELETE fails
>> with "Cannot delete object without valid PKs." because the check
>> assertValidPkForDelete in BrokerHelper calls representsNull on line 482
>> and the Long(0) value is considered invalid...
>>
>> Complete invocation chain for the delete-blocking detection is:
>> DelegatingPersistenceBroker#delete(Object)
>> PersistenceBrokerImpl#delete(Object)
>> PersistenceBrokerImpl#delete(Object, boolean=false)
>> PersistenceBrokerImpl#doDelete(Object, boolean=false)
>> BrokerHelper#assertValidPkForDelete(ClassDescriptor, Object)
>> BrokerHelper#representsNull(FieldDescriptor, Object)
>>
>> The check that fails is line 273 of BrokerHelper rev 1.57.2.17,
>> since the object field is a long (ie type=primitive) and value
>> is instance of Number with longValue=0.
>>
>> IMO the representsNull definition is wrong, since 0 as PK might very
>> well be OK. Am I overlooking something?
>>
>>
>> OJB-version is from CVS, OJB_1_0_RELEASE branch and DB is Oracle9i.
>>
>> DDL:
>>  CREATE TABLE G (
>>     O_ID NUMBER(14,0) NOT NULL,
>>     G_ID NUMBER(4,0) NOT NULL,
>>     ...
>>     CONSTRAINT G_PK PRIMARY KEY (GEOMETRI_ID, OBJEKT_ID)
>>  );
>>
>> Repository mapping:
>>  <field-descriptor column="G_ID" name="gId" jdbc-type="NUMERIC" 
>> primarykey="true" conversion="...NonNullBigDecimal2longFieldConversion"/>
>>  <field-descriptor column="O_ID" name="oId" jdbc-type="NUMERIC" 
>> primarykey="true"/>
>>
>> Object fields:
>>  private long oId;
>>  private long gId;
>>
>> Field conversion:
>>  public class NonNullBigDecimal2longFieldConversion implements 
>> FieldConversion {
>>
>>   public Object javaToSql(Object obj) {
>>     return obj;
>>   }
>>
>>   public Object sqlToJava(Object o) {
>>     if (o == null) {
>>       return null;
>>     }
>>     if (o instanceof Number) {
>>       return new Long(((Number) o).longValue());
>>     }
>>     throw new ConversionException("Error: Couldn´t convert BigDecimal 
>> to long");
>>    }
>>
>>  }

Regards,
  Martin

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Re: [PB-API] Problem with assertValidPkForDelete and Long(0) as PK

Posted by Armin Waibel <ar...@apache.org>.
Hi Martin,

I would suggest to source out the "representsNull" check in a separate 
pluggable service class to allow user to implement their own checks and 
to introduce a new attribute "null-value" in field-descriptor to allow 
user-specific "null values" (e.g. -1, 0, "null", ...).

regards,
Armin


Martin Kalén wrote:
> Greetings,
>  after updating my local codebase with Jakob's latest fixes for applying
> FieldConversion classes internally I am having problems with PB-API 
> delete()
> calls.
> 
> I have successfully been able to remove all work-arounds for 'manually'
> applying FieldConversions when reading trigger-set values back from DB
> and in ReportQuery result collections -- the new code simplifies PB-API
> usage a lot in these cases (if using FieldConversions)!
> 
> 
> However; I got stuck on the following - any hints, ideas or suggestions?
> 
> I am storing an object with a composite PK where one column is allowed
> to contain numeric 0 values. INSERT and UPDATE are OK but DELETE fails
> with "Cannot delete object without valid PKs." because the check
> assertValidPkForDelete in BrokerHelper calls representsNull on line 482
> and the Long(0) value is considered invalid...
> 
> Complete invocation chain for the delete-blocking detection is:
> DelegatingPersistenceBroker#delete(Object)
> PersistenceBrokerImpl#delete(Object)
> PersistenceBrokerImpl#delete(Object, boolean=false)
> PersistenceBrokerImpl#doDelete(Object, boolean=false)
> BrokerHelper#assertValidPkForDelete(ClassDescriptor, Object)
> BrokerHelper#representsNull(FieldDescriptor, Object)
> 
> The check that fails is line 273 of BrokerHelper rev 1.57.2.17,
> since the object field is a long (ie type=primitive) and value
> is instance of Number with longValue=0.
> 
> IMO the representsNull definition is wrong, since 0 as PK might very
> well be OK. Am I overlooking something?
> 
> 
> OJB-version is from CVS, OJB_1_0_RELEASE branch and DB is Oracle9i.
> 
> DDL:
>  CREATE TABLE G (
>     O_ID NUMBER(14,0) NOT NULL,
>     G_ID NUMBER(4,0) NOT NULL,
>     ...
>     CONSTRAINT G_PK PRIMARY KEY (GEOMETRI_ID, OBJEKT_ID)
>  );
> 
> Repository mapping:
>  <field-descriptor column="G_ID" name="gId" jdbc-type="NUMERIC" 
> primarykey="true" conversion="...NonNullBigDecimal2longFieldConversion"/>
>  <field-descriptor column="O_ID" name="oId" jdbc-type="NUMERIC" 
> primarykey="true"/>
> 
> Object fields:
>  private long oId;
>  private long gId;
> 
> Field conversion:
>  public class NonNullBigDecimal2longFieldConversion implements 
> FieldConversion {
> 
>   public Object javaToSql(Object obj) {
>     return obj;
>   }
> 
>   public Object sqlToJava(Object o) {
>     if (o == null) {
>       return null;
>     }
>     if (o instanceof Number) {
>       return new Long(((Number) o).longValue());
>     }
>     throw new ConversionException("Error: Couldn´t convert BigDecimal to 
> long");
>    }
> 
>  }
> 
> 
> Regards,
>  Martin
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-user-help@db.apache.org
> 
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-user-help@db.apache.org