Re: getAllReferencingObjects(Object object) request
Hi Christiaan, On Jun 20, 2007, at 1:19 AM, Christiaan des Bouvrie wrote: Hi Craig, "We actually have changed the specification in this regard, so that if you are using a mapping in which a single database artifact (e.g. primary key, foreign key) is used to describe two or more concepts, the deletion of an instance causes the cleanup of other instances that refer to that deleted instance." Can you tell me where this is described in the spec? It's in 15.3. The JDO 2.1 update is currently: If two relationships (one on each side of an association) are mapped to the same column, the field on only one side of the association needs to be explicitly mapped. The field on the other side of the relationship can be mapped by using the mapped-by attribute identifying the field on the side that defines the mapping. Regardless of which side changes the relationship, flush (whether done as part of commit or explicitly by the user) will modify the datastore to reflect the change and will update the memory model for consistency. There is no further behavior implied by having both sides of the relationship map to the same database column(s). In particular, making a change to one side of the relationship does not imply any runtime behavior by the JDO implementation to change the other side of the relationship in memory prior to flush, and there is no requirement to load fields affected by the change if they are not already loaded. This implies that if the RetainValues flag or DetachAllOnCommit is set to true, and the relationship field is loaded, then the implementation will change the field on the other side so it is visible after transaction completion. Conflicting changes to relationships cause a JDOUserException to be thrown at flush time. Conflicting changes include: adding a related instance with a single-valued mapped-by relationship field to more than one one-to-many collection relationship setting both sides of a one-to-one relationship such that they do not refer to each other Are you referring to the mapped-by attribute in JDO2 to deal with updating of references Yes. or the delete/update action for foreign keys? No, actions are a separate concern. These are intended to reflect the underlying database settings for the foreign keys. For the latter, the jdo implementation I am using has the following comment on this: null the columns of this foreign key. Some databases do not support this action.> Unfortunately, the database I am using doesn't support this. The update in JDO 2.1 will cover the case of delete even if the delete action is not supported by the database itself. "Do all of your examples use delete as the cause of the issue?" Most of them, but it could also be handy to maintain integrity when updating one-one relationships and one-to-many. This is also addressed in 15.3. In JDO 2.1 we're looking to make it more clear what the behavior is for update and delete of instances that are related with the mappedBy relationships. Btw, with jdo1 the recommendation was to manually maintain all references, which is fine by me, since you have that to do that in plain java as well. I just thought that getAllReferencingObjects() could be a handy method in doing this and would not only save the developer time in writing this code himself it would also be less maintenance sensitive. Manually changing the relationships to reflect the change in the database seems like the wrong approach, since changing relationships requires instantiation of relationships simply for this purpose. And this is doing work for no real purpose since the database is already being updated. "Would it be better to describe the delete semantics instead of having the user worry about it?" Not sure what you mean with this. Who is the user in this case? I meant the application developer. As I see it there is no user worrying about this, just the person who is designing/implementing the persistent objects. Right. With the available solutions he either has to maintain the update semantics in the metadata or he has to maintain his own implementation of getAllReferencingObjects()? Yes, and I think we're talking about making the metadata the better place to specify what happens on relationship updates. Regards, Craig Regards, Christiaan Craig Russell Architect, Sun Java Enterprise System http://java.sun.com/products/jdo 408 276-5638 mailto:[EMAIL PROTECTED] P.S. A good JDO? O, Gasp! smime.p7s Description: S/MIME cryptographic signature
Re: getAllReferencingObjects(Object object) request
Hi Craig, "We actually have changed the specification in this regard, so that if you are using a mapping in which a single database artifact (e.g. primary key, foreign key) is used to describe two or more concepts, the deletion of an instance causes the cleanup of other instances that refer to that deleted instance." Can you tell me where this is described in the spec? Are you referring to the mapped-by attribute in JDO2 to deal with updating of references or the delete/update action for foreign keys? For the latter, the jdo implementation I am using has the following comment on this: Unfortunately, the database I am using doesn't support this. "Do all of your examples use delete as the cause of the issue?" Most of them, but it could also be handy to maintain integrity when updating one-one relationships and one-to-many. Btw, with jdo1 the recommendation was to manually maintain all references, which is fine by me, since you have that to do that in plain java as well. I just thought that getAllReferencingObjects() could be a handy method in doing this and would not only save the developer time in writing this code himself it would also be less maintenance sensitive. "Would it be better to describe the delete semantics instead of having the user worry about it?" Not sure what you mean with this. Who is the user in this case? As I see it there is no user worrying about this, just the person who is designing/implementing the persistent objects. With the available solutions he either has to maintain the update semantics in the metadata or he has to maintain his own implementation of getAllReferencingObjects()? Regards, Christiaan
Re: getAllReferencingObjects(Object object) request
Hi Chistiaan, On Jun 18, 2007, at 1:30 AM, Christiaan des Bouvrie wrote: Hi David and Matthew, Thanks for the response. Regarding the design issues, I agree that it is a Java problem. In jdo this problem becomes more evident. If I want to delete an object in java, I need to set all references to null. In JDO I need to set all references to null and actually delete the object. We actually have changed the specification in this regard, so that if you are using a mapping in which a single database artifact (e.g. primary key, foreign key) is used to describe two or more concepts, the deletion of an instance causes the cleanup of other instances that refer to that deleted instance. That is, if you delete an Employee, the collection of employees in the Department, the collection of Employees in the Projects, and the Insurance instances all get either deleted (if dependent) or their collections or references are removed. In the case of object databases in which there are multiple artifacts, then the issue is a bit more tricky in that there is no standard way to describe the relationship that should be deleted. But such metadata could be added to assist in this regard. I noticed that a lot of beginners with JDO assume that when deleting the objects the other part, setting references to null, is done automatically, which is not the case. In any case it is something which needs to be dealt with and it is now left to the developer to do it. What I do now is that for each object I determine which objects are referencing it. This usually comes down to executing queries where I check whether a certain attribute is or contains the object. I figured with all the available jdo meta data this could be something that can be done by the framework? Moreover, this code easily breaks on refactoring. That would also be nicely solved if the jdo metadata is used. Do all of your examples use delete as the cause of the issue? Would it be better to describe the delete semantics instead of having the user worry about it? Craig Regarding the performance, I am not sure what makes this solution slower than the current solution, doing it yourself, that is, if my assumption that it can be done with the jdo metadata is correct. Collecting the metadata is probably a fraction of the actual time to delete the object in the datastore. So the performance decrease will be caused by querying attributes which could possibly contain the object according to the metadata, but which you as a developer know is not the case. I would say if performance becomes a problem in that case you can always go back by doing it yourself, or provide some extra metdata to getAllReferencingObjects so these classes can be skipped. This is also the approach I have currently. I first use my generic delete algorithm to recursively determine what needs to be deleted and what references need to be updated. If I notice or know this will be slow due to a large collection of objects I will switch to a delete-by-query and optimize the number of objects that need to be updated. But again, it is hardly ever considered slow due to the getAllReferencingObjects(), but more due to the actual deleting of large collections of objects using pm.deletePersistentAll(). Kind regards, Christiaan Craig Russell Architect, Sun Java Enterprise System http://java.sun.com/products/jdo 408 276-5638 mailto:[EMAIL PROTECTED] P.S. A good JDO? O, Gasp! smime.p7s Description: S/MIME cryptographic signature
Re: getAllReferencingObjects(Object object) request
Hi David and Matthew, Thanks for the response. Regarding the design issues, I agree that it is a Java problem. In jdo this problem becomes more evident. If I want to delete an object in java, I need to set all references to null. In JDO I need to set all references to null and actually delete the object. I noticed that a lot of beginners with JDO assume that when deleting the objects the other part, setting references to null, is done automatically, which is not the case. In any case it is something which needs to be dealt with and it is now left to the developer to do it. What I do now is that for each object I determine which objects are referencing it. This usually comes down to executing queries where I check whether a certain attribute is or contains the object. I figured with all the available jdo meta data this could be something that can be done by the framework? Moreover, this code easily breaks on refactoring. That would also be nicely solved if the jdo metadata is used. Regarding the performance, I am not sure what makes this solution slower than the current solution, doing it yourself, that is, if my assumption that it can be done with the jdo metadata is correct. Collecting the metadata is probably a fraction of the actual time to delete the object in the datastore. So the performance decrease will be caused by querying attributes which could possibly contain the object according to the metadata, but which you as a developer know is not the case. I would say if performance becomes a problem in that case you can always go back by doing it yourself, or provide some extra metdata to getAllReferencingObjects so these classes can be skipped. This is also the approach I have currently. I first use my generic delete algorithm to recursively determine what needs to be deleted and what references need to be updated. If I notice or know this will be slow due to a large collection of objects I will switch to a delete-by-query and optimize the number of objects that need to be updated. But again, it is hardly ever considered slow due to the getAllReferencingObjects(), but more due to the actual deleting of large collections of objects using pm.deletePersistentAll(). Kind regards, Christiaan
RE: getAllReferencingObjects(Object object) request
I actually discussed this a long time ago with Robin Roos, and we came to the conclusion that this, as David points out, is a Java problem, not so much a JDO one. We considered starting a new JSR dedicated to the concept of bidirectional reference management in Java, but we never filed it. Perhaps this is a good time to pick this idea up again and reconsider. I have a sneaking suspicion that this would be a change way down deep in the guts of Java more than just a new api. -matthew -Original Message- From: David Ezzio [mailto:[EMAIL PROTECTED] Sent: Friday, June 15, 2007 7:03 AM To: [email protected] Subject: Re: getAllReferencingObjects(Object object) request Hi Christiaan, I agree your feature request would be convenient. But I don't see any way to implement it that wouldn't be a design and performance nightmare. Consider first all the design implications. Java, as you know, does not have any such concept. For Java, it is unnecessary, since objects exist as long as another uncollectable object refers to them. This is how Java avoids, as you know, the dangling references of C++. Then consider performance. The JDO implementation very likely has a set of references to uncollected pc objects, but how would it determine that one of these objects refers to the object in question? It would have to reflect on all the fields and see if they have a reference that is compatible with the type of the checked object and in fact refers to it. If I understand your requirement, you have an a graph of objects where you want to make any one of them go away. In Java, you would have to update all objects that refer to the object to be removed. You have to do the same when using JDO. The JDO implementation may give you a vendor feature that might help. Some JDO implementations persistence manager can give you a list of pc objects that they are managing. You could run a query on this set of objects to determine which ones refer to the object that you want to delete. Cheers, David Ezzo Christiaan des Bouvrie wrote: > Dear all, > > > > I would like to make a feature request for a > getAllReferencingObjects(Object object) method, which should return a > set of pc objects which have a reference to the specified pc object. > > > > This would be really convenient for instance when deleting an object to > make sure all references are set to null. In the domain I am working I > have a network of all kinds of objects where each object can be deleted > and thus all other objects have to update their reference. I currently > have a generic delete algorithm which recursively asks all (cascaded > deleted) objects to get their references in order to update them. Of > course, this method would also be quite convenient in unittest to make > sure you have updated everything properly. > > > > Kind regards, > > Christiaan > > > > Notice: This email message, together with any attachments, may contain information of BEA Systems, Inc., its subsidiaries and affiliated entities, that may be confidential, proprietary, copyrighted and/or legally privileged, and is intended solely for the use of the individual or entity named in this message. If you are not the intended recipient, and have received this message in error, please immediately return this by email and then delete it.
Re: getAllReferencingObjects(Object object) request
Hi Christiaan, I agree your feature request would be convenient. But I don't see any way to implement it that wouldn't be a design and performance nightmare. Consider first all the design implications. Java, as you know, does not have any such concept. For Java, it is unnecessary, since objects exist as long as another uncollectable object refers to them. This is how Java avoids, as you know, the dangling references of C++. Then consider performance. The JDO implementation very likely has a set of references to uncollected pc objects, but how would it determine that one of these objects refers to the object in question? It would have to reflect on all the fields and see if they have a reference that is compatible with the type of the checked object and in fact refers to it. If I understand your requirement, you have an a graph of objects where you want to make any one of them go away. In Java, you would have to update all objects that refer to the object to be removed. You have to do the same when using JDO. The JDO implementation may give you a vendor feature that might help. Some JDO implementations persistence manager can give you a list of pc objects that they are managing. You could run a query on this set of objects to determine which ones refer to the object that you want to delete. Cheers, David Ezzo Christiaan des Bouvrie wrote: > Dear all, > > > > I would like to make a feature request for a > getAllReferencingObjects(Object object) method, which should return a > set of pc objects which have a reference to the specified pc object. > > > > This would be really convenient for instance when deleting an object to > make sure all references are set to null. In the domain I am working I > have a network of all kinds of objects where each object can be deleted > and thus all other objects have to update their reference. I currently > have a generic delete algorithm which recursively asks all (cascaded > deleted) objects to get their references in order to update them. Of > course, this method would also be quite convenient in unittest to make > sure you have updated everything properly. > > > > Kind regards, > > Christiaan > > > > Notice: This email message, together with any attachments, may contain information of BEA Systems, Inc., its subsidiaries and affiliated entities, that may be confidential, proprietary, copyrighted and/or legally privileged, and is intended solely for the use of the individual or entity named in this message. If you are not the intended recipient, and have received this message in error, please immediately return this by email and then delete it.
