Here's the problem as I see it: Postgresql used to allow you to specify parameter types which did not match the column type, in the timestamp case if you passed in a parameter specified as varchar it would automatically attempt to convert it to a timestamp. Now Postgresql requires that you either pass in the correct parameter type for the column or otherwise pass the parameter type as unknown/unspecified. Postgresql still doesn't care whether you pass in a string or a timestamp but you MUST specify the correct sql type.
If letting the database take care of the type conversion has never been a problem before, why do we need to worry about it now? Remember the only problem here is that we are passing in a string specified as varchar instead of a string specified as java.sql.Types.Timestamp. Regards Scott 2008/10/14 Adrian Crum <[EMAIL PROTECTED]>: > I understood your alternatives. I apologize for being unclear. > > You said, "or to just throw an exception when the wrong data type is passed > like the commented out code in GenericEntity referenced above does." > > And I'm saying we could do that, but it's going to get interesting because a > lot of code passes Strings into the entity engine. In other words, if we > throw a "hard" exception, there is a good chance that much of OFBiz won't > run. > > Personally, I'd like to see better handling of object types in the higher > level code. I fixed a problem over the weekend that was caused by this very > thing (passing Strings into the entity engine). > > -Adrian > > > David E Jones wrote: >> >> I'm referring to the exception I described in the GenericEntity.java file, >> lines 410-415. Right now it is just a warning in the log (and has been for >> years). The reason to do it there instead of letting the JDBC driver do it >> is that not all developers will test on all possible databases, and this >> will help avoid errors as people use different databases in >> development/testing or deployment. >> >> I tried to describe two possible approaches to improve this situation in >> my first message. Please let me know if those alternatives were not clear >> and I'll try to explain them better. >> >> -David >> >> >> On Oct 13, 2008, at 5:22 PM, Adrian Crum wrote: >> >>> Wasn't that being done already? Jacques started these changes based on >>> exceptions being thrown by his JDBC driver. Other DBs seemed to be working >>> okay. >>> >>> I guess we could throw our own exception to keep things consistent across >>> databases. It will be interesting to see how that affects existing code. >>> >>> -Adrian >>> >>> >>> David E Jones wrote: >>>> >>>> That is a very good point, and I agree. >>>> To me that means we go with the fail-fast approach and have it throw an >>>> exception if you pass in something that is not the correct object type. >>>> Is that what you meant? >>>> -David >>>> On Oct 13, 2008, at 4:57 PM, Adrian Crum wrote: >>>>> >>>>> I would prefer handling object types in higher level code - due to >>>>> ambiguity in how some types would be converted from a String (currency, >>>>> date, time, etc). >>>>> >>>>> -Adrian >>>>> >>>>> David E Jones wrote: >>>>>> >>>>>> This has been a potential problem for a while, but the decision was >>>>>> made quite a while back to not enforce the correct object type. >>>>>> There is code in the GenericEntity.java file (lines 410-415) to check >>>>>> to see if the value passed in matches the object type for the field it is >>>>>> being set on. >>>>>> The best way to solve this problem is a good question. It might be >>>>>> good to introduce some automatic type conversion, or to just throw an >>>>>> exception when the wrong data type is passed like the commented out code >>>>>> in >>>>>> GenericEntity referenced above does. >>>>>> The most common form of automatic conversion is from String to >>>>>> whatever the field's object type is, and that is done by the >>>>>> GenericEntity.setString method. >>>>>> So, what do people think about this? Should we do an automatic type >>>>>> conversion to try to fix programming errors automatically, or do a >>>>>> fail-fast >>>>>> by throwing an exception when the object type is wrong? I suppose the >>>>>> current fail-quiet (in the log) and fail loudly on certain databases >>>>>> later >>>>>> is not the best option... >>>>>> -David >>>>>> On Oct 12, 2008, at 2:20 PM, Scott Gray wrote: >>>>>>> >>>>>>> I've had a look into this and I can't see anything related to Groovy >>>>>>> that is making this necessary, it appears to be entirely a postgresql >>>>>>> issue. >>>>>>> >>>>>>> When executing a prepared statement postgresql seems to require that >>>>>>> the parameter list sql types match the column types. So the problem >>>>>>> isn't that we are passing in a string but that we are setting the sql >>>>>>> type to character varying by using PreparedStatement.setString(). >>>>>>> >>>>>>> Here's a patch that fixes the issue but I'm not really confident >>>>>>> enough to commit it, it would be great to get some comments from >>>>>>> people who know more about this kind of thing: >>>>>>> >>>>>>> Index: framework/entity/src/org/ofbiz/entity/jdbc/SQLProcessor.java >>>>>>> =================================================================== >>>>>>> --- framework/entity/src/org/ofbiz/entity/jdbc/SQLProcessor.java >>>>>>> (revision >>>>>>> 703572) >>>>>>> +++ framework/entity/src/org/ofbiz/entity/jdbc/SQLProcessor.java >>>>>>> (working copy) >>>>>>> @@ -592,6 +592,22 @@ >>>>>>> * >>>>>>> * @throws SQLException >>>>>>> */ >>>>>>> + public void setValueTimestampString(String field) throws >>>>>>> SQLException { >>>>>>> + if (field != null) { >>>>>>> + _ps.setObject(_ind, field, Types.TIMESTAMP); >>>>>>> + } else { >>>>>>> + _ps.setNull(_ind, Types.TIMESTAMP); >>>>>>> + } >>>>>>> + _ind++; >>>>>>> + } >>>>>>> + >>>>>>> + /** >>>>>>> + * Set the next binding variable of the currently active >>>>>>> prepared >>>>>>> statement. >>>>>>> + * >>>>>>> + * @param field >>>>>>> + * >>>>>>> + * @throws SQLException >>>>>>> + */ >>>>>>> public void setValue(java.sql.Time field) throws SQLException { >>>>>>> if (field != null) { >>>>>>> _ps.setTime(_ind, field); >>>>>>> Index: framework/entity/src/org/ofbiz/entity/jdbc/SqlJdbcUtil.java >>>>>>> =================================================================== >>>>>>> --- framework/entity/src/org/ofbiz/entity/jdbc/SqlJdbcUtil.java >>>>>>> (revision >>>>>>> 703572) >>>>>>> +++ framework/entity/src/org/ofbiz/entity/jdbc/SqlJdbcUtil.java >>>>>>> (working copy) >>>>>>> @@ -731,6 +731,9 @@ >>>>>>> fieldClassName = "byte[]"; >>>>>>> } >>>>>>> >>>>>>> + if ("java.sql.Timestamp".equals(fieldType)) { >>>>>>> + fieldClassName = fieldType; >>>>>>> + } >>>>>>> if (Debug.verboseOn()) Debug.logVerbose("type of >>>>>>> field " + entityName + "." + modelField.getName() + >>>>>>> " is " + fieldClassName + ", was expecting " >>>>>>> + mft.getJavaType() + "; this may " + >>>>>>> "indicate an error in the configuration or in >>>>>>> the class, and may result " + >>>>>>> @@ -749,7 +752,11 @@ >>>>>>> break; >>>>>>> >>>>>>> case 2: >>>>>>> - sqlP.setValue((java.sql.Timestamp) fieldValue); >>>>>>> + if (fieldValue instanceof String) { >>>>>>> + sqlP.setValueTimestampString((String) >>>>>>> fieldValue); >>>>>>> + } else { >>>>>>> + sqlP.setValue((java.sql.Timestamp) fieldValue); >>>>>>> + } >>>>>>> break; >>>>>>> >>>>>>> case 3: >>>>>>> >>>>>>> Regards >>>>>>> Scott >>>>>>> >>>>>>> >>>>>>> 2008/10/13 Jacques Le Roux <[EMAIL PROTECTED]>: >>>>>>>> >>>>>>>> Done in revision: 703816 >>>>>>>> It was not possible for PackingSlip.groovy and >>>>>>>> FindInventoryEventPlan.groovy. Because there the date string is >>>>>>>> build >>>>>>>> dynamically in the Groovy file >>>>>>>> >>>>>>>> Jacques >>>>>>>> >>>>>>>> From: "Jacques Le Roux" <[EMAIL PROTECTED]> >>>>>>>>> >>>>>>>>> Adrian, >>>>>>>>> >>>>>>>>> Yes good idea indeed, I will do that >>>>>>>>> >>>>>>>>> Jacques >>>>>>>>> >>>>>>>>> From: "Adrian Crum" <[EMAIL PROTECTED]> >>>>>>>>>> >>>>>>>>>> Jacques, >>>>>>>>>> >>>>>>>>>> Instead of modifying the groovy files, try specifying the data >>>>>>>>>> type in >>>>>>>>>> the screen widget. >>>>>>>>>> >>>>>>>>>> Example in ReportFinancialSummaryScreens.xml: >>>>>>>>>> >>>>>>>>>> <set field="fromDate" from-field="parameters.fromDate" >>>>>>>>>> type="Timestamp"/> >>>>>>>>>> <set field="thruDate" from-field="parameters.thruDate" >>>>>>>>>> type="Timestamp"/> >>>>>>>>>> <script >>>>>>>>>> >>>>>>>>>> location="component://accounting/webapp/accounting/WEB-INF/actions/reports/TransactionTotals.groovy"/> >>>>>>>>>> >>>>>>>>>> -Adrian >>>>>>>> >>>>>>>> >> >> >