File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes NX: RandomAccessFile / Singleton DataSchema 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 "NX: RandomAccessFile / Singleton DataSchema" Watch "NX: RandomAccessFile / Singleton DataSchema" New topic
Author

NX: RandomAccessFile / Singleton DataSchema

Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi everyone,
I have some questions concerning RandomAccessFile and the Singleton-Instance of DataSchema.
I have described my design of thread-safety in other threads but I do it once more. Concerning my question, I think it's important to post some code to be able to describe more clearly the problems.

and my constructor of Data.Class:

My DataSchema-Class is a Singleton:

So here my questions:
1. in Data-Class I haven't synchronized RandomAccessFile, I haven't it also in DataSchema, because i'm afraid of dead-lock, the synchronization is reduced to the mutex, which is a static private HashMap in Data-Class. But because the RAF action will be done from the same thread which is responsable for the elaborating of the Data-Class (I will have one Data-instance per client through Connection Factory), I think I'm Fine, or I'am not right?
2. Since within DataSchema I have a static reference to its Singleton Instance, does it make sense to have the code above within the finalize()-method?
3. Beside the static reference to its Singleton Instance, does it make sense to have static variables within DataSchema?
Due to its function as Singleton I would say no!?
Thanks in advance
Ulrich
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Ulrich,
1. You are OK.
2. The second line (me = null) is useless for sure, and I think (but I may be wrong) that the whole finalize() method isn't useful. A RAF probably closes itself before getting garbage-collected if needed (IMO).
3. Yes ! If you change your mind in the future (or if somebody else does), what's static remains static while any data which makes some sense at the instance level is just there we expect it to be.
Just one comment on your code : I like short variable names too, but I think that "ds" could be a better candidate than "me" as a name for your DataSchema instance.
Cheers,
Phil.
Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi Phil,
thanks, next time I'm in Brussels I will invite you to some beers
Regards
Ulrich
Vlad Rabkin
Ranch Hand

Joined: Jul 07, 2003
Posts: 555
Hi Ulrich,

Is FILE_NAME a constant in your application?
How do you set FILE_NAME?
I didn't understand your idea:
You call DataSchema.getInstance(), and after that you start reading a header?
Could you comment the sequence in which you feel your DataSchema singletone and the way it is first used?
Best,
Vlad
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Ulrich and Vlad,
Sorry, Ulrich when I wrote "Just one comment", I thought about three ones. 2) Vlad is right, why is FILE_NAME a constant ? (I guess it's just temporary) 3) You and Vlad know about it , I am too tired tonight to go on, I'll come back tomorrow morning, but in the meantime I'll just ask this : "Why did you keep that line ?!!"
next time I'm in Brussels I will invite you to some beers

Great ! As just after them I'll invite you to some beers too, mmh ... it's probably better we wait till we pass ! Vlad, we are 3 already ! Let's say that when we are 20 we pay the flight ticket Sydney-Brussels and back for Andrew to get those beers with us.
Best,
Phil.
[ September 30, 2003: Message edited by: Philippe Maquet ]
Vlad Rabkin
Ranch Hand

Joined: Jul 07, 2003
Posts: 555
Hi,
Vlad, we are 3 already ! Let's say that when we are 20 we pay the flight ticket Sydney-Brussels and back for Andrew to get those beers with us.

Cool idea!
One joke:
An airplain crashed on the small Island. Only three people survived: A French a German and a Russian.
After stayng there for a while they have suddenly met a Jin (a magic man). He offered to make true three desires for each survived man:
a French said: I want to get a beatufil woman, a good french wine and get home;
a German said: I want to get good car, good bear and get home;
a Russian said: I want to get vodka, something to eat and get back both French and German guys to have a good company to drink and eat all of this...


Best,
Vlad
[ September 30, 2003: Message edited by: Vlad Rabkin ]
Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi Phil & Vlad,
good joke, Vlad
I would suggest you to come next carneval to Cologne, to drink as much as we can to forget the whole stuff concerning thread, dead-thread, horrible threads
Is FILE_NAME a constant in your application?
How do you set FILE_NAME?

Phil, you're right that's just a temporary. I know, we will have to read the suncertify.properties to get the location of the db-file and then, of course, it can't be a constant anymore. But because I'm a little bit slow , I haven't reached this topic
Vlad, you wrote:
I didn't understand your idea:
You call DataSchema.getInstance(), and after that you start reading a header?

I think you mean:

Because I thought that we would have to check the MagicCookie once a client gets connected to the db.file.
Or do you see another alternative?
Greetings, good night,
Ulrich
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Vlad, we are 3 already ! Let's say that when we are 20 we pay the flight ticket Sydney-Brussels and back for Andrew to get those beers with us.
Oh, sure. And leave me stranded here in Arizona. See if I help you guys any more.


"I'm not back." - Bill Harding, Twister
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11460
    
  94

Hi Ulrich, Vlad, Phil, Jim ....
[Ulrich] in Data-Class I haven't synchronized RandomAccessFile, I haven't it also in DataSchema, because i'm afraid of dead-lock, the synchronization is reduced to the mutex, which is a static private HashMap in Data-Class. But because the RAF action will be done from the same thread which is responsable for the elaborating of the Data-Class (I will have one Data-instance per client through Connection Factory), I think I'm Fine, or I'am not right?

You may not have synchronized the RandomAccessFile itself, but since you seem to be doing all your access to the file within blocks synchronized on reservedRecords, you should be fine.
Which is a qualified way of saying that I agree with everyone that you should be fine.
I think I understand what Vlad is getting at. In my mind, the DataSchema class could verify the cookie and read the schema information. So when an instance of the Data class connects, that work is already done.
[Philippe] Vlad, we are 3 already ! Let's say that when we are 20 we pay the flight ticket Sydney-Brussels and back for Andrew to get those beers with us.

Man, I am so ready to go. I love those Belgian and Dutch beers. I started collecting beer glasses when I was in Holland - of course I had to buy the beers to go with the glasses . I remember one pub in Utrecht refused to sell me a particular beer because he had temporarily run out of the correct glass to put it in, and there was no way he would serve it in the wrong glass :roll:
Just let me know when ...
Regards, Andrew


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Vlad Rabkin
Ranch Hand

Joined: Jul 07, 2003
Posts: 555
Hi,
I think I understand what Vlad is getting at. In my mind, the DataSchema class could verify the cookie and read the schema information. So when an instance of the Data class connects, that work is already done.

Yeap. (For the case of Ulrich, because has has raf member variable inside DataSchema anyway).
In this DataSchema has to have (to my opinion) not getInstance(), but
getInstance(String fileName); The whole header will be read in DataSchema.
That is the way Jim has dne (not a singletone, but reading header inside DataSchema.
I personally do read not in DataSchema, but in Data, but I don have DataSchema.getMagicCookie() method. It is a public constant: DataSchema.MAGIC_COOKIE, so I don't need an instance of DataSchema at the moment my Data reads a header.
There are many ways to do all of this stuff, but I wouldn't do it the way Ulrich has done.
Guys one question from me:
My data class (and DBAdapter on the server) is mutition: I want to make it singletone.


public DBConnectionFactoryImpl(String fileName)
throws IOException, RemoteException {
super();
//create Data object
db = new DBAdapterLocal(fileName);
logger.log(Level.FINER, "Remote connection factory has been started.");
}
...
public DBAdapterRemote create()
throws IOException, RemoteException {
// create Remote Data object.
// All remote Data objects contain a shared instance
// of Data.
DBAdapterRemoteImpl dbRemote = new DBAdapterRemoteImpl(db);
return dbRemote;
}

It would allow me to have many DataAdapter instances of the server. The thing what I extremely don't like in a Singletone is that only lazy singletone initialization is possible in my design. It means that if any problem occury while connection to the file at first time, we will be able to see the problem while the first client connects to the server. The sample:
Data.getInstance(fileName);
Client connects to the DBConnectionFactory.
Clients invokes DBAdapter DBConnectionFactory.create();
The factory create DBAdapter, which wraps Data (meaning the constructor of
DBAdapter calles Data.getInstance(fileName);}
So, if something wrong is with the file (e.g. MagicCookie), the server admin will find out it only after Data.getInstance(fileName) is first called. It is very to my opinion.
I could make inside Data Singletone not a lazy inizialition, but it is impossible since Singletone doesn't know the name of the file at the start of the application.
Any ideas? (I don't want to throw away Factory class ;-) )
Jim:
Oh, sure. And leave me stranded here in Arizona. See if I help you guys any more

Didn't you get my joke? The point what I was saying it doesn't where to meet as long as have something interesting to do and to talk about, we will manage to find a meetpoint...
Ulrich
I would suggest you to come next carneval to Cologne

I leave in F/M. So it is about 190km from Cologne. My wife is about 1,5 year in Colognya in the CRM projects. She want me every year to come there and make fun together with her colleges, but I don't have much clue about Siebel and CRM (and they have not much respect for Java) and I was afraid to there are But now I can take a challenge !
Best,
Vlad
Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi,
Vlad:
I leave in F/M. So it is about 190km from Cologne. My wife is about 1,5 year in Colognya in the CRM projects. She want me every year to come there and make fun together with her colleges, but I don't have much clue about Siebel and CRM (and they have not much respect for Java) and I was afraid to there are But now I can take a challenge !

Four years ago, I worked also in F/M, but, sorry , I didn't like it. I've got too used to Cologne after moving my whole youth from this place to another. I'm getting older
But come next carneval to Cologne, I think that's really an experience. Because when you know people from Cologne then you can find the places where it's really
Because at the wrong places it can really be a nightmare wth all the people so drunk and vulgar.
Andrew, you australians are really amazing, I think that's really popular in Down Under to travel around the world, isn't it? But you have so good beers in Australia too
Oh, sure. And leave me stranded here in Arizona. See if I help you guys any more.

Jim, I was once in Arizona and I was so impressed, so don't expect our pitty The only thing I would miss there, beside little facts , is soccer, because I'm a great soccer fan, but I was impressed by the performance of the americans last World Cup
Greetings
Ulrich
[ October 01, 2003: Message edited by: Ulrich Heeger ]
Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi,
Andrew wrote:
I think I understand what Vlad is getting at. In my mind, the DataSchema class could verify the cookie and read the schema information. So when an instance of the Data class connects, that work is already done.

Vlad wrote:

In this DataSchema has to have (to my opinion) not getInstance(), but
getInstance(String fileName); The whole header will be read in DataSchema.
That is the way Jim has dne (not a singletone, but reading header inside DataSchema.

I resume:
So Andrew's suggest would consist in reading the MagicCookie only once, while Vlad suggests to check the MagicC. each time a client connects to DataSchema by passing the FileName as argument. Thus the work will be done by DataSchema.
Am I right?
Vlad wrote:
It would allow me to have many DataAdapter instances of the server. The thing what I extremely don't like in a Singletone is that only lazy singletone initialization is possible in my design. It means that if any problem occury while connection to the file at first time, we will be able to see the problem while the first client connects to the server.

I had also problems concerning the implementation of a non-lazy singleton init.. In another thread you gave me an example of a non-lazy singleton initialization.By implementation of this solution, I had problems concerning catching IOExceptions, I can avoid them by creating a static{}-block catching IOException and throwing RuntimeException.
But in your case, the problem is that you don't want to have direct access from Data to the File but only get the Filename through arguments. is that right? If yes, why don't you want to have direct access from Data-Class?
Regards
Ulrich
Arun Kumar
Ranch Hand

Joined: Aug 29, 2003
Posts: 67
Hi ppl,
Probably this is not the right thread to ask this question. But since you are discussing data schema here, and my question is related, i will ask here.
When i start my remote server (StartRemoteServer.java), the user gets to choose the database file using a JFileChooser. Once he chooses the file and then clicks "start server", i instantiate the DBInit class. This class in its constructor checks for the magic cookie, if not the correct one (it checks against a cookie in the properties file), it stops the server. Other than this, it initiates various static variables like number of columns, array of column names, array of columnlengths and other stuff from the db file header. So getting the schema happens only once during the server startup.
So inside the data class i have no problems accessing these data schema variables using DBInit.<variable name>.
The same process happens when the clinet is started in "alone" mode, i instantiate the DBInit class again (happens only once), and checks for the magic cookie and dies if the cookie is wrong.
1. In the remote server case i am not sure if the client has to check/do anything about the magic cookie again?
2. In the remote server case, do you use any of the data schema information on the clinet side? Like number of columns, name of the columns, length of each column .... for instance when you call the findByCriteria(String[] criteria) thru the remote interface on the Data class, how do you initialize the criteria[] without kowing the number of columns on the server side. Likewise how do you know how many columns in the JTable. Similarly on the client side do you assume the first column in the db is name, second is location ... and so on. Do you have these information in some property file on the clinet side, or do you use getXXX methods onthe remote interface and get these information from the server side?
Arun
[ October 01, 2003: Message edited by: Arun Kumar ]

SCJP (1.4), SCWCD, SCJD
Vlad Rabkin
Ranch Hand

Joined: Jul 07, 2003
Posts: 555
Hi Ulrich
So Andrew's suggest would consist in reading the MagicCookie only once, while Vlad suggests to check the MagicC. each time a client connects to DataSchema by passing the FileName as argument. Thus the work will be done by DataSchema.
Am I right?

Nope. My Data is mutiotion at the moment (I am trying to do it as singleton, but I can't find an elegant solution). Mutition means I am one and only one instance of Data. It will be created only one time. Every RemoteAdapter object will wrap the shared instance of Data (and therefore DataSchema). So, magic cookie will be read only once.
It seems that you have multiple Data objects and Singletone DataSchema.
So, it makes no sense to read everytime header, when you create Data. What Andrew suggest and what am also suggestiong to you (for your design) to read header in inside your DataSchema class. This way it will be read only once. To let your Singletone dataSchema know which file to read you need getInstance(String fileName), insteand of getInstance().
I like your solution, but with these remarks (above).
I had problems concerning catching IOExceptions, I can avoid them by creating a static{}-block catching IOException and throwing RuntimeException.

It has nothing to do with singletone. Your DataSchema.getInstance() can be declared to throw IOException. You Data class C-tor actually too. We are restructed not to thow IOExcptions in all method of DB Interface, but not in Data C-tor.
But in your case, the problem is that you don't want to have direct access from Data to the File but only get the Filename through arguments. is that right? If yes, why don't you want to have direct access from Data-Class?

Nope. I do have direct access to the File from Data. My DataSchema class takes take RAF and fileName as arguments. I feel DataSchema using C-tor (it is at the moment not a Singletone), but I still have only one shared instance Data and thefore DataSchema for all connections (Mutition).
My problem is :
In my design I have following:

So DBAdapter and Data are so-called mutition.
I want to have following:

The mutition is now impossible:
The only way to do it DBConnectionFactoryImpl would have to create first Data instance and give as an arugument in C-tor of DBAdapter. It would breatch the concept of Adapter Pattern.
So, the best way to do it is make Data class as a Singletone.
There are two types of Singleton : active and lazy.
The active Singletone is created at the start of application (because it is initiated statically). At the moment when the application starts I don't know the fileName. So I can't use it.
The only way to do it as a lazy Singletone. (It will be created upon first invocation of its getInstance(String fileName) method.
But, what I hate is that all IO problems will be realized too late.
Example:
Your server GUI has choisen the file with wrong format, or the file is corrupted. You start the server, but my Server factory doesn't create data object. It just waits for client requests. So you think that everything is Ok. After an hour the first client invokes create() method on the ConnectionFactory and it creates an Instance of RemoteAdapter(which wraps local adapter). The C-tor of DBAdapter invokes then Data.getInstance(fileName) and then your servers tries at first time to open a file connection and you get notified that something is wrong.
So, either I use mutition pattern, but I have then also a single shared DBAdapter, or I use Singletone Data and have the problem described above.
Both solution s..k
Best,
Vlad
Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi Vlad,
now I understand your problem. I feel embarassed that I can't help you to pay you back the big help you have done all time to me
But to repeat my own sentence, I'm still a poor beginner...
Good luck
Ulrich
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11460
    
  94

Hi Vlad,
As I understand it, your main issue with the lazy instantiation of the singleton is that you do not do the instantiation until a client request comes in.
But why wait till then?
You could have a method that just verifies the data file (checks the magic cookie, reads the schema, and checks that the file length is correct based on the schema). Have the server call this method as soon as it knows the file name. Then you know that the file is valid, and you have already read the schema. When a client connects some time in the future, you will already know you are in a safe condition. The client would not have to call the verification method.
Regards, Andrew
Arun Kumar
Ranch Hand

Joined: Aug 29, 2003
Posts: 67
Can someone please answer my questions in my above post before this thread gets lost
Thankyou
Arun
Vlad Rabkin
Ranch Hand

Joined: Jul 07, 2003
Posts: 555
Hi Andrew,
But why wait till then?
You could have a method that just verifies the data file (checks the magic cookie, reads the schema, and checks that the file length is correct based on the schema). Have the server call this method as soon as it knows the file name.

Good idea. The problem is that my server (DBConnectionFactory) shound't actually work with Data instance, since I have DBAdapter class, the Adapter class must be entry point to the database for the Factory.
What you suggest let's say to add validate() method to Data Class and then also validate() method to the DBAdapter accordinately.
The DBConnection Factory C-tor creates an instance of DBAdapter calles validate() methods and sets DBAdapter instance to null.
Is it what you mean?

Tx,
Vlad
[ October 02, 2003: Message edited by: Vlad Rabkin ]
[ October 02, 2003: Message edited by: Vlad Rabkin ]
Vlad Rabkin
Ranch Hand

Joined: Jul 07, 2003
Posts: 555
Hi Arun,
In the remote server case i am not sure if the client has to check/do anything about the magic cookie again?

Nope.
In the remote server case, do you use any of the data schema information on the clinet side? Like number of columns, name of the columns, length of each column

Yeap. I use all the information described by on the client to make changes in database structure transparent for the client.
Best,
Vlad
John Canavan
Greenhorn

Joined: Aug 17, 2003
Posts: 29
Hi Ulrich,
Just a quick question (well questions!!!) on your original post in this thread. Above you posted the following code:

I’m just wondering why you are synchronizing on reservedRecords. Is it because you do not lock the record before you read it i.e. you use the above mechanism rather that a “lock – read – unlock” mechanism? Also, if you don’t lock the record do you not check that the record is not in reservedRecords (another thread may be updating it)? In my read method for example I do not have any synchronization (see below) – before I call read (or indeed update, delete etc) I will lock the record in the adapter class (by adding its record number to reservedRecords) and then perform the read.

Basically I’m wondering why you synchronize on reservedRecords? I presume you are probably using the same general mechanism as I am – locking using a static WeakHashMap in Data.java and then giving each client their own instance of Data.java.
I pretty new to multi-threading programming so my question may be off the mark!
John
Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi John,
I�m just wondering why you are synchronizing on reservedRecords. Is it because you do not lock the record before you read it i.e. you use the above mechanism rather that a �lock � read � unlock� mechanism? Also, if you don�t lock the record do you not check that the record is not in reservedRecords (another thread may be updating it)?


No, for reading I just use the mutex to ensure that no other thread owns the lock for reservedRecords. For updating, of course I use the mechanism lock - update - unlock and in this methods I will check if reservedRecords allready contains the concerning Record.
For example, my lock-method looks like:

But for reading I don't need to check if reservedRecords contains the Record. I think for reading, the only danger consists when another thread at the same time is writing.
For updating I go this way:
locking(entering the synchronized block, checking, locking, Exiting the synchr. block)
updating(entering the synchronized block, checking, updating, Exiting the synchr. block)
unlocking (entering the synchronized block, checking, unlocking, Exiting the synchr. block)
Because the writing will be done within a private method which will only be called within synchronized blocks, there is no danger. The only problem consists in this possible situation:
Client 1 with Thread A locks Record1, leaves the synchronized block.
Now, Client 2 with Thread B gains the (synchronized) lock of reservedRecords, reads Record 1 and leaves the synchronized block.
After that, Client 1 with Thread A gains the (synchronized) lock of reservedRecords, updates Record 1, calls write(Record1) and leaves the synchronized block.
There is no danger that physically at the db-file there will be a conflict between the two threads, but Clien 1 might get a result which shortly has been changed by another Client. But because, if Client 1 now wants to do some stuff with Record 1 like booking, you can check the content of the Record by reading it once more before updating.
Regards
Ulrich
[ October 02, 2003: Message edited by: Ulrich Heeger ]
Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi Vlad, hi Arun,
hi Vlad,
I don't understand why you don't have direct access from your Server to DataSchema. Why do you want to restrain its access faculty to Data-Class?
Or are the clients reduced to the DBAccess-methods? I mean, the client can only have access to Data-Class through DBAccess? Like:

Because I thought that it would be like:


I suppose the second schema is the right one, because you posted to Arun:
quote:
--------------------------------------------------------------------------------
In the remote server case, do you use any of the data schema information on the clinet side? Like number of columns, name of the columns, length of each column
--------------------------------------------------------------------------------
Yeap. I use all the information described by on the client to make changes in database structure transparent for the client.

That means that you have a getDataSchema(Instance)() or something similar at the client side, n'est-ce pas? But why don't you use something similar for your problem mentioned above. You could invoke getDataSchema(Instance)() from your server, or do I miss the point?
Greetings
Ulrich
[ October 02, 2003: Message edited by: Ulrich Heeger ]
[ October 02, 2003: Message edited by: Ulrich Heeger ]
Vlad Rabkin
Ranch Hand

Joined: Jul 07, 2003
Posts: 555
Hi Ulrich,
I don't understand why you don't have direct access from your Server to DataSchema.

I am not I understand your question.
I have an DBAdapter which is my entry point to the database access for the GUI Client.
DBAdapter is not a singletone. It has, of course, getSchema() method (which return SchemaModel to the client. DBAdapter to get the Schema calls Data.getSchema(). Do you mean I could directly call invoke:
return DataSchema.getInstance(fileName) inside DBAdapter?
Vlad
Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi Vlad,
sorry for confusion.
Do you mean I could directly call invoke:
return DataSchema.getInstance(fileName) inside DBAdapter?

Yes, why not?
But for my own comprehension can I repeat my question?
Your request fortifies my assumption that the second schema is the right one:

Is that right?
Greetings
Ulrich
Vlad Rabkin
Ranch Hand

Joined: Jul 07, 2003
Posts: 555
Hi Ulrich,
It depends what you mean by client (GUI as Client or Server as client).
In my case it is not GUI client, it is Adapter.
Client->Adapter->Data(implements DBAccess)
Vlad
Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi,
Andrew wrote:

You could have a method that just verifies the data file (checks the magic cookie, reads the schema, and checks that the file length is correct based on the schema).

Concerning this point, I have some questions.
In DataSchema, I have following method:

I think this the direction what Andrew means with:
"and checks that the file length is correct based on the schema", or am I mistaken?
Here my questions:
1. Concerning the expression: "allRecLen % getRecordLength()) != 0", I suppose you Gurus will critize it because it isn't very elegant, or?
2. "throw new IOException("the db-file might be corrupted")"
When the length of that part of the file which is reserved for storing the Records can't be divided through the number of Records, I have to suppose that the db-file is corrupted and in that case the IOException is the appropriate Exception.
Is that OK?
Thanks a lot in advance
Ulrich
Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi Vlad,
sorry, my schema was of course a little bit simplified, but you have anwered my question.
Because the DataSchema IMO isn't directly integrated in this hierarchy:
Client->Adapter->Data(implements DBAccess)
there won't be a problem to make a call from your Adapter-Class to DataSchema, don't you think so?
Regards
Ulrich
Vlad Rabkin
Ranch Hand

Joined: Jul 07, 2003
Posts: 555
Hi Ulrich,
there won't be a problem to make a call from your Adapter-Class to DataSchema, don't you think so?

It is not a problem, but I don't like it. I call my approach "single entry points":
For the GUI client there is one entry point:
DBConnection Factory, which returns Adapter object per (one per client).
So, the clients communicates then only with Adapter.
Adapter then communicates only with Data class. To get DataSchema it uses Data.getSchema() method.
This approach allowes extrem flexibility. You can do your Schema as singletone or not, you don't have to change your call from Adapter to get the Schema.
What you suggest is Ok, but it makes then your Adapter class dependable from internal implementation of Data access (Data, DataSchema).
Best,
Vlad
John Canavan
Greenhorn

Joined: Aug 17, 2003
Posts: 29
Hello Ulrich,
I understand the approach you are taking now, thanks for clearing that up!
John
Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi Vlad,
we can't get all perfectly
Greetings
Ulrich
[ October 02, 2003: Message edited by: Ulrich Heeger ]
Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi everyone,
because nobody has answered my question above, I will post it once more, benefiting from this occasion to ask one more question.
Here my request:
---------------------------------------------------------------------------
Hi,
Andrew wrote above:

I think this the direction what Andrew means with:
"and checks that the file length is correct based on the schema", or am I mistaken?
Here my questions:
1. Concerning the expression: "allRecLen % getRecordLength()) != 0", I suppose you Gurus will critize it because it isn't very elegant, or?
2. "throw new IOException("the db-file might be corrupted")"
When the length of that part of the file which is reserved for storing the Records can't be divided through the number of Records, I have to suppose that the db-file is corrupted and in that case the IOException is the appropriate Exception.
Is that OK?
Thanks a lot in advance
Ulrich
---------------------------------------------------------------------------
And here my second question:
In NX: some questions concerning find-method, we discussed the validation of the arguments of findcriteria.
I will now reduce the validation of the search-criteria to the control of the length of each String:

Here my question:
1. Do you think the IllegalArgumentException is appropriate?
Thanks a lot in advance,
Greetings
Ulrich
[ October 03, 2003: Message edited by: Ulrich Heeger ]
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11460
    
  94

Hi Vlad,
Sorry for being away for so long, I was concentrating on the SCBCD exam.
Anyway, back to your post 2 days ago...
my server (DBConnectionFactory) shound't actually work with Data instance, since I have DBAdapter class, the Adapter class must be entry point to the database for the Factory

I just want to check that the adapter class is only necessary for the factory / server. Or, to put it another way, the Data class does provide all the functionality required by the interface Sun provided.
Whether you use the adapter class in your local connection is unimportant. What is important is that if someone decided to create their own server for your Data class, they can rely on your Data class meeting all the requirements of the interface provided by Sun.
So are you OK? Or have you delegated some of Data's functionality to the adapter class?
[to Andrew] Is it what you mean?


Yep, that is pretty much what I was meaning. Although I am not sure why you are setting your instance of db to null - it is about to go out of scope anyway. In fact, since you don't really use db for anything in that method, you could reduce it to:


Personally I would have the invariant() method do a little more than just check the cookie. As I have mentioned before, I would also read the schema and verify file length. There are a few other minor things that could be done as well, depending on whether people are reading directly from the file or caching the records. In which case it probably shouldn't be called invariant but something more like "configure()" or "initialise". Of course you would need to document that this method must be called before the Data class can be used, and you would probably want all your methods of Data class to verify that it has been run and run it themselves if it hasn't been run.
Regards, Andrew
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11460
    
  94

Hi Ulrich,

I think this the direction what Andrew means with:
"and checks that the file length is correct based on the schema", or am I mistaken?

That is what I meant.
Here my questions:

Ooops, didn't realise that the question above wasn't a question
1. Concerning the expression: "allRecLen % getRecordLength()) != 0", I suppose you Gurus will critize it because it isn't very elegant, or?

I think that this is perfect. It is simple to read, and does exactly what you want.
2. "throw new IOException("the db-file might be corrupted")"
When the length of that part of the file which is reserved for storing the Records can't be divided through the number of Records, I have to suppose that the db-file is corrupted and in that case the IOException is the appropriate Exception.

Yep, the db-file would have to be corrupt in that case.
As for the IOException - what are you going to do once you know that the database is corrupt? This could be a good location to throw a RuntimeException (or a subclass), since this is probably fatal.
And here my second question:

1 + 1 + 1 + 1 = 2 ?
1. Do you think the IllegalArgumentException is appropriate?

Very appropriate.
In the future, if you wanted to you could then subclass IllegalArgumentException to have separate exceptions for field length exceptions, content exceptions .... So using this exception will work well in the future as well.
Regards, Andrew
Vlad Rabkin
Ranch Hand

Joined: Jul 07, 2003
Posts: 555
Hi Andrew,
I just want to check that the adapter class is only necessary for the factory / server. Or, to put it another way, the Data class does provide all the functionality required by the interface Sun provided.

Adapter is needed to:
1) To provide new functionalility like getSchema
2) To change adapt signuture of method (Throwing DatabaseCheckedExeption in case of IOException instead of RuntimeException (No checked exception was defined in DB a standard DB interface from Sun)
3) To change functionality of find (instead of startwith search-> exact search
4) Instead of String[]-> RecordModel
So the client has no clue about DB interface and its implementation Data. It works only with DBAdapter interface.
Personally I would have the invariant() method do a little more than just check the cookie

Of course. The magic cookie and intergrity is checked in C-tor of Data anyway. I actually I don't need neither invariant() nor init() methods.
It is Ok only do create DBadapter instance:

I use database caching, that is why all the job has to be anyway done in C-tor of Data.
Ok, I think it is clear. I will do Data a lazy singletone (Data.getInstance(String fileName);
And will create an instance of DBAdapter in C-tor of factory to be able to see problems at the start of the server.
Many Tx,
Vlad
Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi Andrew,
1 + 1 + 1 + 1 = 2 ?


I haven't drunk too much Fosters, I swear
Thank you a thousand times for your help
Ulrich
Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi Vlad,
I wrote:
we can't get all perfectly

Sorry, I regret my stupid comment
Greetings
Ulrich
Ulrich Heeger
Ranch Hand

Joined: Jun 06, 2003
Posts: 266
Hi Vlad,
I have reread this thread for better comprehension.
1.At google, I have searched the mutition but I haven't found anything.
You wrote:

I still have only one shared instance Data and thefore DataSchema for all connections (Mutition).

What is the difference between Mutition and Singleton?
2. Because you have only one instance of Data, you have accordingly only one instance of DataSchema?

3.Concerning your newer approach:
You wrote:

I will do Data a lazy singletone (Data.getInstance(String fileName);
And will create an instance of DBAdapter in C-tor of factory to be able to see problems at the start of the server.

Does it mean that now you will create one DBAdapter anyway at the start-up of the server? So through the constructor of DBAdapter the Data-Singleton will be created also, the integrity of the db-file can now be checked.
Have you also changed the create-method you have posted above?

I mean, because you have now allready checked the file, you don't need anymore to give it as argument to DBAdapter-constructor? I mean, have you created a second no-arg constructor?
Thanx for your help
Ulrich
Vlad Rabkin
Ranch Hand

Joined: Jul 07, 2003
Posts: 555
Hi Ulrich,
Sorry, I regret my stupid comment

It wasn't stupid comment. It was 100% true!
What is the difference between Mutition and Singleton?

Mutition is 100% standard class with public C-trs, but you create an of it it only one. All instances of other classes will use the instance. Of course you must be carefull to make sure you really created that instance only once.
Example:
Mutition:
Data data = new Data("db.db");
DataAdapter adapter1 = new DataAdapter(data);
DataAdapter adapter2 = new DataAdapter(data);
Singletone:
DataAdapter adapter1 = new DataAdapter("db.db");
DataAdapter adapter2 = new DataAdapter("db.db");
Whereby C-r of DataAdapter looks like this:
this.data = Data.getInstance("db.db");
As you can see I can hide Data class from caller of DataAdapter with the help of Singletone, what I can't do with Mutition.
I personally don't like Singletones. I am afraid now to list the reasons, because will lead to a very very long discussion fight
My rule is if I can avoid using a singletone - I do avoid it.
Since I want to have multiple instances of DataAdapter I can't avoid singletone
Because you have only one instance of Data, you have accordingly only one instance of DataSchema?

Yeap. That's why I don't see any reason to make DataSchema as a singletone if you have a single Data object: it makes just no sense.
Does it mean that now you will create one DBAdapter anyway at the start-up of the server? So through the constructor of DBAdapter the Data-Singleton will be created also, the integrity of the db-file can now be checked.

Yeap. I don't like it, but it seems to be a satisfied compromise. The most elegant way would be creating a pool of objects, but I don't wanna even go there. It will get then too complicated.
Have you also changed the create-method you have posted above?

It was the new one.
I mean, have you created a second no-arg constructor?

One of the reasons I don't like singletones.
Nope, I will provide only one method: getInstance(String name);
I will have to check
1) inside the method if an instance already exists (lazy singletone)
2) Additionally I will check if the name of the file of the existed instance is the same as in parameter. If not I will thro RuntimeExcepiton.
Actually I wanted first to ask Andrew if I could do it somehow better, but I don't think that there are really any better solutions.
I don't want to provide two getInstance() method. What should do if a user first called getInstance()? There is no any instance of Data yet and the name of file is uknown...
Moreover having it the have I 've done, will allow me to modify the design without affecting caller of DBAdapter: E.g. If I decide to allow multiple instances of Data instead of having it as singletone...
Best,
Vlad
[ October 04, 2003: Message edited by: Vlad Rabkin ]
[ October 04, 2003: Message edited by: Vlad Rabkin ]
[ October 04, 2003: Message edited by: Vlad Rabkin ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Mutition is 100% standard class with public C-trs, but you create an of it it only one. All instances of other classes will use the instance. Of course you must be carefull to make sure you really created that instance only once.
Mmmm, I don't think so, but I can't find a good online linke for multiton right now to corroborate. However when I use "multiton" I mean something that may indeed have more than one instance in the JVM, but control over whether an how new instances are created is restricted according to some rules. Which means it won't have public constructors, because that would enable anyone to create an instance. Instead it will have a static factory method or a separate factory class which controls when & how instances are created. As an example, let's say I want to ensure that for any given DB file, there's only one Data instance in the JVM - however (for future enhancements) there may be more than one Data file, and thus more than one DB instance. But I want to make sure no two Data instances ever share the same file. So, I enforce this with the Data class:

Make sense? Does anyone else have a significantly different understanding of "multiton", or a link to a good reference page?
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11460
    
  94

Hi Iacomus,
I agree with your definition of Multiton. Unfortunately the only references I could find were extremely light descriptions in C++ and Ruby. Had they been more descriptive, or in Java, I would have posted links.
Originally I used a Multiton for my LockManager class, and like you, I had an internal map which tracked which instance of the LockManager was assigned to any given database name. Later though I just refactored my LockManager out of existance
Regards, Andrew
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: NX: RandomAccessFile / Singleton DataSchema