-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 
Author Message
 Post subject: Found two representations of same collection(not with clear)
PostPosted: Thu Nov 16, 2006 6:55 am 
Newbie

Joined: Thu Nov 16, 2006 6:12 am
Posts: 1
Hello to all,

I have some EJB3.0 code, so with the mappings done via Annotations.

The code was working fine, but I had to add some Entity Listeners.

Those entity listeners are of @PostLoad type.

The implementation of the listener would lookup a local implementation of a session bean that would perform a simple query like this:

Code:
Query oQuery = moManager.createQuery( "SELECT COUNT(*) FROM tEntityCommonReport cr WHERE cr.policyId='" + iPKey + "'" );
Long oNumOfErrors = (Long)oQuery.getSingleResult();


The getSingeResult call will throw an exeption like:

HibernateException: Found two representations of same collection.

What I do not understand is why a simple COUNT query would have anything to do with my collections in the Entity Bean.

I am using EJB3.0 EntityBeans, deployed on JBoss4.0.4 GA.

The policy object that has attached the PostLoad listener has a Set of Actions and a transient error state that I want to populate with the custom listener.

I have searched the forum and the docs for this but all I have found related are those topics that use session.clear(), but I do not use that. (I dont know if EJB containter calls that behind the scenes).

The custom listener is listed bellow
Code:
    @PostLoad void afterPolicyLoad()
    {
        String szPolicyObjectName = "policy";
        System.out.println( szPolicyObjectName + " '" + getName() + "' has been loaded. Setting error state..." );
        try
        {
            InitialContext oContext = new InitialContext();
            ILocalTransact oLocalTransact = (ILocalTransact)oContext.lookup( "Application/BeanTransact/local" );
            errorState = oLocalTransact.getPolicyObjectState( getId(), szPolicyObjectName + "Id" );
        }
        catch( Exception e )
        {
            errorState = E_STATE_CLEAR;
            e.printStackTrace();
        }
    }


and the getPolicyObjectState method in the BeanTransact session bean is:
Code:
    public int getPolicyObjectState(long iPKey, String szIdColumn )
    {
        Query oQuery = moManager.createQuery( "SELECT COUNT(*) FROM tEntityCommonReport cr WHERE cr." + szIdColumn + "='" + iPKey + "'" );
        try
        {
            Long oNumOfErrors = (Long)oQuery.getSingleResult(); //thows THE EXCEPTION!!!!!!
            if( oNumOfErrors != null )
            {
                return oNumOfErrors > 0 ? tEntityPolicy.E_STATE_ERROR : tEntityPolicy.E_STATE_CLEAR;
            }
        }
        catch( Exception e )
        {
            e.printStackTrace();
        }
        return tEntityPolicy.E_STATE_CLEAR;
    }


the moManager is injected with @PersistenceContext annotation.

Thank you for you time.

- Ilie


Top
 Profile  
 
 Post subject: Re: Found two representations of same collection(not with cl
PostPosted: Fri Nov 17, 2006 9:00 am 
Newbie

Joined: Mon Sep 04, 2006 6:45 am
Posts: 4
Imho ejb ql doesn't understande COUNT(*) try using COUNT(cr.PK) (or smth like that)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 23, 2006 1:05 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
use of an EM inside a listener is not allowed, even indirect use

_________________
Emmanuel


Top
 Profile  
 
 Post subject: use of Em is not allowed in listeners?
PostPosted: Fri Aug 03, 2007 10:38 am 
Beginner
Beginner

Joined: Fri Apr 20, 2007 10:48 am
Posts: 49
Location: France
Hi Emmanuel,

>use of Em is not allowed in listeners

I was really surprized by your post, can you point me to an explanation of why it is that way?

I have a similar problem : I need to use @PreUpdate to catch update events and do some journalization in the same transaction. What do you
suggest as a replacement solution? Do we have to extend the EntityManager and apend our own listening engine? If it's the case, where do we say to hibernate to use our implementation instead of the default one.

Thanks and regards,
Zied

_________________
Regards,
Zied Hamdi


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 03, 2007 2:36 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
you need to open a different EntityManager, but reusing the same is not allowed.
Mainly because the flush process would be screwed by entity changes.

_________________
Emmanuel


Top
 Profile  
 
 Post subject: and the transaction?
PostPosted: Sat Aug 04, 2007 7:52 am 
Beginner
Beginner

Joined: Fri Apr 20, 2007 10:48 am
Posts: 49
Location: France
Hi Emmanuel,

Thanks for your fast reply. Do you suggest something in the case I want to have both actions (primary and listener) in the same transaction?

You said:
>Mainly because the flush process would be screwed by entity changes.

Does it suffice to do a flush manually at the start of the listener method? (if we suppose I could use a @PostUpdate instead of a @PreUpdate): that way, the sql will be generated against the values before they are changed in the listener...

If it's not the case, I took a brief look at Shale, it seams to handle two step transactions, is it an alternative (using two managers that point to the same db), so the question is more like: "does Shale have an adapter to be branched with the EntityManager API?)

Sorry I'm maybe going too far for a simple problem but I see only one other solution alternative: To have a factory for my own EntityManagerHolder that delegates calls to the "real" EntityManager, In that case I loose some readability that brings the JPA by features like interceptors and injection...

Any advice please?

_________________
Regards,
Zied Hamdi


Top
 Profile  
 
 Post subject: another alternative maybe
PostPosted: Sat Aug 04, 2007 8:13 am 
Beginner
Beginner

Joined: Fri Apr 20, 2007 10:48 am
Posts: 49
Location: France
Hi Emmanuel,

I've just got another idea, read this post before the other :-)

JTA proposes joining transactions (by REQUIRED, SUPPORTED and MANDATORY) how do that act on sessions, because as far as I know, a session holds a transaction (and an Em holds a session).

By getting another EntityManager and joining the transaction, it should be ok since fetches are done separately (at the Session level or maybe even higher at the em level) and the transaction is at the JDBC low level (so if the join is made under the feet of hibernate, no bugs should occur).

I've tried to find how to do a join in the EntityManager Javadoc, the only proposed method joins the existing JTA transaction (and all is done behind the scene), I believe you have already encoutred a similar question.

If I'm right, can you point me to docs on how to do to make a join in a non JTA environement? you can surely have that in a few minutes, compared to me serching google for hours...

Thanks again,
Zied

_________________
Regards,
Zied Hamdi


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 07, 2007 1:44 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Transaction lifecycles have nothing to do with entity manager lifecycles
Just open 2 EMs on the same transaction.

_________________
Emmanuel


Top
 Profile  
 
 Post subject: how?
PostPosted: Thu Aug 09, 2007 5:45 am 
Beginner
Beginner

Joined: Fri Apr 20, 2007 10:48 am
Posts: 49
Location: France
Hi Emmanuel,

It was good to know it is possible to have two EMs on the same transaction but I experience big difficulties to find how to do that: be assured that before posting this message I took a look on the web, in the forums and in the hibernate source code.

What I found is that EntityManagerFactoryImpl#createEntityManager() creates an EntityManagerImpl with the imbedded session factory, EntityManagerImpl.getRawSession() class openSession() unconditionally which in turn creates a new instance of SessionImpl unconditionally. So the only esperence that rests is in the Interceptor passed in the creation of the SessionImpl (by the factory). But I only found one implementation: EmptyInterceptor.

In addition to that: TransactionImpl has in its fields an EM (that can be passed only in its constructor) so the last chance is to have a compound EM that holds all the current EMs belonging to that transaction instance, again, in the implementations of HibernateEntityManagerImplementor theresn't any candidate for that task.

Can you please tell me how to accomplish this task? do I have to do a separate post for this question?

Thanks and sorry for spamming :-)

_________________
Regards,
Zied Hamdi


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 09, 2007 6:39 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Oh I thought you were using JTA, not the clumsy JDBC driver tx.
Year in this case that makes it harder, your best bet is to do em.getDelegate() which returns a Session and then use .connection(), from here you can build a session sessionFactory.openSession(connection);

_________________
Emmanuel


Top
 Profile  
 
 Post subject: ok :-)
PostPosted: Fri Aug 10, 2007 3:42 am 
Beginner
Beginner

Joined: Fri Apr 20, 2007 10:48 am
Posts: 49
Location: France
Thanks Emmanuel,

Your advices were very helpful, as the fact to use two separate EMs: it works perfectly today if I use two separate transacations. So seen it's a reusable part, correcting it later will affect only localized code.

After all it's not the app safety that is in danger. Maybe later I'll fix the problem with Shards, having a two phase commit on the same database.

Anyway, all what was said here is good to know, it is good to know what is not possible to do, and what needs bigger effort too.

The conclusion of this discussion is: Hibernate is still better thought than JPA: it allows this feature that I think will become a common request soon.

Mike, a regular poster said he saw in the specs the folowing text:
Quote:
In general, portable applications should not invoke EntityManager or Query operations,
access other entity instances, or modify relationships in a lifecycle callback method

http://forum.hibernate.org/viewtopic.ph ... 95#2361495

I think they're in the army, a case like mine can't be resolved in a more beautiful way than catching update attempts and doing backup copies before it's done, you pay sooner or later when you are too restrictive.

Regards,
Zied

_________________
Regards,
Zied Hamdi


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.