aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes @deprecated DuplicateKeyException Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "@deprecated DuplicateKeyException" Watch "@deprecated DuplicateKeyException" New topic
Author

@deprecated DuplicateKeyException

Mat Banik
Ranch Hand

Joined: Jan 16, 2004
Posts: 57

Hello to all,

I�m having problem with my decision to:
- just describe in my choices that I�m not going to use the DuplicateKeyException
or
- describe it and use @deprecated javadoc tag ( @Deprecated annotation ).

If I should use �deprecated� I would appreciate an example on how it is done with exception classes-constructors (if it is even possible).

THX


SCJP 1.4 - 83%, SCJD 360-90%,
ITeezy.com
Anton Golovin
Ranch Hand

Joined: Jul 02, 2004
Posts: 476
Hi, Matej!

I would agrue very strongly against not using DuplicateKeyException. The create method, if implemented incorrectly, may cause the 44/80 locking score. DubplicateKeyException solves the problem. It is not the only way to solve the problem, but it is the preferred way to solve the problem.

Apparently - and I am giving away half the solution here - two competing threads running the create method may overwrite the same record!!!

Hope this helps.


Anton Golovin (anton.golovin@gmail.com) SCJP, SCJD, SCBCD, SCWCD, OCEJWSD, SCEA/OCMJEA [JEE certs from Sun/Oracle]
Barend Garvelink
Ranch Hand

Joined: Dec 07, 2004
Posts: 64
Apparently - and I am giving away half the solution here - two competing threads running the create method may overwrite the same record!!!


Despite synchronization?


SCJP 1.4, SCJD 1.4, SCWCD 1.3, ICSD:Websphere 5.1
Isaac Shabtay
Greenhorn

Joined: Oct 31, 2004
Posts: 10
Originally posted by Anton Golovin:

Apparently - and I am giving away half the solution here - two competing threads running the create method may overwrite the same record!!!


Well... If your program ever gets to such a "race condition", then I would say that you might want to rethink your way of synchronizing access to the database.


"Large Vehicles Require More Room" - Highway 69 en route to Sudbury, Ontario
Jim Janssens
Ranch Hand

Joined: Sep 24, 2004
Posts: 210
Originally posted by Anton Golovin:
Hi, Matej!

I would agrue very strongly against not using DuplicateKeyException. The create method, if implemented incorrectly, may cause the 44/80 locking score. DubplicateKeyException solves the problem. It is not the only way to solve the problem, but it is the preferred way to solve the problem.

Apparently - and I am giving away half the solution here - two competing threads running the create method may overwrite the same record!!!

Hope this helps.


I can understand that you want to assist by telling us you think it is a bad idea not to use the duplicateKeyException. But please give some reasonable explanation, because what I can deduct from your post is incorrect.

My opinion:

Two competing threads on a create() should not get the same record number assigned (this part you have correct). But when you do not use primary keys it has nothing to do with the DuplicateKeyException. You probably endup solving this by implementing the propper synchronization on the read/write and the propper synchronization on the system responsible for determining the next record number. So, when using no primary keys, you should not throw DuplicateKeyException.

To answer the TS his question; I don't think you should make it deprecated either. Deprecated means something may not be used anymore becase it is replaced by something else or it should not be used anymore because the use of it is dangerous. This is not the case with the DuplicateKeyException, it is a valid and crucial exception of every normal db implementation. I even think that in the future B&S will implement it when the extend it to deal with primary keys.


When using primary keys you *should* throw the DuplicateKeyException. Everytime you add a record you want to search the database and see if there is allready a record with the key. If false, you add it, if true you throw DuplicateKeyException.

When implementing primary keys, please keep this scenario in mind:

1. Thread1: create() record {a,b,c} with primary key {a,b}
2. Thread1: create() searches database for primary key
3. Thread1: create() result is false (does not exist)
4. Thread2: update() record {z,b,x} to {a,b,x}
5. Thread2: update() search database to see if this pk allready exists
6. Thread2: update() result is false (does not exist)
7. Thread2: update() commit update to file
8. Thread1: create() commit create to file

So in db you have: {a,b,c} and {a,b,c} . The primary is duplicate here, and this should never happen. The correct way would be that the create() or the update() (depending who is first) throw the DuplicateKeyException.

The solution for this:

a) implement the 'searches database for primary key' check on the lowest atomic write method (7 and 8)

==> when you want your Data class to be re-useable and not business logic aware, you'll find yourself in trouble passing the pk's due to the DB interface limitation.

b) lock your whole database

==> well, this you don't want to do...really
Barend Garvelink
Ranch Hand

Joined: Dec 07, 2004
Posts: 64
(off-topic: thank you Anton! I was about to submit my application, but your post tickled me to test the add() handler of my data layer a bit more thoroughly... and uncover a huge (as in: data corrupting) coding error that I somehow overlooked previously.)
Mat Banik
Ranch Hand

Joined: Jan 16, 2004
Posts: 57

Hi Koen,

Just to mention why I didn�t use DKE: I have the URLyBird 1.1.3 assignment where one customer can rent two or more of the same rooms at the same time, at the same location �.
The point is that I�m not able to establish primary key even when I join several columns together.
By the requirements it seems that the company is very dependent at the data file format and there is no way they are going to change it in the future.
Consequently I thought there is no need for DKE. So I started considering over the possibility of deprecation. Because I haven�t jet deprecated any exceptions I�m trying to gather more info on this topic.


Two competing threads on a create() should not get the same record number assigned (this part you have correct). But when you do not use primary keys it has nothing to do with the DuplicateKeyException. You probably endup solving this by implementing the propper synchronization on the read/write and the propper synchronization on the system responsible for determining the next record number. So, when using no primary keys, you should not throw DuplicateKeyException.


That is the way how I did it. All public Data methods synchronized one static RAF and one static lock Map for every instance of Data.


To answer the TS his question; I don't think you should make it deprecated either. Deprecated means something may not be used anymore because it is replaced by something else or it should not be used anymore because the use of it is dangerous. This is not the case with the DuplicateKeyException, it is a valid and crucial exception of every normal db implementation. I even think that in the future B&S will implement it when the extend it to deal with primary keys.


By considering the chance that the data file format is going to change in the future, this is very reasonable approach. But when my design is not supporting primary key at all and
if the need for primary key would arise than there would be lot of refactoring.
Requirements do not rule the DKE out so I�m just going to just stand my point in the choices document.

Thank you for your help.
Jan Groot
Greenhorn

Joined: Nov 13, 2004
Posts: 10
I'm also doing UrlyBird, concerning the create and delete method's in the data interface wich my client isn't using, does throwing an UnsuportedOperationException count as implementing? If so, is this acceptable?


SCJP 1.4<br />SCJD (in progress)
Jared Chapman
Ranch Hand

Joined: Feb 23, 2004
Posts: 81
When implementing primary keys, please keep this scenario in mind:

1. Thread1: create() record {a,b,c} with primary key {a,b}
2. Thread1: create() searches database for primary key
3. Thread1: create() result is false (does not exist)
4. Thread2: update() record {z,b,x} to {a,b,x}
5. Thread2: update() search database to see if this pk allready exists
6. Thread2: update() result is false (does not exist)
7. Thread2: update() commit update to file
8. Thread1: create() commit create to file

So in db you have: {a,b,c} and {a,b,c} . The primary is duplicate here, and this should never happen. The correct way would be that the create() or the update() (depending who is first) throw the DuplicateKeyException.

Just an idea this discussion led me to brainstorm. The update method doesn't throw a DuplicateKeyException, but should it? When choosing fields that make up the primary key, you choose fields that identify the record as unique, and the fields should not be expected to change. For example, the owner field is the worst possible field to be a primary key, because we expect its value to change. So why not prevent updating a record's primary key fields, and instead instruct the caller to delete the record and create a new one? Just an idea, please feel free to tear it apart.


B.S. University of Wisconsin<br />SCJP 1.4 (85%)<br />SCJD 1.4 (92%) B&S Contractors
Mat Banik
Ranch Hand

Joined: Jan 16, 2004
Posts: 57

Hi Jan,


I'm also doing UrlyBird, concerning the create and delete method's in the data interface wich my client isn't using, does throwing an UnsuportedOperationException count as implementing? If so, is this acceptable?


I believe that you have to implement the DB interface fully in the Data class. If you have adapter to the Data class there you could put the UnsuportedOperationException and be fine. I thing that I read about it somewhere in the forum. Take a search and you shell find what you seek.
Mat Banik
Ranch Hand

Joined: Jan 16, 2004
Posts: 57

Hi Jared,

First you should open new post for this topic cos it is entirely of this one.
Second you might consider indexes for the database file when using primary key.
Daniel Simpson
Ranch Hand

Joined: Sep 02, 2004
Posts: 181
Originally posted by Jared Chapman:

Just an idea this discussion led me to brainstorm. The update method doesn't throw a DuplicateKeyException, but should it? When choosing fields that make up the primary key, you choose fields that identify the record as unique, and the fields should not be expected to change. For example, the owner field is the worst possible field to be a primary key, because we expect its value to change. So why not prevent updating a record's primary key fields, and instead instruct the caller to delete the record and create a new one? Just an idea, please feel free to tear it apart.


That is a good point about the update method, Jared. I never thought about that. I wonder if that would be considered out of scope for this assignment though, since DKE is a checked exception, and we have to follow the DB interface exactly. Here was my approach for the create method. I didn't really feel that any field was sufficient enough to be a primary key, so I decided to test every value in the field (except the field for the customer's id showing that it is booked). And if all of the fields were same after trimming for whitespaces, it would throw a DKE, otherwise it would be considered unique. What do you think?


SCJP 1.4<br />SCJD 1.4
Jared Chapman
Ranch Hand

Joined: Feb 23, 2004
Posts: 81
Hey, Daniel, lets continue this discussion here.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: @deprecated DuplicateKeyException