Ok, I think I might be able to clear up a few things here.
Quote:
First, since the objects are remoted to Javascript, they cannot be lazy initialized. So my first ideia was to disable all lazy loading, however there are certain instances where I want to load an object without it's children (such as getting a list of all Surveys). So I left lazy loading on (in the mapping configuration), and when I want to load an object with all it's children, I simply walk the tree to force initialization of all elements. But is there a way to do this automatically in Hibernate? Or can we disable lazy loading in a given Hibernate query for a given mapping, overriding the mapping default?
I think you can use the FETCH keyword in your Hibernate queries to force initialization of lazy collections. So, for example, it should be possible to do the following...
Code:
from Cat as cat
inner join fetch cat.mate
If you want to initialize all of the objects lazy associations, I believe you can use...
Code:
from Document fetch all properties
Please note that the above queries are taken directly from the Hibernate docs.
Quote:
Second, and most important, is the issue of object changes and DB updates, particularly with regards to orphans. If the tree objects were not remoted, I could use mappings with cascade="all-delete-orphans", and then have Hibernate's collections handle the updating of new elements and deletion of orphans. But that is not a possibility.
So one solution was to keep the old version of the survey (the root object) in the business tier, and whenever a new version of that object is requested to be saved, the old object is deleted by Hibernate, and a new one is created (effectively making each object tree immutable in the DB). This works since there are no references between surveys. It's not the most efficient but it is sufficient for the nature of the application.
If a more fine grained control is necessary (for example, because of performance reasons, or because references between survey trees would be necessary), what alternatives would there be? Perhaps using update() on the root objects with mappings with cascade="all", and then having the client maintain orphan lists? Can Hibernate help in any other way? Is version/timestamp useful here? (I have to say I haven't yet quite understood the uses for version/timestamp)
I'm gonna guess that your real problem here is the way you're implementing equals and/or hashcode. My experience with serializing Hibernate entities to a view has only been in the context of Jboss Seam, however... I've not had some of the difficulties you're describing. If my understanding is correct, Hibernate only knows that two objects are the same on two conditions. One is, if the session that initially fetched that object is still open. Two is, if the equals/hash-code methods tell Hibernate that the objects are equivalent.
However, in the case of remoting, I believe that even if the session were to remain open, you'd still end up with Hibernate being unable to tell that the objects were the same unless you had a good equals/hash-code implementation.
Quote:
Hi,
I have nearly the same problem, although my client is written in Flex. To initialize the children objects, I just call the initialize method.
However, this can't be the right solution for me because the relation between parents and children is of type many-to-many. So, loading an object could lead to loading the whole database.
I arrived to the conclusion that ORM + remote services is not completely possible with Hibernate (and probably with any such tool).
Have you looked into EJB3 using Hibernate as your implementation? The reason I ask is because it seems well suited to trying to combine remote services + ORM. However, I think you may have some confusion as to exactly what you're trying to accomplish. The lazy/eager fetching issue isn't native to remote applications at all. Any time you fetch data now, and access it later you can have the issue you're describing.
Quote:
In my case (an application that manages meetings for persons, each person being related to several meetings and each meeting with several persons), The Hibernate version (without remote services) allows me to have only one DAO (for to get the list of persons). If I want to know the meetings related to one person, I can just ask this person. I can then select one of the meetings and ask this object for the other participants. Still no DAO.
In the remote version, this is not possible. When a remote client asks for the list of persons, I simply cannot load each person with the list of meetings, not even the list of meetings ids. So I need a meetingDAO that can return the list of meeting corresponding to a person Id to the remote service.
Sounds like there should be a way to do this without requiring the creation of a MeetingDAO (even though I'm not sure that's such a bad thing). You have a bi-directional @ManyToMany association between Meeting and Person from what I'm gathering... but why do both sides have to be fetch=FetchType.EAGER. Since it sounds like your remote client _always_ needs the meeting data for people that it has, make Person->Meeting eagerly fetched, and make Meeting->Person lazily fetched. Then, if you're absolutely desperate to actually ask a Meeting for all of the people involved you can invoke a remote method to get this information.
No matter what technology you choose, you can't have your cake and eat it too. If you need all of the information up front, then you have to accept the cost that comes with that. If you need it later, it needn't function any differently than a web application in that it must make a request of the data provider to get the additional info as needed.
Quote:
I know there are some frameworks to lazy load objects through a remote connection, but this is for Java remote client.
And frankly, I do not think automatic lazy loading is a good thing over remote connection. There are too many potential problems.
Then, as suggested above, do it manually.
Quote:
However, you can still use Hibernate to load your objects. You simply can't map the relations, which make ORM a bit less useful!
Huh? You seem to be contradicting yourself. Do you want Hibernate to fetch associations remotely or not?
Quote:
In short, in traditional applications, the domain layer is perpendicular to other layers and is accessible to all of them. It is, in particular, accessible to the presentation layer.
With remote client, this is not possible. At the very best, the domain objects appear to be accessible to the presentation layer, but through serialization. So, no lazy loading is possible. This is not a problem if your presentation layer is local like with JSPs, only remoting the views. You can't have remote clients manipulate domain objects. Only a static representation of these objects (at least with today's tools like Hibernate).
EJB3 with Hibernate as it's implementation allows you to do just that. Furthermore, you can have this exact same problem with JSP's deployed on the same box as your Hibernate domain objects. Yes, there are limitations to using ORM, but I don't believe the ones you're pointing out as specific to remoting are really all that different from the generic problems of an ORM.
Quote:
We just came across a serious limitation in Hibernate especially in a distributed programming environment such as GWT-RPC or SOA.
In our scenario Hibernate is not able to recognize collection objects once they travel over network (serialized). So, it ends up deleting all the previous entries in the database and recreates them again based on the collection passed in.
We currently convert PersistentSet into HashSet and serialize it for sending to GWT client. When the same set come back to server for persistence, Hibernate is not able to recognize the objects in the HashSet. So, it ends up deleting all the entries and recreating them again. This is not acceptable behavior thus forcing us to manage Collections using custom coding efforts.
It appears this is a limitation in how the collections are implemented in Hibernate because it assumes all the objects or collection objects reside in the same JVM for their entire life. Whatever happened to the distributed computing such as SOA/CORBA/GWT-RPC??
Any simple work-around or a clean solution would be highly appreciated.
MA
Look at the EQUALS/HASH-CODE of your beans. Hibernate only assures you that an == test will work as long as the session that the object was fetched in is still open (and being used here, obviously). For other cases, you have to describe to Hibernate how to tell if two objects really represent the same thing. This is no different from any other distributed app. If you serialize an object and then de-serialize it, == will no longer function. It's up to you to ensure that the equals method of your object will be able to point the JVM in the correct direction in these cases.