Sorry John, I forgot to mention this. Take a look at:
http://castor.codehaus.org/long-transact.html
for an explanation about long transactions. In addition to the
implementation of the timestamp interface your objects that take part in
long transactions need to have a 'long timestamp' property. Wit the
jdoSetTimestamp(long) method this value is set by castor and by
jdoGetTimestamp() castor reads the timestamp during update to check if
the object has been modified in the mean time. Another precondition for
this to work is that the object need to be in castor's cache between the
load and update transactions. This means that you have to take care
about your cache settings in mapping file. E.g. if you defined to use
time-limited cache with a timeout of 5min but your update happens 20min
after the load a ObjectModifiedException will be thrown. Same can happen
with count-limited cache if the capacity of the cache is to small. E.g.
your cache capacity is 10 and you load the object to be updated later,
then you load more then 10 other objects of the same class before you
call update on the one loaded first you will also get a
ObjectModifiedException. Having said that a ObjectModifiedException will
also be thrown if you modified the object in the database by hand or if
you try to do load and update with 2 seperate test applications.
Ralf
John Greene schrieb:
Hi Ralf,
Well I got this message...:
org.exolab.castor.jdo.PersistenceException: Nested error:
java.lang.IllegalArgumentException: A master object that involves in a long
transaction must be a TimeStampable!
I then implemented TimeStamable and got this message:
org.exolab.castor.jdo.ObjectModifiedException: Timestamp mismatched!
John
-----Original Message-----
From: Ralf Joachim [mailto:[EMAIL PROTECTED]
Sent: Wednesday, February 01, 2006 07:06 PM
To: [email protected]
Subject: Re: [castor-user] How to implement castor?
Hi John,
the update method is designed for long transaction when object is
detached from the transaction. You can use it as follows:
db.begin();
student = (Student) db.find(100);
db.commit();
student.setFirstName("James");
db.begin();
db.update(student);
db.commit();
This is very usefull if you load an object, display it to the user how
changes some of the properties and then you make these changes persistent.
Hope this helps
Ralf
Castor JDO, committer
John Greene schrieb:
werner,
I am doing an update as follows which works:
db.begin();
student = (Student) db.find(100);
student.setFirstName("James");
db.commit();
But I dont understand why this does not work?
db.begin();
student = (Student) db.find(100);
student.setFirstName("James");
db.update(student);
db.commit();
and gives a run time error message:
org.exolab.castor.jdo.DuplicateIdentityException: update object which is
already in the transaction
-----Original Message-----
From: Werner Guttmann [mailto:[EMAIL PROTECTED]
Sent: Sunday, January 29, 2006 06:31 AM
To: [email protected]
Subject: Re: [castor-user] How to implement castor?
John,
I think whilst your approach is very good and clean one, there's a
couple of things to note.
JDOManager.loadConfiguration() is a static method, and should be called
once only to load a configuration with Castor JDO. A call to
loadConfiguration() will instruct Castor JDO to take a JDO configuration
file and load it, hence making all the information provided in that file
available to Castor JDO for further use.
JDOManager.createInstance() will create a JDOManager instance for a
given database (as specified through the parameter passed to the call).
There's no need to create this object instance more than once, as it is
quite an expensive operation as well, and hence should not be performed
on every method call of your DAO.
In other words, consider moving the calls to
JDOManager.loadConfiguration() and JDOManager.createInstance() to e.g.
the constructor of your DAO (at the minimum).
Once you've obtained your JDOManager instance through a call to
JDOManager.createInstance(), use this JDOManager instance to create
Database instances as you need them, use them, and discard them as well.
Following your example below, let me explain what I actually mean. Let's
add a load method to your DAO (one I am actually missing, as you won't
for example be able to delete an object without loading it previously).
public void load(Object identity) {
try {
Database db = _jdo.getDatabase();
db.begin();
db.load (SomeClass.class, identity);
db.commit();
}
catch (PersistenceException e) {
db.rollback();
// some other error handling, such as e.g. logging
}
finally {
db.close();
}
}
In the above load() method, the assumption is that your DAO has an
instance variable _jdo of type JDOManager (which has been assigned the
JDOManager instance as returned by JDOManager.createInstance()). We
first call getDatabase() to obtain a Database instance, then deal with
transaction demarcation and finally go about eventually loading the
object in question, as specified by the identity object passed to the
load method.
Please have a close look at the exception handling, incl. the calls to
Database.rollback() in the catch clause and Database.close() in the
finally clause. These two calls are very important as they are required
to guarantee data consistency (through properly committing/rolling back
your units of work) and resource cleanup.
I hope that gets you a bit further, and don't hesitate to ask any
further questions related to what has just been said.
Werner
John Greene wrote:
Hi Werner,
First thanks for the indications. I was googling the Internet since last
night and saw many different implementations of Castor that got me really
confused.
Okay.... I have created the following DAO class:
public class CastorDAO {
private static String _databaseName = "mydb";
private static String _databaseConfiguration = "jdo-config.xml";
protected static Database _db;
/** Creates a new instance of CastorDAO */
public CastorDAO() {
}
public void loadDatabase() {
try {
JDOManager.loadConfiguration( _databaseConfiguration);
} catch (MappingException e) {
System.out.println(e);
}
}
public void open() {
try {
_db = JDOManager.createInstance(_databaseName).getDatabase();
} catch (PersistenceException e) {
System.out.println(e);
} catch (MappingException e) {
System.out.println(e);
}
}
public void create( Object object ) {
try {
_db.begin();
_db.create( object );
_db.commit();
} catch (PersistenceException e) {
System.out.println(e);
}
}
public void remove( Object object ) {
try {
_db.begin();
_db.remove( object );
_db.commit();
} catch (PersistenceException e) {
System.out.println(e);
}
}
public void update( Object object ) {
try {
_db.begin();
_db.update( object );
_db.commit();
} catch (PersistenceException e) {
System.out.println(e);
}
}
}
To implement adding a NEW STUDENT I would do....
CastorDAO dao = new CastorDAO();
dao.loadConfiguration;
dao.create(student);
Question:
dao.loadConfiguration; ----loads the configuration file,
there is a method to close a database instance connection, however is
there
a method to unload/close the database or test for presence; otherwise I'll
get a runtime Warning message indicating that the database has already
been
loaded?
Thanks
John.
-----Original Message-----
From: Werner Guttmann [mailto:[EMAIL PROTECTED]
Sent: Saturday, January 28, 2006 06:04 PM
To: [email protected]
Subject: Re: [castor-user] How to implement castor?
John,
please see in line ....
John Greene wrote:
I am unclear about how to go about implementing persistence using castor
in
my project. I have created my jdo-config.xml and mapping.xml files, made
a
t
est connection and everything works just fine.
But now I want to implement for a project having many classes that need
pers
istence and I am a bit confused as how to go about it.
Here is an example......:
I have a Java object called "Student" that is mapped to an MySQL
database.
public class Student {
private int _studentID;
private String _firstName;
private String _lastName;
private String _groups;
/** Creates a new instance of Student */
public Student() {
setStudentID(0);
setFirstName("");
setLastName("");
setGroups("");
}
public Student( int studentID, String firstName, String lastName,
String
group ) {
setStudentID(studentID);
setFirstName(firstName);
setLastName(lastName);
setGroups(group);
}
public int getStudentID() {
return _studentID;
}
public void setStudentID(int studentID) {
this._studentID = studentID;
}
public String getFirstName() {
return _firstName;
}
public void setFirstName(String firstName) {
this._firstName = firstName;
}
public String getLastName() {
return _lastName;
}
public void setLastName(String lastName) {
this._lastName = lastName;
}
public String getGroups() {
return _groups;
}
public void setGroups(String groups) {
this._groups = groups;
}
}
1st Problem:
Should this class implement the Persistence class? ...for example:
public class Student implements Persistence {
Not necessarily,
Not necessarily, unless you need the functionality the Persistence
interface offers, like the callback functions. If not, there's no need
to implement any interfaces to be able to persist your Student class
(and others) with Castor JDO.
2nd Problem:
I think that the create, update, remove student methods should be part of
th
e Student class.
In my view, that's not necessarily a good idea. Personally, I prefer to
see my entities (like e.g the Student class) as a POJO, a plain old Java
object that simply has a well-defined state at any time (through the
property values attached to a Student instance). Given this approach,
I'd rather prefer to have a DAO object that offers persistence-related
functionality for a particular entity, and hence provides methods for
the CRUD operations and more (if required).
Do I therefore need to include code to load the jdo-cong.xml
configuration
f
ile inside of Student?
JDOManager.loadConfiguration("jdo-config.xml");
I tried this and got a Warning message for each new instance of Student,
ind
icating that the database has already been loaded.
How can I test if the database has been loaded already?
3rd Problem
My project has numerous classes, each needing mapping to the MySQL
database.
What would be the best way to implement this?
Just define mappings for all your classes, carefully think about how to
relate those objects to each-other, and use your DAOs to load, update,
remove, etc your objects (well, object graphs, to be more precise) with
the help of Castor JDO.
Thanks in advance
-------------------------------------------------
If you wish to unsubscribe from this list, please
send an empty message to the following address:
[EMAIL PROTECTED]
-------------------------------------------------
-------------------------------------------------
If you wish to unsubscribe from this list, please
send an empty message to the following address:
[EMAIL PROTECTED]
-------------------------------------------------
-------------------------------------------------
If you wish to unsubscribe from this list, please
send an empty message to the following address:
[EMAIL PROTECTED]
-------------------------------------------------
-------------------------------------------------
If you wish to unsubscribe from this list, please
send an empty message to the following address:
[EMAIL PROTECTED]
-------------------------------------------------
-------------------------------------------------
If you wish to unsubscribe from this list, please
send an empty message to the following address:
[EMAIL PROTECTED]
-------------------------------------------------
-------------------------------------------------
If you wish to unsubscribe from this list, please
send an empty message to the following address:
[EMAIL PROTECTED]
-------------------------------------------------
-------------------------------------------------
If you wish to unsubscribe from this list, please
send an empty message to the following address:
[EMAIL PROTECTED]
-------------------------------------------------
-------------------------------------------------
If you wish to unsubscribe from this list, please
send an empty message to the following address:
[EMAIL PROTECTED]
-------------------------------------------------