deltaspike-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "John D. Ament" <johndam...@apache.org>
Subject Re: During @Transactional method EntityManager.flush() causes TransactionRequiredException
Date Tue, 15 Dec 2015 12:56:22 GMT
Paul,

Glad its working.  Please don't hesitate to reach out to the list if you
have further questions.

John

On Mon, Dec 14, 2015 at 7:20 PM Paul Wills <paul.wills@engsol.com.au> wrote:

> Hi John,
>
> I've done the change and it works perfectly :-)
>
> Thanks very much,
> Paul
>
> On 15 December 2015 at 09:06, Paul Wills <paul.wills@engsol.com.au> wrote:
>
> > Thanks John.
> >
> > Thats a simple workaround. The reason I use @Database because the code
> > assist can tell me all the choices of database that I have, instead  of
> > remembering all the different annotations (maybe younger programmers
> don't
> > have many problems remembering everything).
> >
> > I will add @DatabaseApp and @DatabaseVault and see how it goes.
> >
> > Thanks again for your help and suggested workaround.
> >
> > Regards,
> > Paul
> >
> > On 14 December 2015 at 23:51, John D. Ament <johndament@apache.org>
> wrote:
> >
> >> Hi Paul,
> >>
> >> If I had to guess, the main reason this hasn't been fixed is because it
> >> hasn't been a need.  The workaround for the issue is pretty straight
> >> forward -instead of using @Database(APP) and @Database(VAULT) you use
> >> dedicated qualifiers - @VaultDB and @AppDB.  I believe most people would
> >> agree that this is the more correct way to do it anyways, since the
> >> attribute just makes it a bit more confusing.
> >>
> >> I can look to see what it takes to fix 259, I would still recommend this
> >> approach of a dedicated qualifier per instead of common qualifier.
> >>
> >> John
> >>
> >>
> >> On Mon, Dec 14, 2015 at 8:29 AM Paul Wills <paul.wills@engsol.com.au>
> >> wrote:
> >>
> >> > Hi Gerhard,
> >> >
> >> > I've been doing a lot more complicated transactional things in Spring
> >> for 7
> >> > years in Tomcat, so its a little frustrating to "go out on a limb"
> >> against
> >> > the Spring crowd to head down what I believe to be the better path
> (JEE
> >> +
> >> > CDI) only to hit problems which undermine the use of the technology
> (in
> >> > this case Deltaspike Transactional handling).
> >> >
> >> > I have to deploy on Tomcat, so it looks like I have to go with OpenEJB
> >> to
> >> > handle the transactions correctly.
> >> >
> >> > Don't get me wrong, Deltaspike is an essential and great library when
> >> using
> >> > CDI, but it doesn't appear that this issue (DELTASPIKE-259) will be
> >> > resolved any time soon.
> >> >
> >> > Regards,
> >> > Paul
> >> >
> >> > On 14 December 2015 at 21:20, Gerhard Petracek <
> >> gerhard.petracek@gmail.com
> >> > >
> >> > wrote:
> >> >
> >> > > hi paul,
> >> > >
> >> > > it doesn't work due to [1].
> >> > >
> >> > > regards,
> >> > > gerhard
> >> > >
> >> > > [1] https://issues.apache.org/jira/browse/DELTASPIKE-259
> >> > >
> >> > >
> >> > >
> >> > > 2015-12-14 9:59 GMT+01:00 Paul Wills <paul.wills@engsol.com.au>:
> >> > >
> >> > >> The EntityManager is injected into the test case like so
> >> > >> @Inject @Database(Instance.APP) private EntityManager
> entityManager;
> >> > >>
> >> > >> The database producer creates entity managers for 2 database
> >> instances
> >> > >> (APP
> >> > >> and VAULT). I originally had the getAppEntityManager() method
> >> annotated
> >> > >> with TransactionScoped but removing it made no difference to the
> >> > flushing
> >> > >> problem. All other test cases which use the entity manager work
> fine,
> >> > but
> >> > >> they are rather simple, ie no reading back from the database before
> >> > >> commiting.
> >> > >>
> >> > >> Here is the producer for the EntityManager(s).
> >> > >> ----
> >> > >> @ApplicationScoped
> >> > >> public class DatabaseProducer {
> >> > >>     // ~---- Static Variables and Methods
> >> > >> ------------------------------------------
> >> > >>     private static Logger LOGGER =
> >> > >> LoggerFactory.getLogger(DatabaseProducer.class);
> >> > >>
> >> > >>     // ~---- Instance Variables
> >> > >> ----------------------------------------------------
> >> > >>     @Inject @PersistenceUnitName("app") private
> EntityManagerFactory
> >> > >> appEntityManagerFactory;
> >> > >>     @Inject @PersistenceUnitName("vault") private
> >> EntityManagerFactory
> >> > >> vaultEntityManagerFactory;
> >> > >>     private EntityManager appEntityManager;
> >> > >>     private EntityManager vaultEntityManager;
> >> > >>     private DataSource appDataSource;
> >> > >>     private DataSource vaultDataSource;
> >> > >>
> >> > >>     // ~---- Public
> >> > >> Interface-----------------------------------------------------
> >> > >>     @Produces @PicketLink
> >> > >>     private EntityManager getSecuriyEntityManager() {
> >> > >>         return getAppEntityManager();
> >> > >>     }
> >> > >>
> >> > >>     @Produces @Database(Instance.APP)
> >> > >>     private EntityManager getAppEntityManager() {
> >> > >>         final EntityManager em = getEntityManager(Instance.APP,
> >> false);
> >> > >>         em.setFlushMode(FlushModeType.AUTO);
> >> > >>         return em;
> >> > >>     }
> >> > >>
> >> > >>     @Produces @Database(Instance.VAULT)
> >> > >>     private EntityManager getVaultEntityManager() {
> >> > >>         return getEntityManager(Instance.VAULT, false);
> >> > >>     }
> >> > >>
> >> > >>     private EntityManager getEntityManager(final Instance instance,
> >> > final
> >> > >> boolean transactionScoped) {
> >> > >>         EntityManager returnValue = null;
> >> > >>         switch(instance) {
> >> > >>         case APP:
> >> > >>             if (transactionScoped) {
> >> > >>                 returnValue =
> >> > >> appEntityManagerFactory.createEntityManager();
> >> > >>
> >> > >>             } else {
> >> > >>                 if (appEntityManager == null) {
> >> > >>                     appEntityManager =
> >> > >> appEntityManagerFactory.createEntityManager();
> >> > >>                     logDatabaseConnectionInfo(instance);
> >> > >>                 }
> >> > >>                 returnValue = appEntityManager;
> >> > >>             }
> >> > >>             break;
> >> > >>
> >> > >>         case VAULT:
> >> > >>             if (transactionScoped) {
> >> > >>                 returnValue =
> >> > >> vaultEntityManagerFactory.createEntityManager();
> >> > >>
> >> > >>             } else {
> >> > >>                 if (vaultEntityManager == null) {
> >> > >>                     vaultEntityManager =
> >> > >> vaultEntityManagerFactory.createEntityManager();
> >> > >>                     logDatabaseConnectionInfo(instance);
> >> > >>                 }
> >> > >>                 returnValue = vaultEntityManager;
> >> > >>             }
> >> > >>             break;
> >> > >>         }
> >> > >>
> >> > >>         return returnValue;
> >> > >>     }
> >> > >>
> >> > >> ----
> >> > >>
> >> > >> Regards,
> >> > >> Paul
> >> > >>
> >> > >> On 14 December 2015 at 16:42, Mark Struberg <struberg@yahoo.de>
> >> wrote:
> >> > >>
> >> > >> > And how is the entity manager being created?
> >> > >> >
> >> > >> > LieGrue,
> >> > >> > Strub
> >> > >> >
> >> > >> > > Am 14.12.2015 um 04:25 schrieb John D. Ament <
> >> johndament@apache.org
> >> > >:
> >> > >> > >
> >> > >> > > Paul,
> >> > >> > >
> >> > >> > > Could you show us what your test looks like, including
how it
> >> > injects
> >> > >> the
> >> > >> > > bean that is used here.
> >> > >> > >
> >> > >> > > John
> >> > >> > >
> >> > >> > > On Sun, Dec 13, 2015 at 10:09 PM Paul Wills <
> >> > paul.wills@engsol.com.au
> >> > >> >
> >> > >> > > wrote:
> >> > >> > >
> >> > >> > >> I can confirm the Transactional annotation is being
imported
> as
> >> > >> follows
> >> > >> > >>
> >> > >> > >> *import*
> >> org.apache.deltaspike.jpa.api.transaction.Transactional;
> >> > >> > >>
> >> > >> > >> Regards,
> >> > >> > >>
> >> > >> > >> Paul
> >> > >> > >>
> >> > >> > >>
> >> > >> > >>> On 10 December 2015 at 15:06, Paul Wills <
> >> > paul.wills@engsol.com.au>
> >> > >> > wrote:
> >> > >> > >>>
> >> > >> > >>> Whilst the following method is called in a test
case, run
> with
> >> > >> > >>> CdiTestRunner, the entityManager.flush() call
causes a
> >> > >> > >>> TransactionRequiredException.
> >> > >> > >>>
> >> > >> > >>> @Transactional
> >> > >> > >>> public void saveAndFetchUser() {
> >> > >> > >>>    // Given - a new user
> >> > >> > >>>    final User randomUser = createRandomUser(false);
> >> > >> > >>>
> >> > >> > >>>   // When - saved
> >> > >> > >>>    final User savedUser = userService.saveUser(randomUser);
> >> > >> > >>>    // Then - user is saved as well as history
and can be
> >> retrieved
> >> > >> by
> >> > >> > id
> >> > >> > >>> and username
> >> > >> > >>>    assertThat(savedUser.getRoles(), hasSize(greaterThan(0)));
> >> > >> > >>>
> >> > >> > >>>    entityManager.flush();  // manually flush
as
> >> UaiCriteriaQueries
> >> > >> > >> aren't
> >> > >> > >>> flushed automatically
> >> > >> > >>>    final Paged<UserHistory> pagedHistory
=
> >> > >> > >>> findUserHistoryMostRecentFirst(randomUser.getUsername());
> >> > >> > >>>    assertThat(pagedHistory.getDerivedTotal(),
equalTo(1));
> >> > >> > >>>    assertThat(pagedHistory.getList(), hasSize(1));
> >> > >> > >>>
> >> > >> > >>>    ...
> >> > >> > >>> }
> >> > >> > >>>
> >> > >> > >>> Is this a bug, or is there another way to flush
the changes
> to
> >> the
> >> > >> > >>> database?
> >> > >> > >>>
> >> > >> > >>> Environment:
> >> > >> > >>> weld: 2.3.1.Final
> >> > >> > >>> deltaspike: 1.5.1.Final
> >> > >> > >>> deltaspike dependencies
> >> > >> > >>>
> >> > >> > >>> <dependency>
> >> > >> > >>>
> >> > >> > >>> <groupId>org.apache.deltaspike.modules</groupId>
> >> > >> > >>>
> >> > >> > >>> <artifactId>*deltaspike*-*jpa*-module-*api*</artifactId>
> >> > >> > >>>
> >> > >> > >>> <version>${deltaspike.version}</version>
> >> > >> > >>>
> >> > >> > >>> <scope>compile</scope>
> >> > >> > >>>
> >> > >> > >>> </dependency>
> >> > >> > >>>
> >> > >> > >>> <dependency>
> >> > >> > >>>
> >> > >> > >>> <groupId>org.apache.deltaspike.modules</groupId>
> >> > >> > >>>
> >> > >> > >>> <artifactId>*deltaspike*-*jpa*-module-*impl*</artifactId>
> >> > >> > >>>
> >> > >> > >>> <version>${deltaspike.version}</version>
> >> > >> > >>>
> >> > >> > >>> <scope>compile</scope>
> >> > >> > >>>
> >> > >> > >>> </dependency>
> >> > >> > >>>
> >> > >> > >>> <dependency>
> >> > >> > >>>
> >> > >> > >>> <groupId>org.apache.deltaspike.core</groupId>
> >> > >> > >>>
> >> > >> > >>> <artifactId>*deltaspike*-core-*api*</artifactId>
> >> > >> > >>>
> >> > >> > >>> *<version>${deltaspike.version}</version>*
> >> > >> > >>>
> >> > >> > >>> <scope>compile</scope>
> >> > >> > >>>
> >> > >> > >>> </dependency>
> >> > >> > >>>
> >> > >> > >>> <dependency>
> >> > >> > >>>
> >> > >> > >>> <groupId>org.apache.deltaspike.core</groupId>
> >> > >> > >>>
> >> > >> > >>> <artifactId>*deltaspike*-core-*impl*</artifactId>
> >> > >> > >>>
> >> > >> > >>> *<version>${deltaspike.version}</version>*
> >> > >> > >>>
> >> > >> > >>> <scope>compile</scope>
> >> > >> > >>>
> >> > >> > >>> </dependency>
> >> > >> > >>>
> >> > >> > >>> <dependency>
> >> > >> > >>>
> >> > >> > >>> <groupId>org.apache.deltaspike.cdictrl</groupId>
> >> > >> > >>>
> >> > >> > >>> <artifactId>*deltaspike*-*cdictrl*-weld</artifactId>
> >> > >> > >>>
> >> > >> > >>> <version>${deltaspike.version}</version>
> >> > >> > >>>
> >> > >> > >>> <scope>test</scope>
> >> > >> > >>>
> >> > >> > >>> </dependency>
> >> > >> > >>>
> >> > >> > >>> <dependency>
> >> > >> > >>>
> >> > >> > >>> <groupId>org.jboss.weld.se</groupId>
> >> > >> > >>>
> >> > >> > >>> <artifactId>weld-*se*-core</artifactId>
> >> > >> > >>>
> >> > >> > >>> *<version>${weld.version}</version>*
> >> > >> > >>>
> >> > >> > >>> <scope>test</scope>
> >> > >> > >>>
> >> > >> > >>> </dependency>
> >> > >> > >>>
> >> > >> > >>> Regards,
> >> > >> > >>> Paul Wills
> >> > >> > >>
> >> > >> >
> >> > >>
> >> > >
> >> > >
> >> >
> >>
> >
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message