Hi Noc2,

take a look at: http://castor.codehaus.org/key-generator.html about the
options you have with keygenerators.

Regards
Ralf


Noc2 schrieb:
> hello Ralf!
> 
> Thanks for you reply! I understand the problem now. Thanks for the
> explanation.
> 
> While i was busy with the problem i noticed something else as well. I
> mentioned something about mysql doing an auto-incrementation of the ID in
> the Performance table. 
> 
> With the knowledge of your reply, i changed the code yesterday. I made a new
> field in the database called "Date" of the type date, and the start and stop
> have become bigint in the database. When i need to display time, the bigints
> are turned into longs, and the longs are then used in the Timeconstructor in
> java. 
> 
> Anyway, i decided to disable the auto-incrementation. I had to write
> something to generate keys then, and i needed to test it. But my testcode of
> performance, and the testdatabase hadnt been changed yet, so i there was no
> bigint or separate "date" field yet, and you know what? With the
> auto-increment disabled, the code did work. 
> 
> Are there perhaps any known bugs with the auto-increment? i performed a
> quick search, but on behalf of my job, i cant spend too much time on
> googling for problems that have been resolved already. 
> 
> Again, thank you very much for your reply, i learned something from it.
> 
> regards, 
> noc2
> 
> 
> 
> Ralf Joachim-2 wrote:
>> Hi Noc2,
>>
>> according to your description I can not see anything that you may be
>> doing wrong. But there is one problem that I faced myself sometime ago.
>>
>> Let's assume you set your start timestamp as follows:
>>
>> perf.setStart(new Date());
>>
>> The start timestamp then holds a value that has millisecond resolution.
>> If you store this value to a database column that has only second
>> resolution the milliseconds will not be contained in the database. If
>> you try to update this object in another transaction Castor will load
>> the object from the database and compares it with the cached one. At
>> this time Castor recognizes that the start timestamp form the database
>> is not the same as the one of the object in cache because the
>> milliseconds are missing. This will lead to a ObjectModifiedException as
>> seen by you.
>>
>> Having said that this may also happen with other datatypes (e.g. if you
>> store a 30 char string into a database field with only 25 chars).
>>
>> Regards
>> Ralf
>>
>>
>> Noc2 schrieb:
>>> Hello everybody, 
>>>
>>> I am back with a new problem, a real mindcracker for me. As usual, it is
>>> possible that this problem is as easy as cake, then i will feel stupid
>>> again, but as it is now (with my limited knowledge) i cant seem to find a
>>> solution. 
>>>
>>> The situation is as following: 
>>>
>>> check the next piece of mapping: 
>>>
>>> <<<<<<<<<<<<<<<<<<<mapping>>>>>>>>>>>>>>>>
>>>
>>> <field name="start" type="date">
>>>                     <sql name="start" type="timestamp" />
>>> </field>
>>>
>>> <field name="stop" type="date">
>>>                     <sql name="stop" type="timestamp" />
>>> </field>
>>>
>>> <<<<<<<<<<<<<<<<<< end of mapping >>>>>>>>>>>
>>>
>>> As you can see, i am trying to "convert" java date obj into a timestamp
>>> object. 
>>> This piece of mapping tries to map a Performance Object, the code
>>> following
>>> here: 
>>>
>>> *********************** start of code **************************
>>>
>>> public class Performance implements TimeStampable {
>>>     
>>>     private int performanceID;
>>>     private int userID;
>>>     private int activityID;
>>>     private Date start;
>>>     private Date stop;
>>>     
>>>     private long timestamp = 0;
>>>     
>>>     public long jdoGetTimeStamp(){
>>>             return timestamp;
>>>     }
>>>     
>>>     public void jdoSetTimeStamp(long timestamp){
>>>             this.timestamp = timestamp;
>>>     }
>>>     
>>>     
>>>     public int getUserID() {
>>>             return userID;
>>>     }
>>>     public void setUserID(int userID) {
>>>             this.userID = userID;
>>>     }
>>>     public int getActivityID() {
>>>             return activityID;
>>>     }
>>>     public void setActivityID(int activityID) {
>>>             this.activityID = activityID;
>>>     }
>>>     public Date getStart() {
>>>             return start;
>>>     }
>>>     public void setStart(Date start) {
>>>             this.start = start;
>>>     }
>>>     public Date getStop() {
>>>             return stop;
>>>     }
>>>     public void setStop(Date stop) {
>>>             this.stop = stop;
>>>     }
>>>     public int getPerformanceID() {
>>>             return performanceID;
>>>     }
>>>     public void setPerformanceID(int performanceID) {
>>>             this.performanceID = performanceID;
>>>     }
>>> }
>>>
>>> ************************** end of code ***************************
>>>
>>> As you all can see, not much about it. 
>>>
>>> I recently solved the problems i had with caching and long transactions,
>>> everything worked perfectly, until i tried to create and update
>>> Performance
>>> objects in long transactions. 
>>>
>>> The scenario is as following: i create a performance object to track the
>>> start of some activity. Due to database restrictions (mysql), it is
>>> impossible to have a timestamp entry that is null (this might have
>>> nothing
>>> to do with the problem but i think its better to just tell everything). 
>>>
>>> Ofcourse i also need to know when the activity stops, so i perform an
>>> update
>>> on the Performance object when the activity stops, and i would then like
>>> to
>>> create a new Performance object for the next Activity. 
>>>
>>> But on the update, i get the following Exception and errormessage:
>>>
>>> org.exolab.castor.jdo.ObjectModifiedException: Invalid object timestamp
>>> detected.
>>>
>>> Now, to me, this looks very strange. ObjectModifiedException is thrown
>>> when
>>> there is a concurrency problem, more accurate, when one transaction is
>>> modifying an entry used by another transaction. 
>>> In my case, this is not really possible, because every single operation i
>>> perform on the database is a transaction that has been committed. To
>>> prove
>>> this, i ll give the code i use to update. 
>>>
>>> ************** start of code *************
>>> public void update(Object updatedObject) {
>>>             try {
>>>                     db.begin();
>>>                     
>>>                     db.update(updatedObject);
>>>                     
>>>                     logger.info("UPDATE COMPLETED");
>>>                     
>>>                     db.commit();
>>>                     
>>>             } catch (PersistenceException e) {
>>>                     logger.fatal("PersistanceException : " + 
>>> e.getMessage());
>>>                     e.printStackTrace();
>>>             }
>>>     }
>>> ********************* end of code **************
>>> In the application, when i create the currentPerformanceObject, it has no
>>> ID. I let MySql create an auto increasing number for that. So i figured i
>>> might be making my own object a dirty one, because castor isnt aware of
>>> the
>>> change in the database. So logically i tried to set the the dirty
>>> attribute
>>> in the mappingfile to ingnore, but with no effect (this also means that
>>> my
>>> theory about the ID is not correct as well). 
>>>
>>> I dont have a clue what could be wrong. To complete this post, i ll add
>>> the
>>> pieces of code where all this stuff happens. 
>>>
>>> ********************** start of code *********************
>>>
>>>             activityList.getList().addSelectionListener(new 
>>> SelectionListener(){
>>>                     public void widgetSelected(SelectionEvent event){
>>>                             MessageBox msgbox = new
>>> MessageBox(site.getShell(),SWT.ICON_INFORMATION|SWT.YES|SWT.NO);
>>>                             msgbox.setMessage("Are you sure you wish to 
>>> start this activity?");
>>>                             int msg = msgbox.open();
>>>                             if(msg == SWT.YES){
>>>                                     
>>>                                     if(currentPerformance != null){
>>>                                             endCurrentPerformance();
>>>                                     }
>>>                                     currentActivity =
>>> (Activity)activityList.getElementAt(activityList.getList().getSelectionIndex());
>>>                                     
>>> status.setText(statusText+currentActivity.getName());
>>>                                     
>>>                                     logActivity();
>>>                                     
>>>                             }
>>>                     }
>>>
>>>
>>>     private void logActivity(){
>>>             currentPerformance = new Performance();
>>>             
>>> currentPerformance.setActivityID(currentActivity.getActivityID());
>>>             currentPerformance.setUserID(Application.conn.getCurrentUser());
>>>             currentPerformance.setStart(new Date());
>>>             currentPerformance.setStop(null);
>>>             
>>>             
>>> Application.conn.getAccess().createPerformance(currentPerformance);
>>>             
>>>             System.out.println("THE TIMESTAMP OF THE PERFORMANCE OBJECT:
>>> "+currentPerformance.jdoGetTimeStamp());
>>>     }
>>>
>>> private void endCurrentPerformance(){
>>>             currentPerformance.setStop(new Date());
>>>             
>>>             System.out.println("THE TIMESTAMP OF THE PERFORMANCE OBJECT WHEN
>>> UPDATING:
>>> "+currentPerformance.jdoGetTimeStamp());
>>>             
>>>             
>>> Application.conn.getAccess().updatePerformance(currentPerformance);
>>>             
>>>             System.out.println("UPDATE COMPLETED");
>>>     }
>>>
>>> ******************** end of code **********************
>>>
>>> As you can see, all the activities are contained in a listviewer. When i
>>> click an activity, i want to make sure that the user didnt accidently
>>> clicked it, so i ask to confirm with a dialogbox. If there is a
>>> currentPerformance, i update it in 'endCurrentPerformance', if not, i
>>> just
>>> create a new Performance in 'logActivity'. 
>>>
>>> In my opinion this is a very strange situation. The errormessage
>>> indicates
>>> that there is an invalid object timestamp. I know that when i create a
>>> new
>>> object, the timestamp has to be 0, as an indication that the object is a
>>> new
>>> one. Castor changes the timestamp, so the object will not be forgotten. 
>>>
>>> I compare the timestamp value with the original one just before updating,
>>> and they are exactly the same. 
>>>
>>> In my application i use the same variable name to instantiate a new
>>> Performance. But since instantiating means assigning a new reference to
>>> the
>>> variable, it can not be that the new object has the timestamp of the
>>> object
>>> that was previously referenced by the same variable.  
>>>
>>> Any help on this matter would be very much appreciated. 
>>>
>>> greetings, 
>>>
>>> Noc2
>> -- 
>>
>> Syscon Ingenieurbüro für Meß- und Datentechnik GmbH
>> Ralf Joachim
>> Raiffeisenstraße 11
>> 72127 Kusterdingen
>> Germany
>>
>> Tel.   +49 7071 3690 52
>> Mobil: +49 173 9630135
>> Fax    +49 7071 3690 98
>>
>> Internet: www.syscon.eu
>> E-Mail: [EMAIL PROTECTED]
>>
>> Sitz der Gesellschaft: D-72127 Kusterdingen
>> Registereintrag: Amtsgericht Stuttgart, HRB 382295
>> Geschäftsleitung: Jens Joachim, Ralf Joachim
>>
>> ---------------------------------------------------------------------
>> To unsubscribe from this list please visit:
>>
>>     http://xircles.codehaus.org/manage_email
>>
>>
>>
> 

---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email

Reply via email to