I'm throwing this on the mailing list because I think it is a an interesting subject to discuss there. And there are also more people on the list with similar issues. Hope you don't mind :-)
On Tuesday, November 19, 2002, at 05:37 AM, Dain wrote:
Dain, what you need is more real use-cases. This is really basic stuff which is used in most applications today. I'll be happy to provide you with more examples of such code that is now performing less optimal in JBoss. I might sound a bit negative but in reality I am *very* positive about JBoss, I just start knowing the code better and start seeing its limitations and strengths.On Monday, November 18, 2002, at 04:21 PM, Stefan Arentz wrote:Now I understand. I don't think the optimization I added would help here. The (bad) idea was a user would never call getUsers unless they really wanted to access the data, but now I see that this is plain wrong. I think this will require a big architectural change, so I personally would leave it for 4.0. If you want to take a look at it, be careful with the transaction code. There are a bunch of rules in the spec regarding the usable life of a CMR collection and transactions. Whatever you decide, please post a feature request, so we can track the issue.On Monday, Nov 18, 2002, at 18:23 Europe/Amsterdam, Dain wrote:This has already been solved in 3.2 and 4.0. I think that the patch has been applied to 3.0.4, but I'm not sure, as someone else did the back port. If you are seeing this behavior in 3.0.4 try Branch_3_0. If you are still seeing it in Branch_3_0, send me another email.Dain, thanks for the reply. I just checked out 3.2 and looked at the queries that it does. I think the problem is still there, but maybe we are talking about different issues.
Here are some more details. My setup is this:
Users <-> UserGroups <-> Groups
This is a Many to Many relation, JBoss generates the UserGroups table which has a UserId and GroupId.
I am doing this to add a user to a group:
void Group.addUser(User user)
{
Collection users = this.getUsers();
if (users.contains(user) == false) {
users.add(user);
}
}
It generates the following query:
select UserId from USERGROUPS where GroupId = ?
My idea was to delay the actual loading of this data until users.iterator() or users.size() is being called ... for simple add/delete operations it is not needed at all i think.
What I will do is write feature requests about specific CMP issues like this one. Good examples with detailed descriptions and code examples. That should help for your 4.0 design and maybe some of those improvements can be implemented for 3.x. I think 3.0 and 3.2 are really important because to be honest I don't see 4.0 available for probably at least another year. This is not bad, it is just the way it works. JBoss went through the same release cycle with 2.4 -> 3.0.
So, here is my first take at the collection problem.
What is needed is something that Hibernate calls Lazy Loading or Lazy Initialization. This means that a call like getUsers() returns a smart collection that knows about the (SQL) query that backs it. I think almost *all* database access can be delayed, maybe even the initial select. Except when it is a SELECT FOR UPDATE .... statement i guess, I'm not sure about that.
What kind of access do we have to a Collection?
iterator() - should only call the original SELECT query and then fetch a result when Iterator.next() is called or DELETE when remove() is used.
add() - should only do a optional SELECT On the PK to prevent duplicates and then INSERT
remove() - should only do a SELECT on the PK to find out if the object was part of the collection and then DELETE
I don't know the EJB spec really that well, so I'm not sure what kind of problems this would introduce in combination with caching and transactions.
There are a couple of problems with this approach though.
First of all, the Collection classes don't throw exceptions. So for example, when Collection.iterator() is called, it is impossible to throw a database exception. I'm not sure how to solve this. Maybe the iterator can return a stub null bean that throws an EJBException when accessed, dunno. Sounds flakey though :-)
'Smart Collections' are easy from a Local Bean when everything is in the same VM. What happens when the bean is remote? Fallback to standard Collections or use a proxy object to access the smart collection? How is that done now?
I'll be happy to discuss this in more detail or even start hacking on an implementation for 3.x.
S.
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development
