Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] OneToMany list insertion problem

Hi Tom,

Thanks for your help.  See answers below.

BTW, one thing that seems curious to me...  Through the Eclipse development environment, I downloaded the update for the EclipseLink library.  The library name it downloaded is "EclipseLink 2.3.2 - Indigo".  However, in the log file I see:

EclipseLink, version: Eclipse Persistence Services - 2.3.0.v20110604-r9504|#]

Is this really 2.3.2 or do I somehow have 2.3.0?  Did this not give me the right thing?  If not, where should I download it from?


On Feb 29, 2012, at 9:51 AM, Tom Ware wrote:

> Let me try to see if I understand what you are doing.
> 
> First, I assume when you talk about two transactions, you are talking about two consecutive calls to the same session bean method and the transaction ends as that method ends.  Is that correct?

	Yes, exactly.

> 
> Next in that method, you are doing roughly this:
> 
> 1. game = findGame();
> 2. output(games.groups.size());
> 3. group = game.removeGroup();
> 4. ouput(group.lines.size());
> 5. line = group.removeLine();
> 6. line.update()
> 7. group.addLine(line);
> 8. game.addGroup(group);
> 9. output(group.lines.size());
> 10. output(games.groups.size());

	Yes.

> 
> The first time this method is called, everything seems to go as expected.  Correct?

	Yes.  At the end of the transaction, the output for the list of lines is correct which is what I'm looking at in particular.  All lines are there and ordered as expected.

> 
> The second time you call this method, one of the outputs does not output what you expect.  Which one?

	At the beginning of the 2nd transaction/routine, before I change anything, I again print out the list of lines to verify things are still as expected.  They aren't.  The list no longer includes the line that was removed and was reinserted in the list.

> 
> Does any of this code make calls that cause other transactions to occur?

	No, no other transactions.  It's just this one routine that is called.  I call the addUserSelectorQuestionLine routine that is part of the UserSelectorQuestionGroup class.  That's it.

> 
> How do you access the lists when you get the sizes of them?  Are you looking at them in the debugger?  Are you accessing them through access methods on the classes that supply them?  Are you getting them some other way?

	Very bare bones... just printing statements to the log file.  Using the .size() routine on the lists to get the number of elements.  Then I step through them one by one and printing a line for each that shows the element name and ranking. That's how I know which one is missing.

> 
> -Tom
> 
> On 28/02/2012 6:21 PM, Renee Revis wrote:
>> 
>> Hmm... well, I was hopeful the upgraded version would solve the problem, but it
>> didn't.
>> 
>> Not sure what you need to see in regards to the transaction begin/end. I just
>> have a call into an EJB bean. The entity manager is injected in the bean and I
>> then call the appropriate routine to process/get the desired question. There are
>> a few JPA calls before the ones I included, but they just get me to the correct
>> game for the user so don't seem important to include. The routine ends just
>> after the calls I showed and so that's the end of the transaction.
>> 
>> I've been playing with things a bit, based on looking at this bug you referenced
>> and it does seem to be related to removing and adding the entity back into the
>> list. I created a test where I get a pointer to the list of the elements that
>> exist initially. After modifying the question line, I completely clear out the
>> list that the group references and add all of the elements back in, one by one.
>> I've tried two scenarios - one where I do a remove as I have been doing
>> previously and one where I only reference the question line using a get. The
>> remove case fails, the get case succeeds. Here are the particulars:
>> 
>> --------------------------------------------------------
>> 1st scenario with remove (this fails - i.e., the list doesn't include the
>> nextQuestionLine element in the next transaction):
>> 
>> tmpLines = nextQuestionGroup.getQuestionLines();
>> nextQuestionLine = nextQuestionGroup.getQuestionLines().remove(0); // REMOVE
>> 
>> <process the question line>
>> 
>> nextQuestionGroup.setQuestionLines(new ArrayList<UserSelectorQuestionLine>());
>> for (UserSelectorQuestionLine nextLine : tmpLines) {
>> nextQuestionGroup.addUserSelectorQuestionLine(nextLine);
>> }
>> nextQuestionGroup.addUserSelectorQuestionLine(nextQuestionLine);
>> 
>> 
>> --------------------------------------------------------
>> 2nd scenario with get (this is fine):
>> 
>> tmpLines = nextQuestionGroup.getQuestionLines();
>> nextQuestionLine = nextQuestionGroup.getQuestionLines().get(0); // GET
>> 
>> <process the question line>
>> 
>> nextQuestionGroup.setQuestionLines(new ArrayList<UserSelectorQuestionLine>());
>> for (UserSelectorQuestionLine nextLine : tmpLines) {
>> nextQuestionGroup.addUserSelectorQuestionLine(nextLine);
>> }
>> --------------------------------------------------------
>> 
>> 
>> 
>> 
>> On Feb 28, 2012, at 12:49 PM, Tom Ware wrote:
>> 
>>> I can't really tell how your transactions begin and end in the pseudo code you
>>> have provided. Before going into that, I'd like to suggest you try a more
>>> recent version of EclipseLink. We have fixed a couple of bugs related to lists
>>> since 2.1.3. One that jumps out at me is this one:
>>> 
>>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=346022
>>> 
>>> Although, the bug describes an issue with ManyToMany, the fix would cover
>>> other collections as well.
>>> 
>>> I suggest verifying you still see an issue on EclipseLink 2.3.2.
>>> 
>>> -Tom
>>> 
>>> On 28/02/2012 11:52 AM, Renee Revis wrote:
>>>> 
>>>> What I mean is that I make many requests to get questions. In each transaction,
>>>> I remove a question line from the list, update the ranking, add the line back
>>>> into the list and then return the question to the user.
>>>> 
>>>> When I'm debugging, I'm just comparing the difference between two of these
>>>> transactions. Everything seems fine at the end of the first one, just before the
>>>> commit, but when I check the data at start of the next request/transaction, I
>>>> find the situation of one question line no longer showing up in the list. It's
>>>> still there, because the JPA query finds it, but the list in the entity no
>>>> longer references it.
>>>> 
>>>> I'm using EclipseLink 2.1.3 - Helios with GlassFish 3.1.1. I get the entity
>>>> manager through injection:
>>>> 
>>>> @PersistenceContext(unitName = "UserDB_Lib")
>>>> private EntityManager userEm;
>>>> 
>>>> Here are some relevant lines (with some unnecessary detail removed):
>>>> 
>>>> When the transaction first starts, we get the group we want to use. I display
>>>> the number of lines in the list and log the list elements with the
>>>> showQuestionLines routine, as well as show the number of lines we found in the
>>>> db with the query.
>>>> 
>>>> 
>>>> nextQuestionGroup = userGame.getQuestionGroups().remove(0);
>>>> logger.info("use group: " + <ref>.getName() + ", with num lines: " +
>>>> <ref>.getQuestionLines().size());
>>>> showQuestionLines(userEm, nextQuestionGroup);
>>>> dbLines = userEm.createNamedQuery("...").<setParams>.getResultList();
>>>> logger.info("num lines found in db: " + dbLines.size());
>>>> nextQuestionLine = nextQuestionGroup.getQuestionLines().remove(0);
>>>> 
>>>> 
>>>> Then we use the question line, update the ranking, and add it back in as shown
>>>> below. I display the number of elements and the element list again, which, as
>>>> I've said, looks correct at this point for the first transaction, but at the
>>>> start of the next transaction, it's different. I'm pretty sure the flush command
>>>> is unnecessary because this is the end of the transaction, but I've been trying
>>>> anything I could think of.
>>>> 
>>>> I'm using the reference to the same element that I removed from the list (i.e.,
>>>> nextQuestionLine). That is still a persisted entity, right? I'm not somehow
>>>> getting a copy of it and so adding back in an unpersisted entity to the list,
>>>> am I?
>>>> 
>>>> 
>>>> // Add the question line back into the group, likely with an updated ranking and
>>>> thus, position in the list
>>>> nextQuestionGroup.addUserSelectorQuestionLine(nextQuestionLine);
>>>> 
>>>> 
>>>> // Add the question group back into the game. It will be re-ordered by the new
>>>> min ranking
>>>> userSelectorGame.addQuestionGroup(nextQuestionGroup);
>>>> 
>>>> 
>>>> logger.info("after, num lines for group: " +
>>>> nextQuestionGroup.getQuestionLines().size());
>>>> logger.info("after, num groups for game: " +
>>>> userGame.getQuestionGroups().size());
>>>> showQuestionLines(userEm, nextQuestionGroup);
>>>> userEm.flush();
>>>> 
>>>> 
>>>> 
>>>> On Feb 28, 2012, at 11:08 AM, Tom Ware wrote:
>>>> 
>>>>> You mention you are making two requests, the first to make changes to the
>>>>> list, and the second where you see the problem. Can you please give some more
>>>>> details about how this is work.
>>>>> 
>>>>> How are the transactions delineated? Is the first one finished by the time the
>>>>> 2nd one starts?
>>>>> 
>>>>> How are you getting the EntityManagers?
>>>>> 
>>>>> Can you give some pseudo code for each request?
>>>>> 
>>>>> What version of EclipseLink are you using?
>>>>> 
>>>>> -Tom
>>>>> 
>>>>> On 28/02/2012 10:39 AM, Renee Revis wrote:
>>>>>> 
>>>>>> I have a bi-directional ManyToOne mapping between two entities. I maintain the
>>>>>> order of the list on the OneToMany side based on a ranking field. Initially I
>>>>>> can create the entities and everything is fine. After that, when I use a
>>>>>> question line, I remove it from the list, update the ranking and then add it
>>>>>> back into the list based on the new ranking value. I realize that the ManyToOne
>>>>>> side is the owning side and it's up to me to maintain the list order in memory
>>>>>> on the ManyToOne side, so that's what I'm trying to do.
>>>>>> 
>>>>>> Everything seems to work fine at first. Just before the EJB transaction
>>>>>> finishes, I log the elements of the list and everything is as I expect.
>>>>>> However,
>>>>>> when I make the next request (i.e., a new EJB transaction), the list shows that
>>>>>> the element was removed from the list, but never added back in. This doesn't
>>>>>> match what it previously showed, however, in the first EJB transaction context.
>>>>>> 
>>>>>> If I do a JPA query for the elements that are actually in the database, all of
>>>>>> the elements are there. And if I restart the server to force everything to be
>>>>>> restored from the database, it all comes back as I expected (i.e., with the
>>>>>> element in the list and ordered as I expected), so it seems to be a caching
>>>>>> issue somehow with the persistence context. I can't figure out why, in the new
>>>>>> transaction, I would see the change from removing the element, but not from
>>>>>> inserting it. They both happen in the same transaction so I should see either
>>>>>> both changes or neither.
>>>>>> 
>>>>>> Does anyone have any ideas as to what might be causing this problem? I've tried
>>>>>> a variety of things, and nothing has worked so far.
>>>>>> 
>>>>>> Thanks for any help,
>>>>>> Renee
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> The relevant parts of the entities are:
>>>>>> 
>>>>>> public class UserSelectorQuestionLine implements Serializable {
>>>>>> private Integer ranking;
>>>>>> @ManyToOne
>>>>>> private UserSelectorQuestionGroup questionGroup;
>>>>>> }
>>>>>> 
>>>>>> and
>>>>>> 
>>>>>> public class UserSelectorQuestionGroup implements Serializable {
>>>>>> @OrderBy("ranking ASC")
>>>>>> @OneToMany(fetch=FetchType.EAGER, mappedBy="questionGroup")
>>>>>> private List<UserSelectorQuestionLine> questionLines;
>>>>>> }
>>>>>> 
>>>>>> 
>>>>>> And the routine I use to add an element into the list in the
>>>>>> UserSelectorQuestionGroup class is:
>>>>>> 
>>>>>> public void addUserSelectorQuestionLine(UserSelectorQuestionLine
>>>>>> newUserSelectorQuestionLine) {
>>>>>> int index=0;
>>>>>> Random gen = new Random();
>>>>>> 
>>>>>> if (this.questionLines.size() == 0) {
>>>>>> this.questionLines.add(newUserSelectorQuestionLine);
>>>>>> } else {
>>>>>> for (UserSelectorQuestionLine nextQuestionLine : this.questionLines) {
>>>>>> if (newUserSelectorQuestionLine.getRanking() < nextQuestionLine.getRanking()) {
>>>>>> break;
>>>>>> } else if
>>>>>> (newUserSelectorQuestionLine.getRanking().equals(nextQuestionLine.getRanking()))
>>>>>> {
>>>>>> // We want to mix up the order of the question lines that have equal ranking
>>>>>> if (gen.nextInt(2) == 1) {
>>>>>> break;
>>>>>> }
>>>>>> }
>>>>>> index++;
>>>>>> }
>>>>>> this.questionLines.add(index, newUserSelectorQuestionLine);
>>>>>> }
>>>>>> this.minRanking = questionLines.get(0).getRanking();
>>>>>> }
>>>>>> 
>>>>>> I know this routine is called and is working correctly because I can
>>>>>> display the
>>>>>> elements of the list in the log after this is called and everything is as
>>>>>> expected in the first EJB transaction context.
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> _______________________________________________
>>>>>> eclipselink-users mailing list
>>>>>> eclipselink-users@xxxxxxxxxxx <mailto:eclipselink-users@xxxxxxxxxxx>
>>>>>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>>>>> _______________________________________________
>>>>> eclipselink-users mailing list
>>>>> eclipselink-users@xxxxxxxxxxx <mailto:eclipselink-users@xxxxxxxxxxx>
>>>>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>>>> 
>>>> 
>>>> 
>>>> _______________________________________________
>>>> eclipselink-users mailing list
>>>> eclipselink-users@xxxxxxxxxxx
>>>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>>> _______________________________________________
>>> eclipselink-users mailing list
>>> eclipselink-users@xxxxxxxxxxx
>>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>> 
>> 
>> 
>> _______________________________________________
>> eclipselink-users mailing list
>> eclipselink-users@xxxxxxxxxxx
>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
> _______________________________________________
> eclipselink-users mailing list
> eclipselink-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/eclipselink-users



Back to the top