Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / March 2007

Tip: Looking for answers? Try searching our database.

Persistent Collection malfunction

Thread view: 
pek - 02 Mar 2007 17:53 GMT
OK, here is what I have:
Class Game with :
 @OneToMany
 List getTeams()
 @OneToOne
 CardStack centerStack()

Class Team
 @OneToMany
 List getPlayers()

Class Player
 @OneToOne
 CardStack getHandStack()

Class CardStack
 @OneToMany
 List getCards()

Every list is an ArrayList. The problem is that I has a Stateful Bean
GameManager that has a persisted game reference.
When all players tell to the game that they are ready to play through
the setPlayerReady(boolean state) of GameManager, then the method
startGame() automatically is called. startGame() adds 108 cards in the
centerStack and then from centerStack it gives each player 11 cards by
removing them from the centerStack (I do more things with it thats why
I don't give them right away to players hand). This is done by using
this method:
for (Team aTeam:game.getTeams()) {
 for (Player aPlayer:aTeam.getPlayers()) {

aPlayer.getHandStack().getCards().add(game.getCenterStack().getCards().remove(0));
 }
}

This correctly adds 11 cards to player's hand. But the funny part is
that it also adds 11 identical references of the player in the team!
After doing this, I refresh the game through EntityManager manager;
manager.refresh(game) and call
game.getTeams().get(0).getPlayers().size() = 11. All players are the
same one. The database has everything correct, 1 player for each team
and 11 cards for each player. I don't get it..I tried doing every
thing.. Flushing before adding cards, flushing before removing,
refreshing, merging..Everything.. And the wierd part is that every
change makes other malfunctions. Some times I get a duplicate key
violation when I try to remove one card from center stack and add it
to players hand all at once (like above) and to avoid this I have to
do:
Card aCard = game.getCenterStack().getCards().remove(0);
manager.flush();
aPlayer.getHandStack().getCards().add(aCard);
and that works but has other problems... I can't find any good source
for working with collections..

Any help..?
Thanks in advance.
Joshua Cranmer - 03 Mar 2007 02:01 GMT
> OK, here is what I have:
> Class Game with :
[quoted text clipped - 52 lines]
> Any help..?
> Thanks in advance.

First off, just a little comment to make about your design: I think it
would be better to have addTop(), addBottom(), removeTop(),
removeBottom() for your CardStack class to clean a little code up.

Design decisions aside, are you using multiple threads? If so, then you
might be having race conditions -- the key violations would seem to
imply that.

Could you also elaborate more on the extra players, i.e., does
game.getTeams().get(0).getPlayers().get(0) ==
game.getTeams().get(0).getPlayers().get(1) ?
pek - 03 Mar 2007 15:21 GMT
> > OK, here is what I have:
> > Class Game with :
[quoted text clipped - 52 lines]
> > Any help..?
> > Thanks in advance.

First thanks for the quick reply. I really need it..

> First off, just a little comment to make about your design: I think it
> would be better to have addTop(), addBottom(), removeTop(),
> removeBottom() for your CardStack class to clean a little code up.
Currently I thought of removing completely the CardStack since it only
has a set of cards in an ArrayList<Card>. But I found this useful in
other situations (where a ArrayList<CardStack> is needed, I found it
really hard to map ArrayList<ArrayList<Card>> in the database :S) so I
am not sure if removing it is a good idea after all. Interesting
thought with these methods though, but since it only beautifies my
code I'd like to firstly find out what is the problem and then little
by little make changes trying not to affect (disastrously) the code
(XP programming style).

> Design decisions aside, are you using multiple threads? If so, then you
> might be having race conditions -- the key violations would seem to
> imply that.
The GameManager is a stateful bean. Every member of the network must
create remotely this bean and create or join an existing game. From
there he uses the bean for game interactions. I had to persist all the
data for sharing it. I don't create any threads in the bean, but I
assume that every bean is a thread by itself. I am not sure if this is
a problem.

> Could you also elaborate more on the extra players, i.e., does
> game.getTeams().get(0).getPlayers().get(0) ==
> game.getTeams().get(0).getPlayers().get(1) ?
Well, I am using List which allows duplicates, but no. There isn't
anywhere in my code that adds the same player. A member of the game
must create a GameManager remotely, create a game or join an existing
with a token he got when he logged in (String
DomainManager.login(String username,String password)). This token (64
random characters) is used to locate the members data in the database
(for security reasons I don't want to send any member data to the
client,or any reference to any server-side object at all) and then
create a Player object with the member's data that was found, in
Players class constructor [Player(Member aMember)]. After that, the
player is added properly to the teams player list. I thought of using
a collection that doesn't allow duplicates but I couldn't find one
that is also indexed. A player can add himself in any team using the
teams index and any where in the teams player list using seatIndex
(game.getTeams().get(teamIndex).getPlayers().add(seatIndex,Player)).

I hope this is enough. Thank you again. I am really waiting for your
reply.
Joshua Cranmer - 03 Mar 2007 20:10 GMT
> First thanks for the quick reply. I really need it..
>
[quoted text clipped - 19 lines]
> assume that every bean is a thread by itself. I am not sure if this is
> a problem.

I don't know much about beans, so I don't know if it creates threads.
The easiest way to find out is to use the command
System.err.println(Thread.getAllStackTraces());

>> Could you also elaborate more on the extra players, i.e., does
>> game.getTeams().get(0).getPlayers().get(0) ==
[quoted text clipped - 14 lines]
> teams index and any where in the teams player list using seatIndex
> (game.getTeams().get(teamIndex).getPlayers().add(seatIndex,Player)).

What your wording seems to imply is that the program is somehow
deep-copying all of the players, but I doubt this is the case.
Seeing as I have no idea how the for loops could mangle the players so,
I would think that including all of the code of startGame() would be
helpful. Tracking done segfaults in C has taught me that the incorrect
code need not be the instruction that actually fails.

Actually, on second thought, the code of Card and GameManager would be
really helpful right about now (especially if it's Card that's causing
duplicate key information).
pek - 07 Mar 2007 22:52 GMT
> > First thanks for the quick reply. I really need it..
>
[quoted text clipped - 53 lines]
> really helpful right about now (especially if it's Card that's causing
> duplicate key information).

OK, I have uploaded the parts that are needed over here:
http://pek.ekei.com/misc/help/cards/source.html
GameManager : The Stateful Bean
Card : The Card class
Game : A Data Type class that holds all information of a game.
Client : An example of how things work

Each file has some documentation in it.
Joshua Cranmer - 09 Mar 2007 00:05 GMT
>>> First thanks for the quick reply. I really need it..
>>>> First off, just a little comment to make about your design: I think it
[quoted text clipped - 59 lines]
>
> Each file has some documentation in it.

/** Stupid Method */

Gotta love documenting stuff, don't you? (I've always thought that
documenting stuff like setFoo: Sets the foo variable were pointless)

At this point, it seems to me that either Utility's deckCreator (less
likely) is either messing up the players or that J2EE or JavaBeans (more
likely) are. Suffice to say, this is completely flummoxing me right now.
Lew - 09 Mar 2007 02:24 GMT
> At this point, it seems to me that either Utility's deckCreator (less
> likely) is either messing up the players or that J2EE or JavaBeans (more
> likely) are. Suffice to say, this is completely flummoxing me right now.

J2EE and JavaBeans are specifications. How do you think they are "messing up
the players"?

JavaBeans are like any other class - they are written by someone and could be
buggy. Which beans do you suspect of causing trouble? It is meaningless to say
"JavaBeans" are at fault generally; that's exactly like saying "classes" are
at fault. It may be true, but not usefully so. What is useful is to identify
which JavaBeans are causing trouble.

Are you suggesting that the J2EE container is messing up? Which one are you
using? The major ones are very, very unlikely to be the source of your
difficulty. On what basis could you say that it is "more likely" to be a cause
of trouble?

What is "Utility" and its "deckCreator"? Why do you think these artifacts are
"less likely" to be the source of trouble?

-- Lew
pek - 09 Mar 2007 15:50 GMT
> > At this point, it seems to me that either Utility's deckCreator (less
> > likely) is either messing up the players or that J2EE or JavaBeans (more
[quoted text clipped - 18 lines]
>
> -- Lew

I'm personally using JBoss
Joshua Cranmer - 10 Mar 2007 01:40 GMT
>> At this point, it seems to me that either Utility's deckCreator (less
>> likely) is either messing up the players or that J2EE or JavaBeans
[quoted text clipped - 19 lines]
>
> -- Lew
What I mean is that the some hitch in the specifications are causing the
trouble, IMHO. If you read that source code that pek posted, you will
see what I mean by Utility (a class) and deckCreator (a method). I think
that they are less likely to be the source because the method seems
straightforward to me and more difficult to cause problems than the J2EE
or JavaBeans code. That said, I am casting about in unknown waters, so
my opinion should not be taken as truth.
pek - 10 Mar 2007 04:32 GMT
> >> At this point, it seems to me that either Utility's deckCreator (less
> >> likely) is either messing up the players or that J2EE or JavaBeans
[quoted text clipped - 27 lines]
> or JavaBeans code. That said, I am casting about in unknown waters, so
> my opinion should not be taken as truth.

Is there anywhere in the web that I can find information about
collection implementation in J2EE... All the books I have found and
JavaDocs simply say how to remove and add to a collection, there isn't
anywhere something like collection.add(anotherCollection.remove(0)) to
tell me if this is wrong or right and why...
Lew - 10 Mar 2007 05:16 GMT
> Is there anywhere in the web that I can find information about
> collection implementation in J2EE... All the books I have found and
> JavaDocs simply say how to remove and add to a collection, there isn't
> anywhere something like collection.add(anotherCollection.remove(0)) to
> tell me if this is wrong or right and why...

Sure there is:

<http://java.sun.com/javase/6/docs/api/java/util/Collection.html#add(E)>

and

<http://java.sun.com/javase/6/docs/api/java/util/Collection.html#remove(java.lang
.Object
)>

which, without even following the links, tells you right away that unless
collection holds Boolean and anotherCollection holds Integer, the idiom will
not work.

You should be in the habit of checking the API docs for this kind of question.

-- Lew
pek - 10 Mar 2007 08:09 GMT
> > Is there anywhere in the web that I can find information about
> > collection implementation in J2EE... All the books I have found and
[quoted text clipped - 17 lines]
>
> -- Lew

I believe this is incorrect. The remove of collection is
Collection.remove() with no parameters. I use ArrayLists which
implements List and has a method ArrayList.remove(int index) which
returns the removed object in the specified index
( http://java.sun.com/javase/6/docs/api/java/util/List.html#remove(int)
)
Lew - 10 Mar 2007 14:17 GMT
>>> Is there anywhere in the web that I can find information about
>>> collection implementation in J2EE... All the books I have found and
>>> JavaDocs simply say how to remove and add to a collection, there isn't
>>> anywhere something like collection.add(anotherCollection.remove(0)) to
>>> tell me if this is wrong or right and why...

Lew wrote:
>> Sure there is:
>>
[quoted text clipped - 9 lines]
>>
>> You should be in the habit of checking the API docs for this kind of question.

> I believe this is incorrect. The remove of collection is
> Collection.remove() with no parameters.

No, it's remove( Object o ) with one parameter. You hid that fact with the
ellipsis when you quoted the URL for the Javadoc of the method:

<http://java.sun.com/javase/6/docs/api/java/util/Collection.html#remove(java.lang
.Object
)>

is the correct link.

> I use ArrayLists [sic] which

you didn't say. You said "collection".

> implements List and has a method ArrayList.remove(int index) which
> returns the removed object in the specified index
> ( http://java.sun.com/javase/6/docs/api/java/util/List.html#remove(int)
> )

Unless the source List contains Integers, in which case there is some
ambiguity with autoboxing.

If not dealing with that case, you still have to make sure the base types of
the two Lists are the same.

If they are the same, then

dest.add( src.remove( 0 ))

is perfectly legitimate for two Lists.

What is the exact error you get when you try it?

-- Lew
pek - 11 Mar 2007 23:23 GMT
> >>> Is there anywhere in the web that I can find information about
> >>> collection implementation in J2EE... All the books I have found and
[quoted text clipped - 49 lines]
>
> -- Lew

There is no error... It does exactly what I want it do to.. It removes
a card from one list and adds it to the other..the problem is that
somehow after the method is over and the transaction is commited, the
teams have the same number of players with the number of cards I add,
meaning, I add 11 cards to the player
(player.getCards().add(game.getCenterDeck().getCards().remove(0)) and
the team has 11 references to the SAME player.
game.getTeams().get(1).getPlayers().size = 11.. I can't understand
why. I think that the problem is the way the transaction is commited.
I mean, since the transaction is executed after the method ends, it
probably doesn't make the correct changes. I read somewhere that
hibernate follows a number of steps. I think that this is what screws
everything. But I can't figure out the solution. Any help..?


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.