-
1. Re: How to get EntityManager without @In?
wise_guybg Aug 31, 2007 4:58 AM (in response to gothmog)Try Component.getInstance("entityManager", true)
-
2. Re: How to get EntityManager without @In?
gothmog Aug 31, 2007 5:22 AM (in response to gothmog)Good idea, I tried it but got
21:11:46,928 ERROR [STDERR] Exception in thread "Thread-21" 21:11:46,928 ERROR [STDERR] java.lang.IllegalStateException: No application context active 21:11:46,928 ERROR [STDERR] at org.jboss.seam.Component.forName(Component.java:1690) 21:11:46,928 ERROR [STDERR] at org.jboss.seam.Component.getInstance(Component.java:1740) 21:11:46,928 ERROR [STDERR] at org.jboss.seam.Component.getInstance(Component.java:1723) 21:11:46,928 ERROR [STDERR] at model.EXAccessPoint.flushToDb(EXAccessPoint.java:217) 21:11:46,928 ERROR [STDERR] at model.EXAccessPoint.access$0(EXAccessPoint.java:207) 21:11:46,928 ERROR [STDERR] at model.EXAccessPoint$InvalidateList.run(EXAccessPoint.java:257)
Then I noticed that my em has ended up in the conversation scope21:10:18,545 INFO [Component] Component: em, scope: CONVERSATION, type: JAVA_BEAN, class: org.jboss.seam.persistence.ManagedPersistenceContext
My components.xml looks like<core:init debug="true" jndi-pattern="isis-prototype/#{ejbName}/local" transaction-management-enabled="true" /> <security:identity authenticate-method="#{authenticator.authenticate}"/> <web:multipart-filter create-temp-files="true" max-request-size="1000000" url-pattern="*.seam"/> <web:context-filter url-pattern="/content/*"/> <persistence:managed-persistence-context name="em" auto-create="true" persistence-unit-jndi-name="java:/viewEntityManagerFactory"/>
and my persistence.xml looks like<persistence-unit name="viewDatabase"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:/viewDatasource</jta-data-source> <properties> <property name="hibernate.hbm2ddl.auto" value="create-drop"/> <property name="hibernate.show_sql" value="false"/> <!-- These are the default for JBoss EJB3, but not for HEM: --> <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/> <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/> <property name="jboss.entity.manager.factory.jndi.name" value="java:/viewEntityManagerFactory"/> </properties> </persistence-unit>
Any ideas?
I can't remember how I did this, but I did read the seam manual on transactions in conversations and (in another class unrelated to this) I followed the approach given, which was to set the flush mode to manual to get the atomic transactions across a conversation on a @Begin, so...@Scope(ScopeType.CONVERSATION) public class MaintainProfileAction implements Serializable { ... @Begin(join=true, flushMode=FlushModeType.MANUAL) public void find() { ...
has this forever put the em in conversation scope I wonder ?
Any ideas? another persistence unit?
Troy -
3. Re: How to get EntityManager without @In?
pmuir Aug 31, 2007 5:49 AM (in response to gothmog)An SMPC is in the conversation scope always as the ManagedPersistenceContext component is annotated @Scope(CONVERSATION).
Anyway, look at ContextualHttpServletRequest for how to set up and tear down the context. -
4. Re: How to get EntityManager without @In?
nhieb Aug 31, 2007 6:14 AM (in response to gothmog)Why don't u use EJB3 timers? You can create timer that will do ur "housekeeping" work, and it will survive redeploys and server shutdown. Besides, in this case EM will be accessible automatically.
try something like this@Stateless @Name("jobsTimer") public class JobsTimerIMPL implements JobsTimer { @Resource javax.ejb.TimerService timerService; @In EntityManager entityManager; @Logger private Log log; public void createTimer() { Timer timer = timerService.createTimer(5, 5, "timer that fires every 5 sec and starts 5 sec after it was created"); } @Timeout public void timeout(Timer timer) { //em must be automatically accessable here log.info(em); }
So create timer with createTimer method, and then timeout method wll be called every 5 sec -
5. Re: How to get EntityManager without @In?
gothmog Aug 31, 2007 6:46 AM (in response to gothmog)I thought about using timers but got discouraged when in the spec it says
While timer durations are express in millisecond units, this is because the millisecond is the unit of time granularity used by the API...it is expected that most timed events will correspond to hours, days or longer...
and then later on it says
The timer service is intended for the modeling of long lived business processes.
So I came to the conclusion that it was a bit of an overkill and hence thought a simple background thread should do it.
I tried Pete's idea of trying to setup the contexts for the thread, but the problem there lies in the fact that I can't because the ThreadLocal storages access is local to the seam package so I can't actually set anything on it :(
If all else fails, I guess I'll have to use timers. -
6. Re: How to get EntityManager without @In?
pmuir Aug 31, 2007 6:50 AM (in response to gothmog)Use Seam managed timers. 1) Simple timers (default, don't persist across application restart), 2) EJB3 (do persist - but this can be not the beehaviour you want), 3) Quartz (don't persist, good business interval support)
-
7. Re: How to get EntityManager without @In?
nhieb Aug 31, 2007 6:51 AM (in response to gothmog)May be this can work
Lifecycle.beginCall(); Component.getInstance("entityManager", true) Lifecycle.endCall();
I used that in MDB to get some seam components... -
8. Re: How to get EntityManager without @In?
gothmog Aug 31, 2007 7:22 AM (in response to gothmog)Thanks for the suggestions, I tried the beginCall() ... endCall() on the lifecycle and yes that does work, I can get an EntityManager in my thread however back to the original problem, the entity manager has not started a transaction for me, so nothing gets posted to the db and when I flush I get
23:15:43,708 ERROR [STDERR] Exception in thread "Thread-21" 23:15:43,708 ERROR [STDERR] javax.persistence.TransactionRequiredException: no transaction is in progress 23:15:43,708 ERROR [STDERR] at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:293) 23:15:43,708 ERROR [STDERR] at org.jboss.seam.persistence.EntityManagerProxy.flush(EntityManagerProxy.java:90) 23:15:43,708 ERROR [STDERR] at model.EXAccessPoint.flushToDb(EXAccessPoint.java:236) 23:15:43,708 ERROR [STDERR] at model.EXBackgroundThread.run(EXBackgroundThread.java:36) 23:15:44,282 INFO [EXAccessPoint] calculateEx():from=11:15:39 PM;now=11:15:44 PM;exs.size()=3;currentStartIndex=2
The code inside the thread does this at the momentLifecycle.beginCall(); EntityManager em = (EntityManager)Component.getInstance("em", true); ... em.persist(...); ... em.flush(); Lifecycle.endCall();
I'll try JNDI directly... -
9. Re: How to get EntityManager without @In?
gothmog Aug 31, 2007 8:02 AM (in response to gothmog)Thanks guys for all your help, I learnt a lot on this thread.
In the end I just wrote a SLSB using a @PersistenceContext annotation to get my EntityManager then I just did a lookup via JNDI in the housekeeping thread to get it then called a write method on it passing the object requiring the housekeeping.
Thanks
Troy