aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes How to handle deleted records after find Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Java 8 in Action this week in the Java 8 forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "How to handle deleted records after find" Watch "How to handle deleted records after find" New topic
Author

How to handle deleted records after find

Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
the main logic of my findRooms method at Business-level that GUI clients use for search data is :
1) getInstance() to obtain unique singlenton instance of Data-class;
2) call to find(searchCriteria) on that singleton-instance;
3) loop the results of point "2)" and for every found record call read(recNo)-method on the singleton-instance;

I have all methods of Data-class synchronized (only private methods of Data-class are not synchronized) - therefore at point "2)" (see above) nothing bad happen,
but when I loop through found records at point "3)" the current single record between points "2)" and "3)" can be :
a) deleted;
b) deleted and recreated (my create method reuses deleted records);

The first question is : must we handle these situations ("a)" and "b)") in findRooms of Business-class ?

Even through we must not - the read(recNo)'s method signature declares "throws RecordNotFoundException"...
Therefore the second question is : how can i handle this RecordNotFoundException ? RecordNotFoundException is checked because it is the recoverable condition. Can i only write message on the console : "System.out.println('This is the message for future release that handle the delete function')" or something similar ? Is it enough ?

Thank you for help (hope that i was clear)...
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 4925
    
  10

must we handle these situations ("a)" and "b)") in findRooms of Business-class ?

Of course you must handle them, but it won't take a lot of extra effort:
a) you catch the RNFE, but just ignore it (maybe add some code comment "record could have been deleted, so just ignoring"). this handles the deleted records
b) now the deleted and recreated records: because you have to filter the returned records (in the client you just want to see exact matches, the find-method returns startsWith matches) these recreated records will get filtered out if they don't match.

Another alternative: you could create an extra find-method (in your own interface which extends the given interface) which returns the record numbers and the actual records, so with just one call you'll get what you need (and you don't need to catch possible RNFEs). You still need to apply the exact match filter

Hope it helps!


SCJA, SCJP (1.4 | 5.0 | 6.0), SCJD
http://www.javaroe.be/
Sean Keane
Ranch Hand

Joined: Nov 03, 2010
Posts: 581

There are three options that come to my mind:

1) Ignore the exception. The findRooms method returns all records that it can find back to the user (i.e. it ignores the fact that some records may be deleted in between searching for the records and getting the record information).
2) Don't ignore the exception. The findRooms method throws and exception and no records are returned to the user.
3) Make the entire operation atomic. So it is not possible for a record to get deleted in between searching and retrieving the information for records.

I would go with option (1).


SCJP (1.4 | 5.0), OCJP (6.0), OCMJD
Sean Keane
Ranch Hand

Joined: Nov 03, 2010
Posts: 581

Roel De Nijs wrote:b) now the deleted and recreated records: because you have to filter the returned records (in the client you just want to see exact matches, the find-method returns startsWith matches) these recreated records will get filtered out if they don't match.


It is worth mentioning that this will only apply if you are reusing records. But very valid point!

Even if you have reused record numbers, I guess there is nothing stopping you ignore this possibility and highlighting it in your choices?

How did you handle this Roel? Create a seperate find method in your Data class that returned record details in one atomic operation?
Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
Yes it is very useful advice, thank you Roel !

I think that "Another alternative" solution is more clear and less error prone (and seems to conform to invaluable KISS-universalDesignPattern ).

Item 1 :
- I add new "public synchronized Map<Integer, String[]> findRecords(String[] criteria)" to my suncertify.db.AdvancedDB (suncertify.db.AdvancedDB extends suncertify.db.DB);
- the new findRecords will call original suncertify.db.Data's find(String[] criteria) method and then read(recNo) for every found record to construct of Map<Integer, String[]>;
- in my the new findRecords I will catch the RNFE, but just ignore it (in catch block I will add some code comment "record could have been deleted...").

then the main logic of my findRooms method at Business-level that GUI clients use for search, thansforms in :
1) getInstance() to obtain unique singlenton instance of Data-class;
2) call to the new findRecords(String[] criteria) on that singleton-instance;

At this point i handle all situations at Server-level (Data-class) :
a) record deleted;
b) record deleted and recreated.

Item 2 :
"You still need to apply the exact match filter" - why this step if my synchronized findRecords(String[] criteria) return me exact searched records ?

(the original find(String[] criteria) called from my new findRecords(String[] criteria) has the following core check :

[edit] do not post actual code snippets

Is the logic in Item 1 (see above) seems correct ?

Why and when must i apply the exact match filter after calling new findRecords(String[] criteria) ?

Thank you in advance...
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 4925
    
  10

Sean Keane wrote:How did you handle this Roel? Create a seperate find method in your Data class that returned record details in one atomic operation?

That's exactly what I did Just ignoring the RNFE (as you opted in your previous post) is just as good. I would certainly not opt for option 2 of your previous post
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 4925
    
  10

Dmitri Cherkas wrote:- in my the new findRecords I will catch the RNFE, but just ignore it (in catch block I will add some code comment "record could have been deleted...").

your code comment makes no sense at all, because you are executing an atomic operation, no records can't be deleted when executing this findRecords-method.

Dmitri Cherkas wrote:Why and when must i apply the exact match filter after calling new findRecords(String[] criteria) ?

startsWith-matching is not the same as exact matches. And according to your instructions you should only see exact matches appear in the JTable.
Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
Roel De Nijs wrote:
your code comment makes no sense at all, because you are executing an atomic operation, no records can't be deleted when executing this findRecords-method.

Yes you are right...

Roel De Nijs wrote:
startsWith-matching is not the same as exact matches.

You are right another time (some finesses of ass.instructions kill me)...

Therefore find-method on search criteria "Fred" will return "Fred", "Freddy" and "Freding", but in JTable i will view only "Fred"-record... Am i right ?
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 4925
    
  10

Dmitri Cherkas wrote:herefore find-method on search criteria "Fred" will return "Fred", "Freddy" and "Freding", but in JTable i will view only "Fred"-record... Am i right ?
Sean Keane
Ranch Hand

Joined: Nov 03, 2010
Posts: 581

I think that ignoring the RecordNotFoundException is a safe enough approach, so you could go with not making the entire operation atomic.

The more important question I think that if you are reusing record numbers can you ignore the fact that a record number returned from the find method could in fact refer to a totally different record when you go to get the information for that record?

On the face of it, I think this second scenario will be dealt with ok. Because you must filter the search results for exact matches. So when you come across a record that has been deleted and a new one recreated with the same ID it either will or will not match the entire search critieria.

If the recreated record matches the entire search criteria, then everything is OK and the record will be displayed in the GUI. If the record does not match the entire search criteria then it will be filtered out of the final list of records and thus will never get displayed in the GUI.

So there should be no need for an atomic operation in this second scenario either as filtering ensures that we will never have incorrect records being displayed in the GUI. Sound analysis?

Of course adding a separate atomic find operation to the Data class as Roel has done is far more intuitive. Otherwise you would have to document the behaviour I described above so that any new developers working with your code were aware of how it operated without having to figure it out themselves.
Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
Thank you Roel, thank you Sean !
Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
Sean Keane wrote:
...Because you must filter the search results for exact matches. So when you come across a record that has been deleted and a new one recreated with the same ID it either will or will not match the entire search critieria..


If I understand the application logic well, the GUI-clients do only one call to Business-level (findRooms method) during the search records. After this single call, the GUI-client locally filters returned results for exact matches - therefore client cannot know if records to view in JTable deleted or recreated. Clients only view filtered records returned from Business-level.

Do I miss something in application logic ?
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 4925
    
  10

My business service does the filtering. My GUI just shows what it gets from the business service. Filtering out the records is a business requirement, so why not adding the filtering in your business service
Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
"Filtering the records (returned from Data-class) on business-lever to return the exact matches" sounds very logical to me...
Sean Keane
Ranch Hand

Joined: Nov 03, 2010
Posts: 581

I do my filtering in my Business Service class (i.e. on server side). But when it comes to reusing deleted records, where you do the filtering is not the key, the key is that you do the filtering .

Regardless of where you do the filtering, the fact that you must filter the results guarantees that you will not display invalid records in the GUI (i.e. records that reuse the ID of a deleted record, where the deleted record matched the search criteria but the new record does not match the search criteria).

Based on the fact that you are guaranteed that invalid records will not be displayed in the GUI by using the find method and filtering, you could avoid creating an atomic operation in the Data class to carry out this operation, instead noting it in your choices.txt as a valid enhancement for the future .
Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
The "exact match filtering" destroy logic of my application a little...

1) the find-method of Data-class has (String[] criteria) as a parameter, but when I loop criteria-array to compare with database records I use numberOfFieldsInRecord-field dinamically populated when i read database file at the start of the program :

in the findRooms-method of Business-class i must reexecute similar for-loop on returned records to find exact matches :
2) the findRooms-method of Business-class also has (String... criteria) as a parameter, and this criteria-array passes me GUI-client. But in this case I havn't access to numberOfFieldsInRecord (this field cannot be public because it's cannot be changed, and cannot be final because database is read out of constructor).

In this case I have mismatch in logic (the length of criteria-array passed me from GUI-client is out of control)... and now I cannot see how to solve this mismatch... Can you suggest me anything ?
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 4925
    
  10

Dmitri Cherkas wrote:Can you suggest me anything ?

I don't know why you need to loop in findRooms-method in your business service You just need the index of the location and name fields, because those ones are the only one you can search one. Another alternative would be: introduce a value object instead of using String[], it will make your life a whole lot easier (because you can do something like room.getLocation().equals(givenLocation)).
Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
This is the worse day of the month (i am about quantity of work in my office)

I think I understand what you mean, Roel... and it seems logical...

Actually it means to have :
1) universal Data-class (its find-method can search on each field of database-record)
2) and tuned for assignment-needs Business-class (its findRooms-method can search only on "hotel name" and/or "hotel location" fields),

am I right ?

I already redesign tomorrow findRooms-method to take as parameter Room-valueobject instead of String[].

Now my findRooms-method is simpler : it has a Room parameter and loop results of Data's find-method to compare (exact match) only "hotel name" and/or "hotel location".

About "and/or" i use the following logic :
a) if in Room-parameter of the findRooms-method "name != null and location != null" I apply search "name AND location" : return database records that has "name AND location equals to name AND location of search criteria (Room-parameter)",
b) if in Room-parameter of the findRooms-method "name != null but location == null" I apply search only for "name" : return database records that has "name equals to name of search criteria (Room-parameter)",
c) if in Room-parameter of the findRooms-method "name == null but location != null" I apply search only for "location" : return database records that has "location equals to location of search criteria (Room-parameter)".

What do you think about all it above ? or ?
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 4925
    
  10

Dmitri Cherkas wrote:am I right ?



Dmitri Cherkas wrote:I already redesign tomorrow findRooms-method to take as parameter Room-valueobject instead of String[].

That's already a good improvement (in comparison of using String[] or seperate Strings), but maybe you can consider creating a RoomFilter-object. This object is only used for searching. Could you think of some advantage(s) for using a seperate RoomFilter-object (instead of reusing the Room-object).

Dmitri Cherkas wrote:What do you think about all it above ?

I have a similar implementation, so definitely (even if it would be different from my implementation, but was meeting the requirements you got the thumbup )
Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
Roel wrote:
That's already a good improvement (in comparison of using String[] or seperate Strings), but maybe you can consider creating a RoomFilter-object. This object is only used for searching. Could you think of some advantage(s) for using a seperate RoomFilter-object (instead of reusing the Room-object).

At this moment i don't see advantage(s) for using a seperate RoomFilter-object... but only because now I have not panoramic view of my complete application... I will remember you council implementing GUI. Thank you Roel !

And the last small question before definitively finish with Business-layer and start with RMI-level :

My main logic of book-method of Business-level is :

[edit] don't provide actual code snippets

the situations "1_1)", "3), 3_1), 3_2)" are controllable and logical, but what can i do in case of "2_1)" ? This situation can not occur (the record is locked), but read-method of Data-class declares RecordNotFoundException in the method signature...
In catch-block of "2_1)" :
a) could I simply trace, writing message on console (System.out.println("Record deleted, but this situation never occur.")) ?
b) do nothing or just write a comment within catch-block can be interpret as "eating" the exceptional condition ?
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 4925
    
  10

Dmitri Cherkas wrote:At this moment i don't see advantage(s) for using a seperate RoomFilter-object... but only because now I have not panoramic view of my complete application...

It has nothing to do with the current application, but with possible new functionality in future releases.

Dmitri Cherkas wrote:And the last small question

I added a few code comments and throw an IllegalStateException (which wraps the RNFE). I would certainly not opt for logging, because log files are rarely looked at when no problem occur
Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
Roel wrote: It has nothing to do with the current application, but with possible new functionality in future releases.
Interesting... very interesting...

About booking and RecordNotFoundException in read after lock : from "Effective Java Second Edition (Joshua Bloch)", Chapter 9, Item 60: "... IllegalStateException. This is generally the exception to throw if the invocation is illegal because of the state of the receiving object."

But if you used java.lang.IllegalStateException to handle this situation :

and pass with famous score i will use this construct too...

Thank you, Roel ! Have a nice day.
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 4925
    
  10

Dmitri Cherkas wrote:Interesting... very interesting...

Something to think about: what will you do if the business guys want to be able to search on minimum and maximum price of a room. How will you implement that one?

Dmitri Cherkas wrote:Effective Java Second Edition (Joshua Bloch)

That book is on my reading list.

Dmitri Cherkas wrote:This is generally the exception to throw if the invocation is illegal because of the state of the receiving object.

That's what the javadoc of the class says too, so indeed it might not be the most appropriate exception to be thrown in this situation.
Sarah Archer
Greenhorn

Joined: Jul 25, 2010
Posts: 19
Dmitri Cherkas wrote:
... But if you used java.lang.IllegalStateException to handle this situation ... and pass with famous score i will use this construct too...


That's such a bad reason to use an IllegalStateException - and you can hardly put it in your choices.txt If you have a good reason for doing something different, and you have, then you should go with it.
Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
Hello, Sarah !

Thank you for your reply...

My logic seems to be :
1) "Roel used java.lang.IllegalStateException to handle the situation where using java.lang.IllegalStateException is very disputable"
2) "but Roel passed with famous score"
3) "therefore I will use this construct too"

but the above logic chain doesn't specify two background elements :
1_1) the first and most fundamental is : from "Effective Java Second Edition (Joshua Bloch)", Chapter 9, Item 60: "... be aware that choosing which exception to reuse is not always an exact science."
2_2) (incur from "1_1)" ) if using java.lang.IllegalStateException in this case is OK for Sun (Oracle) (Roel passes), therefore i can handle it in the same manner.

You are right - i must not write in "choices.txt" "1) - 2) - 3)", but only
a) "I used java.lang.IllegalStateException to handle the situation where using java.lang.IllegalStateException is very disputable"
b) but in this case it's OK, because : from "Effective Java Second Edition (Joshua Bloch)", Chapter 9, Item 60: "... be aware that choosing which exception to reuse is not always an exact science."
c) something else...

I don't know better exception to use in this case and I thank Roel for the sincere suggestion in this non trivial situation.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: How to handle deleted records after find
 
Similar Threads
Scaratching left side with right hand - Client identification with service instance
pls validate my locking strategy - all inputs are g8ly appreciated. (URLyBird)
nx:All of URLy Bird 1.1.3 about read/write lock
Locking confusion -- help
Is there any benefit in the RMI Factory solution - when you have a lock cookie in your interface?