You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@olingo.apache.org by Korbinian Bachl <ko...@whiskyworld.de> on 2015/02/16 09:46:07 UTC

olingo JPA / JTA - wrong transactions used

Hi,

I'm using Olingo 2.0.2 and I can query all items so far. When I want to update content, I get error:

...
<message xml:lang="en">"OData - JPA Runtime: JPA update request is not correct"message>
    <innererror>class java.lang.IllegalStateException : 
Exception Description: Cannot use an EntityTransaction while using JTA.innererror>
....

Digging deeper into the code, I ended up in file ODataJPAContextImpl

and there in the function 

private  Object processUpdate(PutMergePatchUriInfo updateView,
      final InputStream content, final Map<String, Object> properties, final String requestContentType)
      throws ODataJPAModelException, ODataJPARuntimeException {
...
boolean isLocalTransaction = setTransaction();

...
}

with

private boolean setTransaction() {
    final EntityTransaction transaction = em.getTransaction();
    if (!transaction.isActive()) {
      em.getTransaction().begin();
      return true;
    }

    return false;
  }


So far I understood this one is the function that collides with my JTA setup. I now wonder how I can suppress to initialize this method?

I've sending in the right EntityManagerFactory into Olingo, e.g.:

public class ConnectorODataJPAServiceFactory extends ODataJPAServiceFactory {

    private static final String PERSISTENCE_UNIT_NAME = "myPU";

    @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
    EntityManagerFactory emf;


    @Override
    public ODataJPAContext initializeODataJPAContext() throws ODataJPARuntimeException {
        ODataJPAContext oDatJPAContext = this.getODataJPAContext();

        try {
            CdiContainer.get().getNonContextualManager().postConstruct(this);
            oDatJPAContext.setEntityManagerFactory(emf);
            oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
            oDatJPAContext.setPageSize(100);
            setDetailErrors(true);
            return oDatJPAContext;
        } catch (Exception e) {
            System.out.print(e);
            throw new RuntimeException(e);
        }
    }

...

So where is the catch here?


Best,

Korbinian

RE: olingo JPA / JTA - wrong transactions used

Posted by "Amend, Christian" <ch...@sap.com>.
Hi Korbinian,

I am still looking into this. This seems to be a combination of problems where the Olingo library might not encode correctly and this leads to issues with the clients.

I have created a JIRA issue to track this: https://issues.apache.org/jira/browse/OLINGO-594

Best Regards,
Christian

-----Original Message-----
From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de] 
Sent: Donnerstag, 12. März 2015 16:07
To: user@olingo.apache.org
Subject: Re: olingo JPA / JTA - wrong transactions used

Hello Christian,

sounds resonable - however, neither browsers like google Chrome or Firefox nor software like SAP HANA works correctly without the additional UTF-8 in the header....

I stumbled over this as I had much garbage in my hana tables, after fixing the header all was fine;

Best,

Korbinian 



----- Ursprüngliche Mail -----
> Von: "Christian Amend" <ch...@sap.com>
> An: user@olingo.apache.org
> CC: "Korbinian Bachl" <ko...@whiskyworld.de>
> Gesendet: Donnerstag, 12. März 2015 13:11:31
> Betreff: RE: olingo JPA / JTA - wrong transactions used
> 
> Hi Korbinian,
> 
> the json specification defines UTF-8 as the default. Also the media type
> application/json doesn`t specify a charset parameter as registered here:
> http://www.iana.org/assignments/media-types/application/json
> 
> Quote: "Note:  No "charset" parameter is defined for this registration.
> Adding one really has no effect on compliant recipients."
> 
> So any client that requests the json format should not treat the payload
> based on an unspecified charset header. I would not like to encourage
> uncompliant clients to use the charset header by adding it as a default in
> the Olingo library.
> 
> Best Regards,
> Christian
> 
> -----Original Message-----
> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> Sent: Donnerstag, 12. März 2015 12:57
> To: user@olingo.apache.org
> Subject: Re: olingo JPA / JTA - wrong transactions used
> 
> Hi Chandan,
> 
> thanks for fixing this!
> 
> I think I hit another problem with olingo odata v2. If you e.g. do:
> 
> ...odata/Entites/?$top=10&$format=json
> 
> the returned data is correct. What is incorrect is the send out header. Via
> the JSON impl. the data is send using UTF-8 encoding, while the header is
> stated solely as:
> Content-Type: application/json;
> 
> which then leads to incorrect pickup by clients as they chose any encoding
> they like or think it might be encoding xxx - leading to various problems
> with special chars.
> 
> The fix is as simple as correcting the header to:
> 
> Content-Type: application/json;charset=utf-8;
> 
> I did this using an filter wrapper around the response, yet IMHO this should
> be fixed inside olingo;
> 
> 
> 
> Best,
> 
> Korbinian
> 
> 
> ----- Ursprüngliche Mail -----
> > Von: "Chandan V.A" <ch...@sap.com>
> > An: user@olingo.apache.org
> > Gesendet: Donnerstag, 12. März 2015 09:53:06
> > Betreff: RE: olingo JPA / JTA - wrong transactions used
> > 
> > Hi All,
> > The support for JTA is implemented by pulling the code from
> > https://github.com/apache/olingo-odata2/pull/2 and applying some
> > adjustments
> > to the code line to be backward compatible. The changes are part of
> > 2.0.4-SNAPSHOT version.
> > 
> > Refer issue - https://issues.apache.org/jira/browse/OLINGO-580 for more
> > details that includes on how to use this feature. In case of bugs feel free
> > to reopen the issue.
> > 
> > Regards
> > Chandan
> > 
> > -----Original Message-----
> > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > Sent: Thursday, February 26, 2015 5:43 PM
> > To: user@olingo.apache.org
> > Subject: Re: olingo JPA / JTA - wrong transactions used
> > 
> > everything in: https://github.com/apache/olingo-odata2/pull/2
> > 
> > Now, when will Chandan do the JPA for olingo OData V4? ;)
> > 
> > 
> > 
> > Best,
> > 
> > Korbinian
> > 
> > ----- Ursprüngliche Mail -----
> > > Von: "Michael Bolz" <mi...@sap.com>
> > > An: "Chandan V.A" <ch...@sap.com>
> > > CC: user@olingo.apache.org
> > > Gesendet: Donnerstag, 26. Februar 2015 12:59:46
> > > Betreff: Re: olingo JPA / JTA - wrong transactions used
> > > 
> > > Hello all,
> > > 
> > > after a first look I agree with the suggestion from Chandan.
> > > So from my side a +1 for a minor rename ;o)
> > > 
> > > Kind regards,
> > > Michael
> > > 
> > > > On 26 Feb 2015, at 12:11, V.A, Chandan <ch...@sap.com> wrote:
> > > > 
> > > > Hello Korbinian,
> > > > I did a quick review of the code and at first sight looks fine. I have
> > > > few
> > > > comments with respect to the name. I feel ODataJPATransaction will be
> > > > more
> > > > appropriate than ODataJPATransactionContext. Because we are executing
> > > > transaction steps using this interface and not just setting and getting
> > > > values.
> > > > WDYT?
> > > > 
> > > > Proposal
> > > > public interface ODataJPATransaction {
> > > > 	void begin();
> > > > 	void rollback();
> > > > 	void commit();
> > > > 	void isActive();
> > > > }
> > > > 
> > > > The class name for default implementation can be
> > > > ODataJPATransactionLocalDefault.
> > > > 
> > > > Thanks
> > > > Kind Regards
> > > > Chandan
> > > > 
> > > > -----Original Message-----
> > > > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > > Sent: Thursday, February 26, 2015 4:09 PM
> > > > To: user@olingo.apache.org; Bolz, Michael
> > > > Subject: Re: olingo JPA / JTA - wrong transactions used
> > > > 
> > > > Here you go: https://github.com/apache/olingo-odata2/pull/2
> > > > 
> > > > Best,
> > > > 
> > > > Korbinian
> > > > 
> > > > 
> > > > ----- Ursprüngliche Mail -----
> > > >> Von: "Michael Bolz" <mi...@sap.com>
> > > >> An: user@olingo.apache.org
> > > >> CC: "korbinian bachl" <ko...@whiskyworld.de>
> > > >> Gesendet: Donnerstag, 26. Februar 2015 08:56:45
> > > >> Betreff: Re: olingo JPA / JTA - wrong transactions used
> > > >> 
> > > >> Hello Korbinian,
> > > >> 
> > > >> I would prefer to add this just at “ODataJPAServiceFactory”.
> > > >> First this way it is consistent with the “setODataTransactionContext”
> > > >> and
> > > >> second the callback is only related to database (JTA) dependent
> > > >> (using)
> > > >> OData services.
> > > >> @Korbinian and Chandan: I think (hope) you both agree with my opinion
> > > >> ;o)
> > > >> 
> > > >> When you send me the pull request I will check it and afterwards merge
> > > >> into
> > > >> Olingo master.
> > > >> 
> > > >> Kind regards,
> > > >> Michael
> > > >> 
> > > >>> On 25 Feb 2015, at 12:17, Korbinian Bachl
> > > >>> <ko...@whiskyworld.de>
> > > >>> wrote:
> > > >>> 
> > > >>> Hello Michael,
> > > >>> 
> > > >>> I've looked at the suggested OnJPAWriteContent-approach and this
> > > >>> would
> > > >>> work. Question is just if the callback should be implemented within
> > > >>> ODataServiceFactory or just within ODataJPAServiceFactory;
> > > >>> 
> > > >>> Either way we would need one (1) interface
> > > >>> 
> > > >>> public interface ODataTransactionContext extends ODataCallback {
> > > >>> 
> > > >>> public void startTransaction();
> > > >>> 
> > > >>> public void commitTransaction();
> > > >>> 
> > > >>> public void rollbackTransaction();
> > > >>> 
> > > >>> public boolean transactionIsActive();
> > > >>> 
> > > >>> }
> > > >>> 
> > > >>> as well as 1 class that implements the current default;
> > > >>> 
> > > >>> it would be put into the Factory class like
> > > >>> 
> > > >>> protected void setODataTransactionContext(final
> > > >>> ODataTransactionContext
> > > >>> oDataTransactionContext) {
> > > >>>   this.oDataTransactionContext = oDataTransactionContext;
> > > >>> }
> > > >>> 
> > > >>> and any access to transactions would then need to run via
> > > >>> getTransactionContext() e.g.:
> > > >>> 
> > > >>> FactoryClassInstace.getTransactionContext().startTransaction();
> > > >>> 
> > > >>> (or if you want the more noisy version:
> > > >>> FactoryClassInstace.getCallback(ODataTransactionContext.class).startTransaction();
> > > >>> - something I really dont like as this calling stack of
> > > >>> if(callbackInterface.isAssignableFrom... ) is something I see waste
> > > >>> of
> > > >>> CPU
> > > >>> cycles in regular and often called code areas, bad habbit IMHO)
> > > >>> 
> > > >>> 
> > > >>> Any other usages like JTA can then override the
> > > >>> setODataTransactionContext(...) and supply a class that "does"
> > > >>> exactly
> > > >>> what needed.
> > > >>> 
> > > >>> 
> > > >>> If this is the way to go, then just let me know which "way" you want
> > > >>> it
> > > >>> and
> > > >>> I can send you a pull request for it (on github);
> > > >>> 
> > > >>> 
> > > >>> 
> > > >>> Best,
> > > >>> 
> > > >>> Korbinian
> > > >>> 
> > > >>> ----- Ursprüngliche Mail -----
> > > >>>> Von: "Michael Bolz" <mi...@sap.com>
> > > >>>> An: user@olingo.apache.org
> > > >>>> Gesendet: Montag, 23. Februar 2015 11:03:40
> > > >>>> Betreff: Re: olingo JPA / JTA - wrong transactions used
> > > >>>> 
> > > >>>> Hi,
> > > >>>> 
> > > >>>> could a solution with the “Callback” approach (like the
> > > >>>> “OnJPAWriteContent”)
> > > >>>> work for this?
> > > >>>> So that the “ODataTransactionContext” is implemented as
> > > >>>> “ODataTransactionCallback”?
> > > >>>> 
> > > >>>> This way in the “ODataJPAServiceFactory” a method like: "protected
> > > >>>> void
> > > >>>> setTransactionCallback(final ODataTransactionCallback callback)” can
> > > >>>> be
> > > >>>> provided and
> > > >>>> if someone want to implement (inherit) his own “ODataServiceFactory”
> > > >>>> he
> > > >>>> can
> > > >>>> support the callback (interface) directly via the “getCallback(…)”
> > > >>>> method.
> > > >>>> 
> > > >>>> Kind regards,
> > > >>>> Michael
> > > >>>> 
> > > >>>> 
> > > >>>>> On 23 Feb 2015, at 10:17, Korbinian Bachl
> > > >>>>> <ko...@whiskyworld.de>
> > > >>>>> wrote:
> > > >>>>> 
> > > >>>>> Hello Chandan,
> > > >>>>> 
> > > >>>>> I've looked into the ODataServiceFactory and its usages and I
> > > >>>>> really
> > > >>>>> dont
> > > >>>>> think this is good. Problems are
> > > >>>>> 
> > > >>>>> a, ODataServiceFactory is in lib module - so no external dependency
> > > >>>>> should
> > > >>>>> be pulled into
> > > >>>>> b, just extending the class like I suggested wont work as we would
> > > >>>>> have
> > > >>>>> to
> > > >>>>> fix over 13 implementations of this Factory as well - not speaking
> > > >>>>> about
> > > >>>>> any custom implementations so far;
> > > >>>>> c, I currently dont see the "need" to have JTA outside of JPA
> > > >>>>> context
> > > >>>>> -
> > > >>>>> since no one ever asked for it;
> > > >>>>> 
> > > >>>>> What I can think of is a CustomTransaction class object that gets
> > > >>>>> its
> > > >>>>> "hold" within ODataServiceFactory and needs to be setup by the
> > > >>>>> implementation of the ODataServiceFactory only if it needs to use
> > > >>>>> it.
> > > >>>>> Something like e.g.:
> > > >>>>> 
> > > >>>>> in ODataServiceFactory:
> > > >>>>> ----------
> > > >>>>> private ODataTransactionContext = null;
> > > >>>>> 
> > > >>>>> //stub - needs to be implemented if want to be used
> > > >>>>> public void setUpTransactionContext() {};
> > > >>>>> 
> > > >>>>> public getODataTransactionContext() {
> > > >>>>>     return ODataTransactionContext;
> > > >>>>> }
> > > >>>>> 
> > > >>>>> public setODataTransactionContext(ODataTransactionContext ctx)
> > > >>>>> {...}
> > > >>>>> 
> > > >>>>> ---------
> > > >>>>> 
> > > >>>>> 
> > > >>>>> and ODataTransactionContext could be some kind of abstract class
> > > >>>>> that
> > > >>>>> has
> > > >>>>> the methods
> > > >>>>> 
> > > >>>>> public abstract class ODataTransactionContext {
> > > >>>>> 
> > > >>>>> public abstract void commitTransaction();
> > > >>>>> 
> > > >>>>> public abstract void startTransaction();
> > > >>>>> 
> > > >>>>> public abstract void rollbackTransaction();
> > > >>>>> 
> > > >>>>> public abstract boolean transactionIsActive();
> > > >>>>> 
> > > >>>>> }
> > > >>>>> 
> > > >>>>> -------
> > > >>>>> 
> > > >>>>> IMHO looks ugly; But using an interface for this would be even more
> > > >>>>> ugly....
> > > >>>>> 
> > > >>>>> 
> > > >>>>> Best,
> > > >>>>> 
> > > >>>>> Korbinian
> > > >>>>> 
> > > >>>>> 
> > > >>>>> ----- Ursprüngliche Mail -----
> > > >>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > > >>>>>> An: user@olingo.apache.org
> > > >>>>>> Gesendet: Donnerstag, 19. Februar 2015 08:07:59
> > > >>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > > >>>>>> 
> > > >>>>>> Hello Korbinian,
> > > >>>>>> I could have kept the methods as part of ODataJPAServiceFactory
> > > >>>>>> but
> > > >>>>>> the
> > > >>>>>> problem is, extending the ODataJPAServiceFactory class for an
> > > >>>>>> application
> > > >>>>>> is
> > > >>>>>> optional. Applications can create their own factory classes by
> > > >>>>>> directly
> > > >>>>>> inheriting ODataServiceFactory. We need to support such
> > > >>>>>> applications
> > > >>>>>> as
> > > >>>>>> well. I have created the JIRA issue
> > > >>>>>> https://issues.apache.org/jira/browse/OLINGO-580 to implement
> > > >>>>>> support
> > > >>>>>> for
> > > >>>>>> JTA based transactions.
> > > >>>>>> 
> > > >>>>>> Thanks
> > > >>>>>> Kind Regards
> > > >>>>>> Chandan
> > > >>>>>> 
> > > >>>>>> -----Original Message-----
> > > >>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > >>>>>> Sent: Wednesday, February 18, 2015 7:30 PM
> > > >>>>>> To: user@olingo.apache.org
> > > >>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> > > >>>>>> 
> > > >>>>>> Hello Chandan,
> > > >>>>>> 
> > > >>>>>> sounds good. What I would do - based upon your idea - is to extend
> > > >>>>>> the
> > > >>>>>> ODataJPAServiceFactory with 4 methods (as this one has to be used
> > > >>>>>> in
> > > >>>>>> any
> > > >>>>>> case):
> > > >>>>>> 
> > > >>>>>> public static void startTransaction(EntityManager em, Object
> > > >>>>>> transaction)
> > > >>>>>> {
> > > >>>>>>  em.getTransaction().begin();
> > > >>>>>>  transaction = em.getTransaction();
> > > >>>>>> }
> > > >>>>>> 
> > > >>>>>> public static void commitTransaction(Object transaction) {
> > > >>>>>>  ((EntitiyTransaction) transaction).commit();
> > > >>>>>> }
> > > >>>>>> 
> > > >>>>>> public static void rollbackTransaction(Object transaction) {
> > > >>>>>>  ((EntitiyTransaction) transaction).rollback();
> > > >>>>>> }
> > > >>>>>> 
> > > >>>>>> public static boolean transactionIsActive(Object transaction) {
> > > >>>>>> return ((EntitiyTransaction) transaction).isActive();
> > > >>>>>> }
> > > >>>>>> 
> > > >>>>>> These then would be called from wherever olingo JPA needs them.
> > > >>>>>> 
> > > >>>>>> That way any one needing JTA can override these methods while the
> > > >>>>>> rest
> > > >>>>>> won't
> > > >>>>>> even notice them...
> > > >>>>>> 
> > > >>>>>> 
> > > >>>>>> What do you think?
> > > >>>>>> 
> > > >>>>>> Best,
> > > >>>>>> 
> > > >>>>>> Korbinian
> > > >>>>>> 
> > > >>>>>> 
> > > >>>>>> 
> > > >>>>>> 
> > > >>>>>> 
> > > >>>>>> ----- Ursprüngliche Mail -----
> > > >>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > > >>>>>>> An: user@olingo.apache.org
> > > >>>>>>> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
> > > >>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > > >>>>>>> 
> > > >>>>>>> Hello Korbinian,
> > > >>>>>>> I would at least keep the application managed transactions (like
> > > >>>>>>> JTA)
> > > >>>>>>> outside
> > > >>>>>>> the context of JPA Processor for following reasons
> > > >>>>>>> 1) Wiring the JTA transactions into JPA processor could make the
> > > >>>>>>> processor
> > > >>>>>>> to
> > > >>>>>>> behave more like a framework than as a library (which is the
> > > >>>>>>> current
> > > >>>>>>> state).
> > > >>>>>>> 2) JPA processor also need to take JNDI lookup as parameter from
> > > >>>>>>> applications
> > > >>>>>>> for looking up the datasource.
> > > >>>>>>> 3) Olingo JPA processor should take care of just data
> > > >>>>>>> transformations
> > > >>>>>>> and
> > > >>>>>>> need not worry about the scope of transactions
> > > >>>>>>> 4) Olingo JPA processor should not take dependency to J2EE api
> > > >>>>>>> because
> > > >>>>>>> I
> > > >>>>>>> am
> > > >>>>>>> not sure will this artifact work in OSGI environments
> > > >>>>>>> 
> > > >>>>>>> One proposal from my side would be to provide a callback
> > > >>>>>>> mechanism
> > > >>>>>>> for
> > > >>>>>>> transaction handling, where the library just calls a method in
> > > >>>>>>> the
> > > >>>>>>> interface
> > > >>>>>>> to begin the transaction and end the transaction. If no one
> > > >>>>>>> implements
> > > >>>>>>> the
> > > >>>>>>> callback mechanism the library would resort to "RESOURCE_LOCAL"
> > > >>>>>>> based
> > > >>>>>>> transaction handling. With this approach applications will have a
> > > >>>>>>> greater
> > > >>>>>>> control over transaction handling and also need not rewrite
> > > >>>>>>> JPAProcessorImpl
> > > >>>>>>> or extend ODataJPAProcessor.
> > > >>>>>>> 
> > > >>>>>>> What do you think? Do you foresee any shortcomings with this
> > > >>>>>>> approach?
> > > >>>>>>> 
> > > >>>>>>> Thanks
> > > >>>>>>> Kind Regards
> > > >>>>>>> Chandan
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> -----Original Message-----
> > > >>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > >>>>>>> Sent: Wednesday, February 18, 2015 6:22 PM
> > > >>>>>>> To: user@olingo.apache.org
> > > >>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> > > >>>>>>> 
> > > >>>>>>> Hello Chandan,
> > > >>>>>>> 
> > > >>>>>>> I finally had some success in using JTA based transactions.
> > > >>>>>>> However,
> > > >>>>>>> this
> > > >>>>>>> only worked when I cloned the current git and changed it in the
> > > >>>>>>> JPAProcessorImpl directly; If I try to do this from within my
> > > >>>>>>> project
> > > >>>>>>> onto
> > > >>>>>>> the intialization with
> > > >>>>>>> 
> > > >>>>>>> oDatJPAContext.setODataProcessor(new
> > > >>>>>>> ODataJPAProcessorJTA(oDatJPAContext));
> > > >>>>>>> 
> > > >>>>>>> I then have to do a ODataJPAProcessorJTA which is 99% copy n
> > > >>>>>>> paste
> > > >>>>>>> from
> > > >>>>>>> ODataJPAProcessor and then also need a 95% copy n paste
> > > >>>>>>> JPAProcessorImplJTA
> > > >>>>>>> from JPAProcessorImpl;
> > > >>>>>>> 
> > > >>>>>>> As if this isn't ugly enough, it gets real dirty when trying to
> > > >>>>>>> use
> > > >>>>>>> it
> > > >>>>>>> as
> > > >>>>>>> you
> > > >>>>>>> simply cant force olingo to use it! Problem is that it comes from
> > > >>>>>>> the
> > > >>>>>>> JPAAccessFactoryImpl class static; is a static one and sits in
> > > >>>>>>> ODataJPAFactoryImpl and finally this one gets called in public
> > > >>>>>>> abstract
> > > >>>>>>> class ODataJPAFactory
> > > >>>>>>> 
> > > >>>>>>> using
> > > >>>>>>> 
> > > >>>>>>> public static ODataJPAFactory createFactory() {
> > > >>>>>>> 
> > > >>>>>>>  if (factoryImpl != null) {
> > > >>>>>>>    return factoryImpl;
> > > >>>>>>>  } else {
> > > >>>>>>>    try {
> > > >>>>>>>      Class<?> clazz =
> > > >>>>>>>      Class.forName(ODataJPAFactory.IMPLEMENTATION);
> > > >>>>>>> 
> > > >>>>>>>      Object object = clazz.newInstance();
> > > >>>>>>>      factoryImpl = (ODataJPAFactory) object;
> > > >>>>>>> 
> > > >>>>>>>    } catch (Exception e) {
> > > >>>>>>>      throw new RuntimeException(e);
> > > >>>>>>>    }
> > > >>>>>>> 
> > > >>>>>>>    return factoryImpl;
> > > >>>>>>>  }
> > > >>>>>>> }
> > > >>>>>>> 
> > > >>>>>>> where private static final String IMPLEMENTATION =
> > > >>>>>>>    "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> Simple said - overriding this logic in the olingo project is next
> > > >>>>>>> to
> > > >>>>>>> impossible as you would end up with nearly the whole project
> > > >>>>>>> copy'n'pasted
> > > >>>>>>> over; Simple changing the e.g.  resolver etc. wont works as there
> > > >>>>>>> are
> > > >>>>>>> many
> > > >>>>>>> usages of the ODataJPAFactory createFactory() method;
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> Implementing JTA to work in olingo on the other hand is quite
> > > >>>>>>> easy.
> > > >>>>>>> You
> > > >>>>>>> can
> > > >>>>>>> check on the fly if your JTA or not via e.g.:
> > > >>>>>>> 
> > > >>>>>>> public static boolean isResourceLocal(EntityManager em) {
> > > >>>>>>>      try {
> > > >>>>>>>          EntityTransaction tx = em.getTransaction();
> > > >>>>>>>          return true;
> > > >>>>>>>      } catch (IllegalStateException ex) {
> > > >>>>>>>          return false;
> > > >>>>>>>      }
> > > >>>>>>>  }
> > > >>>>>>> 
> > > >>>>>>> and this one can then set into a boolean var classwide in the
> > > >>>>>>> JPAProcessorImpl; so the setTransaction would become:
> > > >>>>>>> 
> > > >>>>>>> private boolean setTransaction() {
> > > >>>>>>>    if(isLocalTX) {
> > > >>>>>>>        final EntityTransaction transaction = em.getTransaction();
> > > >>>>>>>        if (!transaction.isActive()) {
> > > >>>>>>>            em.getTransaction().begin();
> > > >>>>>>>            return true;
> > > >>>>>>>        }
> > > >>>>>>>    } else {
> > > >>>>>>>        try {
> > > >>>>>>>            transaction = (UserTransaction) new
> > > >>>>>>>            InitialContext().lookup("java:comp/UserTransaction");
> > > >>>>>>>            transaction.begin();
> > > >>>>>>>        } catch (NamingException e) {
> > > >>>>>>>            e.printStackTrace();
> > > >>>>>>>        } catch (NotSupportedException e) {
> > > >>>>>>>            e.printStackTrace();
> > > >>>>>>>        } catch (SystemException e) {
> > > >>>>>>>            e.printStackTrace();
> > > >>>>>>>        }
> > > >>>>>>>    }
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>>  return false;
> > > >>>>>>> }
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> and this would work on all JTA bases Servers. The rest of the
> > > >>>>>>> transaction
> > > >>>>>>> logic would simply look like e.g.:
> > > >>>>>>> 
> > > >>>>>>> if (isLocalTransaction) {
> > > >>>>>>>      em.getTransaction().commit();
> > > >>>>>>>    }
> > > >>>>>>> if(transaction != null) {
> > > >>>>>>>          transaction.commit();
> > > >>>>>>>    }
> > > >>>>>>> Or even
> > > >>>>>>> if (isLocalTransaction) {
> > > >>>>>>>      em.getTransaction().commit();
> > > >>>>>>>    }
> > > >>>>>>> else {
> > > >>>>>>>          transaction.commit();
> > > >>>>>>>    }
> > > >>>>>>> in case we expect a 100% availbilty of transactional context;
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> Problem is now that this needs at least the dependency of
> > > >>>>>>>      <dependency>
> > > >>>>>>>          <groupId>javax</groupId>
> > > >>>>>>>          <artifactId>javaee-api</artifactId>
> > > >>>>>>>          <version>6.0</version>
> > > >>>>>>>      </dependency>
> > > >>>>>>> as else there is no UserTransaction class available; Would this
> > > >>>>>>> dependency
> > > >>>>>>> be
> > > >>>>>>> ok for the JPA part of the olingo project?
> > > >>>>>>> 
> > > >>>>>>> What do you think?
> > > >>>>>>> 
> > > >>>>>>> Best,
> > > >>>>>>> 
> > > >>>>>>> Korbinian
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> ----- Ursprüngliche Mail -----
> > > >>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > > >>>>>>>> An: user@olingo.apache.org
> > > >>>>>>>> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
> > > >>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > > >>>>>>>> 
> > > >>>>>>>> Hello Korbinian,
> > > >>>>>>>> Please check the JIRA item -
> > > >>>>>>>> https://issues.apache.org/jira/browse/OLINGO-549
> > > >>>>>>>> for updates on Olingo V4 JPA processor. Current status is there
> > > >>>>>>>> is
> > > >>>>>>>> no
> > > >>>>>>>> support for V4 JPA processor and the development is in progress.
> > > >>>>>>>> 
> > > >>>>>>>> Thanks
> > > >>>>>>>> Kind Regards
> > > >>>>>>>> Chandan
> > > >>>>>>>> 
> > > >>>>>>>> -----Original Message-----
> > > >>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > >>>>>>>> Sent: Wednesday, February 18, 2015 2:48 PM
> > > >>>>>>>> To: user@olingo.apache.org
> > > >>>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> > > >>>>>>>> 
> > > >>>>>>>> Hello Chandan,
> > > >>>>>>>> 
> > > >>>>>>>> thank you for the info. Will try this. I've seen that Olingo
> > > >>>>>>>> also
> > > >>>>>>>> has
> > > >>>>>>>> a
> > > >>>>>>>> OData
> > > >>>>>>>> V4 in Beta2 - but I couldn't really find information about its
> > > >>>>>>>> "readyness".
> > > >>>>>>>> Would it work in a simple CRUD scenario with JPA? Reason is as
> > > >>>>>>>> it
> > > >>>>>>>> seems
> > > >>>>>>>> as
> > > >>>>>>>> my other system I talk to via OData is moving from V3 to V4
> > > >>>>>>>> currently,
> > > >>>>>>>> at
> > > >>>>>>>> least the doc of its alredy speaks of OData V4 ready.
> > > >>>>>>>> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
> > > >>>>>>>> 
> > > >>>>>>>> Best,
> > > >>>>>>>> 
> > > >>>>>>>> Korbinian
> > > >>>>>>>> 
> > > >>>>>>>> 
> > > >>>>>>>> 
> > > >>>>>>>> ----- Ursprüngliche Mail -----
> > > >>>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > > >>>>>>>>> An: user@olingo.apache.org
> > > >>>>>>>>> Gesendet: Dienstag, 17. Februar 2015 07:11:28
> > > >>>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > > >>>>>>>>> 
> > > >>>>>>>>> Hello Korbinian,
> > > >>>>>>>>> You can extend the
> > > >>>>>>>>> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor
> > > >>>>>>>>> and
> > > >>>>>>>>> implement
> > > >>>>>>>>> the processor methods as it is done in
> > > >>>>>>>>> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.
> > > >>>>>>>>> In
> > > >>>>>>>>> your implementation for Create, Update and Delete you could
> > > >>>>>>>>> begin
> > > >>>>>>>>> the
> > > >>>>>>>>> JTA
> > > >>>>>>>>> transaction and close the transaction by either commit or
> > > >>>>>>>>> rollback.
> > > >>>>>>>>> 
> > > >>>>>>>>> I have not tried the scenario with JTA based transactions but
> > > >>>>>>>>> only
> > > >>>>>>>>> Resource
> > > >>>>>>>>> Local based transactions. Please check and tell if the above
> > > >>>>>>>>> solution
> > > >>>>>>>>> works
> > > >>>>>>>>> for your case. Else raise a JIRA feature request to support JTA
> > > >>>>>>>>> based
> > > >>>>>>>>> transactions.
> > > >>>>>>>>> 
> > > >>>>>>>>> Regards
> > > >>>>>>>>> Chandan
> > > >>>>>>>>> 
> > > >>>>>>>>> -----Original Message-----
> > > >>>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > >>>>>>>>> Sent: Monday, February 16, 2015 2:16 PM
> > > >>>>>>>>> To: user@olingo.apache.org
> > > >>>>>>>>> Subject: olingo JPA / JTA - wrong transactions used
> > > >>>>>>>>> 
> > > >>>>>>>>> Hi,
> > > >>>>>>>>> 
> > > >>>>>>>>> I'm using Olingo 2.0.2 and I can query all items so far. When I
> > > >>>>>>>>> want
> > > >>>>>>>>> to
> > > >>>>>>>>> update content, I get error:
> > > >>>>>>>>> 
> > > >>>>>>>>> ...
> > > >>>>>>>>> <message xml:lang="en">"OData - JPA Runtime: JPA update request
> > > >>>>>>>>> is
> > > >>>>>>>>> not
> > > >>>>>>>>> correct"message>
> > > >>>>>>>>>  <innererror>class java.lang.IllegalStateException :
> > > >>>>>>>>> Exception Description: Cannot use an EntityTransaction while
> > > >>>>>>>>> using
> > > >>>>>>>>> JTA.innererror>
> > > >>>>>>>>> ....
> > > >>>>>>>>> 
> > > >>>>>>>>> Digging deeper into the code, I ended up in file
> > > >>>>>>>>> ODataJPAContextImpl
> > > >>>>>>>>> 
> > > >>>>>>>>> and there in the function
> > > >>>>>>>>> 
> > > >>>>>>>>> private  Object processUpdate(PutMergePatchUriInfo updateView,
> > > >>>>>>>>>    final InputStream content, final Map<String, Object>
> > > >>>>>>>>>    properties,
> > > >>>>>>>>>    final
> > > >>>>>>>>>    String requestContentType)
> > > >>>>>>>>>    throws ODataJPAModelException, ODataJPARuntimeException {
> > > >>>>>>>>> ...
> > > >>>>>>>>> boolean isLocalTransaction = setTransaction();
> > > >>>>>>>>> 
> > > >>>>>>>>> ...
> > > >>>>>>>>> }
> > > >>>>>>>>> 
> > > >>>>>>>>> with
> > > >>>>>>>>> 
> > > >>>>>>>>> private boolean setTransaction() {
> > > >>>>>>>>>  final EntityTransaction transaction = em.getTransaction();
> > > >>>>>>>>>  if (!transaction.isActive()) {
> > > >>>>>>>>>    em.getTransaction().begin();
> > > >>>>>>>>>    return true;
> > > >>>>>>>>>  }
> > > >>>>>>>>> 
> > > >>>>>>>>>  return false;
> > > >>>>>>>>> }
> > > >>>>>>>>> 
> > > >>>>>>>>> 
> > > >>>>>>>>> So far I understood this one is the function that collides with
> > > >>>>>>>>> my
> > > >>>>>>>>> JTA
> > > >>>>>>>>> setup.
> > > >>>>>>>>> I now wonder how I can suppress to initialize this method?
> > > >>>>>>>>> 
> > > >>>>>>>>> I've sending in the right EntityManagerFactory into Olingo,
> > > >>>>>>>>> e.g.:
> > > >>>>>>>>> 
> > > >>>>>>>>> public class ConnectorODataJPAServiceFactory extends
> > > >>>>>>>>> ODataJPAServiceFactory
> > > >>>>>>>>> {
> > > >>>>>>>>> 
> > > >>>>>>>>>  private static final String PERSISTENCE_UNIT_NAME = "myPU";
> > > >>>>>>>>> 
> > > >>>>>>>>>  @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
> > > >>>>>>>>>  EntityManagerFactory emf;
> > > >>>>>>>>> 
> > > >>>>>>>>> 
> > > >>>>>>>>>  @Override
> > > >>>>>>>>>  public ODataJPAContext initializeODataJPAContext() throws
> > > >>>>>>>>>  ODataJPARuntimeException {
> > > >>>>>>>>>      ODataJPAContext oDatJPAContext =
> > > >>>>>>>>>      this.getODataJPAContext();
> > > >>>>>>>>> 
> > > >>>>>>>>>      try {
> > > >>>>>>>>>          CdiContainer.get().getNonContextualManager().postConstruct(this);
> > > >>>>>>>>>          oDatJPAContext.setEntityManagerFactory(emf);
> > > >>>>>>>>>          oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
> > > >>>>>>>>>          oDatJPAContext.setPageSize(100);
> > > >>>>>>>>>          setDetailErrors(true);
> > > >>>>>>>>>          return oDatJPAContext;
> > > >>>>>>>>>      } catch (Exception e) {
> > > >>>>>>>>>          System.out.print(e);
> > > >>>>>>>>>          throw new RuntimeException(e);
> > > >>>>>>>>>      }
> > > >>>>>>>>>  }
> > > >>>>>>>>> 
> > > >>>>>>>>> ...
> > > >>>>>>>>> 
> > > >>>>>>>>> So where is the catch here?
> > > >>>>>>>>> 
> > > >>>>>>>>> 
> > > >>>>>>>>> Best,
> > > >>>>>>>>> 
> > > >>>>>>>>> Korbinian
> > > >>>>>>>>> 
> > > >>>>>>>> 
> > > >>>>>>> 
> > > >>>>>> 
> > > >>>> 
> > > >>>> 
> > > >> 
> > > >> 
> > > 
> > > 
> > 
> 

Re: olingo JPA / JTA - wrong transactions used

Posted by Korbinian Bachl <ko...@whiskyworld.de>.
Hello Christian,

sounds resonable - however, neither browsers like google Chrome or Firefox nor software like SAP HANA works correctly without the additional UTF-8 in the header....

I stumbled over this as I had much garbage in my hana tables, after fixing the header all was fine;

Best,

Korbinian 



----- Ursprüngliche Mail -----
> Von: "Christian Amend" <ch...@sap.com>
> An: user@olingo.apache.org
> CC: "Korbinian Bachl" <ko...@whiskyworld.de>
> Gesendet: Donnerstag, 12. März 2015 13:11:31
> Betreff: RE: olingo JPA / JTA - wrong transactions used
> 
> Hi Korbinian,
> 
> the json specification defines UTF-8 as the default. Also the media type
> application/json doesn`t specify a charset parameter as registered here:
> http://www.iana.org/assignments/media-types/application/json
> 
> Quote: "Note:  No "charset" parameter is defined for this registration.
> Adding one really has no effect on compliant recipients."
> 
> So any client that requests the json format should not treat the payload
> based on an unspecified charset header. I would not like to encourage
> uncompliant clients to use the charset header by adding it as a default in
> the Olingo library.
> 
> Best Regards,
> Christian
> 
> -----Original Message-----
> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> Sent: Donnerstag, 12. März 2015 12:57
> To: user@olingo.apache.org
> Subject: Re: olingo JPA / JTA - wrong transactions used
> 
> Hi Chandan,
> 
> thanks for fixing this!
> 
> I think I hit another problem with olingo odata v2. If you e.g. do:
> 
> ...odata/Entites/?$top=10&$format=json
> 
> the returned data is correct. What is incorrect is the send out header. Via
> the JSON impl. the data is send using UTF-8 encoding, while the header is
> stated solely as:
> Content-Type: application/json;
> 
> which then leads to incorrect pickup by clients as they chose any encoding
> they like or think it might be encoding xxx - leading to various problems
> with special chars.
> 
> The fix is as simple as correcting the header to:
> 
> Content-Type: application/json;charset=utf-8;
> 
> I did this using an filter wrapper around the response, yet IMHO this should
> be fixed inside olingo;
> 
> 
> 
> Best,
> 
> Korbinian
> 
> 
> ----- Ursprüngliche Mail -----
> > Von: "Chandan V.A" <ch...@sap.com>
> > An: user@olingo.apache.org
> > Gesendet: Donnerstag, 12. März 2015 09:53:06
> > Betreff: RE: olingo JPA / JTA - wrong transactions used
> > 
> > Hi All,
> > The support for JTA is implemented by pulling the code from
> > https://github.com/apache/olingo-odata2/pull/2 and applying some
> > adjustments
> > to the code line to be backward compatible. The changes are part of
> > 2.0.4-SNAPSHOT version.
> > 
> > Refer issue - https://issues.apache.org/jira/browse/OLINGO-580 for more
> > details that includes on how to use this feature. In case of bugs feel free
> > to reopen the issue.
> > 
> > Regards
> > Chandan
> > 
> > -----Original Message-----
> > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > Sent: Thursday, February 26, 2015 5:43 PM
> > To: user@olingo.apache.org
> > Subject: Re: olingo JPA / JTA - wrong transactions used
> > 
> > everything in: https://github.com/apache/olingo-odata2/pull/2
> > 
> > Now, when will Chandan do the JPA for olingo OData V4? ;)
> > 
> > 
> > 
> > Best,
> > 
> > Korbinian
> > 
> > ----- Ursprüngliche Mail -----
> > > Von: "Michael Bolz" <mi...@sap.com>
> > > An: "Chandan V.A" <ch...@sap.com>
> > > CC: user@olingo.apache.org
> > > Gesendet: Donnerstag, 26. Februar 2015 12:59:46
> > > Betreff: Re: olingo JPA / JTA - wrong transactions used
> > > 
> > > Hello all,
> > > 
> > > after a first look I agree with the suggestion from Chandan.
> > > So from my side a +1 for a minor rename ;o)
> > > 
> > > Kind regards,
> > > Michael
> > > 
> > > > On 26 Feb 2015, at 12:11, V.A, Chandan <ch...@sap.com> wrote:
> > > > 
> > > > Hello Korbinian,
> > > > I did a quick review of the code and at first sight looks fine. I have
> > > > few
> > > > comments with respect to the name. I feel ODataJPATransaction will be
> > > > more
> > > > appropriate than ODataJPATransactionContext. Because we are executing
> > > > transaction steps using this interface and not just setting and getting
> > > > values.
> > > > WDYT?
> > > > 
> > > > Proposal
> > > > public interface ODataJPATransaction {
> > > > 	void begin();
> > > > 	void rollback();
> > > > 	void commit();
> > > > 	void isActive();
> > > > }
> > > > 
> > > > The class name for default implementation can be
> > > > ODataJPATransactionLocalDefault.
> > > > 
> > > > Thanks
> > > > Kind Regards
> > > > Chandan
> > > > 
> > > > -----Original Message-----
> > > > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > > Sent: Thursday, February 26, 2015 4:09 PM
> > > > To: user@olingo.apache.org; Bolz, Michael
> > > > Subject: Re: olingo JPA / JTA - wrong transactions used
> > > > 
> > > > Here you go: https://github.com/apache/olingo-odata2/pull/2
> > > > 
> > > > Best,
> > > > 
> > > > Korbinian
> > > > 
> > > > 
> > > > ----- Ursprüngliche Mail -----
> > > >> Von: "Michael Bolz" <mi...@sap.com>
> > > >> An: user@olingo.apache.org
> > > >> CC: "korbinian bachl" <ko...@whiskyworld.de>
> > > >> Gesendet: Donnerstag, 26. Februar 2015 08:56:45
> > > >> Betreff: Re: olingo JPA / JTA - wrong transactions used
> > > >> 
> > > >> Hello Korbinian,
> > > >> 
> > > >> I would prefer to add this just at “ODataJPAServiceFactory”.
> > > >> First this way it is consistent with the “setODataTransactionContext”
> > > >> and
> > > >> second the callback is only related to database (JTA) dependent
> > > >> (using)
> > > >> OData services.
> > > >> @Korbinian and Chandan: I think (hope) you both agree with my opinion
> > > >> ;o)
> > > >> 
> > > >> When you send me the pull request I will check it and afterwards merge
> > > >> into
> > > >> Olingo master.
> > > >> 
> > > >> Kind regards,
> > > >> Michael
> > > >> 
> > > >>> On 25 Feb 2015, at 12:17, Korbinian Bachl
> > > >>> <ko...@whiskyworld.de>
> > > >>> wrote:
> > > >>> 
> > > >>> Hello Michael,
> > > >>> 
> > > >>> I've looked at the suggested OnJPAWriteContent-approach and this
> > > >>> would
> > > >>> work. Question is just if the callback should be implemented within
> > > >>> ODataServiceFactory or just within ODataJPAServiceFactory;
> > > >>> 
> > > >>> Either way we would need one (1) interface
> > > >>> 
> > > >>> public interface ODataTransactionContext extends ODataCallback {
> > > >>> 
> > > >>> public void startTransaction();
> > > >>> 
> > > >>> public void commitTransaction();
> > > >>> 
> > > >>> public void rollbackTransaction();
> > > >>> 
> > > >>> public boolean transactionIsActive();
> > > >>> 
> > > >>> }
> > > >>> 
> > > >>> as well as 1 class that implements the current default;
> > > >>> 
> > > >>> it would be put into the Factory class like
> > > >>> 
> > > >>> protected void setODataTransactionContext(final
> > > >>> ODataTransactionContext
> > > >>> oDataTransactionContext) {
> > > >>>   this.oDataTransactionContext = oDataTransactionContext;
> > > >>> }
> > > >>> 
> > > >>> and any access to transactions would then need to run via
> > > >>> getTransactionContext() e.g.:
> > > >>> 
> > > >>> FactoryClassInstace.getTransactionContext().startTransaction();
> > > >>> 
> > > >>> (or if you want the more noisy version:
> > > >>> FactoryClassInstace.getCallback(ODataTransactionContext.class).startTransaction();
> > > >>> - something I really dont like as this calling stack of
> > > >>> if(callbackInterface.isAssignableFrom... ) is something I see waste
> > > >>> of
> > > >>> CPU
> > > >>> cycles in regular and often called code areas, bad habbit IMHO)
> > > >>> 
> > > >>> 
> > > >>> Any other usages like JTA can then override the
> > > >>> setODataTransactionContext(...) and supply a class that "does"
> > > >>> exactly
> > > >>> what needed.
> > > >>> 
> > > >>> 
> > > >>> If this is the way to go, then just let me know which "way" you want
> > > >>> it
> > > >>> and
> > > >>> I can send you a pull request for it (on github);
> > > >>> 
> > > >>> 
> > > >>> 
> > > >>> Best,
> > > >>> 
> > > >>> Korbinian
> > > >>> 
> > > >>> ----- Ursprüngliche Mail -----
> > > >>>> Von: "Michael Bolz" <mi...@sap.com>
> > > >>>> An: user@olingo.apache.org
> > > >>>> Gesendet: Montag, 23. Februar 2015 11:03:40
> > > >>>> Betreff: Re: olingo JPA / JTA - wrong transactions used
> > > >>>> 
> > > >>>> Hi,
> > > >>>> 
> > > >>>> could a solution with the “Callback” approach (like the
> > > >>>> “OnJPAWriteContent”)
> > > >>>> work for this?
> > > >>>> So that the “ODataTransactionContext” is implemented as
> > > >>>> “ODataTransactionCallback”?
> > > >>>> 
> > > >>>> This way in the “ODataJPAServiceFactory” a method like: "protected
> > > >>>> void
> > > >>>> setTransactionCallback(final ODataTransactionCallback callback)” can
> > > >>>> be
> > > >>>> provided and
> > > >>>> if someone want to implement (inherit) his own “ODataServiceFactory”
> > > >>>> he
> > > >>>> can
> > > >>>> support the callback (interface) directly via the “getCallback(…)”
> > > >>>> method.
> > > >>>> 
> > > >>>> Kind regards,
> > > >>>> Michael
> > > >>>> 
> > > >>>> 
> > > >>>>> On 23 Feb 2015, at 10:17, Korbinian Bachl
> > > >>>>> <ko...@whiskyworld.de>
> > > >>>>> wrote:
> > > >>>>> 
> > > >>>>> Hello Chandan,
> > > >>>>> 
> > > >>>>> I've looked into the ODataServiceFactory and its usages and I
> > > >>>>> really
> > > >>>>> dont
> > > >>>>> think this is good. Problems are
> > > >>>>> 
> > > >>>>> a, ODataServiceFactory is in lib module - so no external dependency
> > > >>>>> should
> > > >>>>> be pulled into
> > > >>>>> b, just extending the class like I suggested wont work as we would
> > > >>>>> have
> > > >>>>> to
> > > >>>>> fix over 13 implementations of this Factory as well - not speaking
> > > >>>>> about
> > > >>>>> any custom implementations so far;
> > > >>>>> c, I currently dont see the "need" to have JTA outside of JPA
> > > >>>>> context
> > > >>>>> -
> > > >>>>> since no one ever asked for it;
> > > >>>>> 
> > > >>>>> What I can think of is a CustomTransaction class object that gets
> > > >>>>> its
> > > >>>>> "hold" within ODataServiceFactory and needs to be setup by the
> > > >>>>> implementation of the ODataServiceFactory only if it needs to use
> > > >>>>> it.
> > > >>>>> Something like e.g.:
> > > >>>>> 
> > > >>>>> in ODataServiceFactory:
> > > >>>>> ----------
> > > >>>>> private ODataTransactionContext = null;
> > > >>>>> 
> > > >>>>> //stub - needs to be implemented if want to be used
> > > >>>>> public void setUpTransactionContext() {};
> > > >>>>> 
> > > >>>>> public getODataTransactionContext() {
> > > >>>>>     return ODataTransactionContext;
> > > >>>>> }
> > > >>>>> 
> > > >>>>> public setODataTransactionContext(ODataTransactionContext ctx)
> > > >>>>> {...}
> > > >>>>> 
> > > >>>>> ---------
> > > >>>>> 
> > > >>>>> 
> > > >>>>> and ODataTransactionContext could be some kind of abstract class
> > > >>>>> that
> > > >>>>> has
> > > >>>>> the methods
> > > >>>>> 
> > > >>>>> public abstract class ODataTransactionContext {
> > > >>>>> 
> > > >>>>> public abstract void commitTransaction();
> > > >>>>> 
> > > >>>>> public abstract void startTransaction();
> > > >>>>> 
> > > >>>>> public abstract void rollbackTransaction();
> > > >>>>> 
> > > >>>>> public abstract boolean transactionIsActive();
> > > >>>>> 
> > > >>>>> }
> > > >>>>> 
> > > >>>>> -------
> > > >>>>> 
> > > >>>>> IMHO looks ugly; But using an interface for this would be even more
> > > >>>>> ugly....
> > > >>>>> 
> > > >>>>> 
> > > >>>>> Best,
> > > >>>>> 
> > > >>>>> Korbinian
> > > >>>>> 
> > > >>>>> 
> > > >>>>> ----- Ursprüngliche Mail -----
> > > >>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > > >>>>>> An: user@olingo.apache.org
> > > >>>>>> Gesendet: Donnerstag, 19. Februar 2015 08:07:59
> > > >>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > > >>>>>> 
> > > >>>>>> Hello Korbinian,
> > > >>>>>> I could have kept the methods as part of ODataJPAServiceFactory
> > > >>>>>> but
> > > >>>>>> the
> > > >>>>>> problem is, extending the ODataJPAServiceFactory class for an
> > > >>>>>> application
> > > >>>>>> is
> > > >>>>>> optional. Applications can create their own factory classes by
> > > >>>>>> directly
> > > >>>>>> inheriting ODataServiceFactory. We need to support such
> > > >>>>>> applications
> > > >>>>>> as
> > > >>>>>> well. I have created the JIRA issue
> > > >>>>>> https://issues.apache.org/jira/browse/OLINGO-580 to implement
> > > >>>>>> support
> > > >>>>>> for
> > > >>>>>> JTA based transactions.
> > > >>>>>> 
> > > >>>>>> Thanks
> > > >>>>>> Kind Regards
> > > >>>>>> Chandan
> > > >>>>>> 
> > > >>>>>> -----Original Message-----
> > > >>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > >>>>>> Sent: Wednesday, February 18, 2015 7:30 PM
> > > >>>>>> To: user@olingo.apache.org
> > > >>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> > > >>>>>> 
> > > >>>>>> Hello Chandan,
> > > >>>>>> 
> > > >>>>>> sounds good. What I would do - based upon your idea - is to extend
> > > >>>>>> the
> > > >>>>>> ODataJPAServiceFactory with 4 methods (as this one has to be used
> > > >>>>>> in
> > > >>>>>> any
> > > >>>>>> case):
> > > >>>>>> 
> > > >>>>>> public static void startTransaction(EntityManager em, Object
> > > >>>>>> transaction)
> > > >>>>>> {
> > > >>>>>>  em.getTransaction().begin();
> > > >>>>>>  transaction = em.getTransaction();
> > > >>>>>> }
> > > >>>>>> 
> > > >>>>>> public static void commitTransaction(Object transaction) {
> > > >>>>>>  ((EntitiyTransaction) transaction).commit();
> > > >>>>>> }
> > > >>>>>> 
> > > >>>>>> public static void rollbackTransaction(Object transaction) {
> > > >>>>>>  ((EntitiyTransaction) transaction).rollback();
> > > >>>>>> }
> > > >>>>>> 
> > > >>>>>> public static boolean transactionIsActive(Object transaction) {
> > > >>>>>> return ((EntitiyTransaction) transaction).isActive();
> > > >>>>>> }
> > > >>>>>> 
> > > >>>>>> These then would be called from wherever olingo JPA needs them.
> > > >>>>>> 
> > > >>>>>> That way any one needing JTA can override these methods while the
> > > >>>>>> rest
> > > >>>>>> won't
> > > >>>>>> even notice them...
> > > >>>>>> 
> > > >>>>>> 
> > > >>>>>> What do you think?
> > > >>>>>> 
> > > >>>>>> Best,
> > > >>>>>> 
> > > >>>>>> Korbinian
> > > >>>>>> 
> > > >>>>>> 
> > > >>>>>> 
> > > >>>>>> 
> > > >>>>>> 
> > > >>>>>> ----- Ursprüngliche Mail -----
> > > >>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > > >>>>>>> An: user@olingo.apache.org
> > > >>>>>>> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
> > > >>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > > >>>>>>> 
> > > >>>>>>> Hello Korbinian,
> > > >>>>>>> I would at least keep the application managed transactions (like
> > > >>>>>>> JTA)
> > > >>>>>>> outside
> > > >>>>>>> the context of JPA Processor for following reasons
> > > >>>>>>> 1) Wiring the JTA transactions into JPA processor could make the
> > > >>>>>>> processor
> > > >>>>>>> to
> > > >>>>>>> behave more like a framework than as a library (which is the
> > > >>>>>>> current
> > > >>>>>>> state).
> > > >>>>>>> 2) JPA processor also need to take JNDI lookup as parameter from
> > > >>>>>>> applications
> > > >>>>>>> for looking up the datasource.
> > > >>>>>>> 3) Olingo JPA processor should take care of just data
> > > >>>>>>> transformations
> > > >>>>>>> and
> > > >>>>>>> need not worry about the scope of transactions
> > > >>>>>>> 4) Olingo JPA processor should not take dependency to J2EE api
> > > >>>>>>> because
> > > >>>>>>> I
> > > >>>>>>> am
> > > >>>>>>> not sure will this artifact work in OSGI environments
> > > >>>>>>> 
> > > >>>>>>> One proposal from my side would be to provide a callback
> > > >>>>>>> mechanism
> > > >>>>>>> for
> > > >>>>>>> transaction handling, where the library just calls a method in
> > > >>>>>>> the
> > > >>>>>>> interface
> > > >>>>>>> to begin the transaction and end the transaction. If no one
> > > >>>>>>> implements
> > > >>>>>>> the
> > > >>>>>>> callback mechanism the library would resort to "RESOURCE_LOCAL"
> > > >>>>>>> based
> > > >>>>>>> transaction handling. With this approach applications will have a
> > > >>>>>>> greater
> > > >>>>>>> control over transaction handling and also need not rewrite
> > > >>>>>>> JPAProcessorImpl
> > > >>>>>>> or extend ODataJPAProcessor.
> > > >>>>>>> 
> > > >>>>>>> What do you think? Do you foresee any shortcomings with this
> > > >>>>>>> approach?
> > > >>>>>>> 
> > > >>>>>>> Thanks
> > > >>>>>>> Kind Regards
> > > >>>>>>> Chandan
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> -----Original Message-----
> > > >>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > >>>>>>> Sent: Wednesday, February 18, 2015 6:22 PM
> > > >>>>>>> To: user@olingo.apache.org
> > > >>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> > > >>>>>>> 
> > > >>>>>>> Hello Chandan,
> > > >>>>>>> 
> > > >>>>>>> I finally had some success in using JTA based transactions.
> > > >>>>>>> However,
> > > >>>>>>> this
> > > >>>>>>> only worked when I cloned the current git and changed it in the
> > > >>>>>>> JPAProcessorImpl directly; If I try to do this from within my
> > > >>>>>>> project
> > > >>>>>>> onto
> > > >>>>>>> the intialization with
> > > >>>>>>> 
> > > >>>>>>> oDatJPAContext.setODataProcessor(new
> > > >>>>>>> ODataJPAProcessorJTA(oDatJPAContext));
> > > >>>>>>> 
> > > >>>>>>> I then have to do a ODataJPAProcessorJTA which is 99% copy n
> > > >>>>>>> paste
> > > >>>>>>> from
> > > >>>>>>> ODataJPAProcessor and then also need a 95% copy n paste
> > > >>>>>>> JPAProcessorImplJTA
> > > >>>>>>> from JPAProcessorImpl;
> > > >>>>>>> 
> > > >>>>>>> As if this isn't ugly enough, it gets real dirty when trying to
> > > >>>>>>> use
> > > >>>>>>> it
> > > >>>>>>> as
> > > >>>>>>> you
> > > >>>>>>> simply cant force olingo to use it! Problem is that it comes from
> > > >>>>>>> the
> > > >>>>>>> JPAAccessFactoryImpl class static; is a static one and sits in
> > > >>>>>>> ODataJPAFactoryImpl and finally this one gets called in public
> > > >>>>>>> abstract
> > > >>>>>>> class ODataJPAFactory
> > > >>>>>>> 
> > > >>>>>>> using
> > > >>>>>>> 
> > > >>>>>>> public static ODataJPAFactory createFactory() {
> > > >>>>>>> 
> > > >>>>>>>  if (factoryImpl != null) {
> > > >>>>>>>    return factoryImpl;
> > > >>>>>>>  } else {
> > > >>>>>>>    try {
> > > >>>>>>>      Class<?> clazz =
> > > >>>>>>>      Class.forName(ODataJPAFactory.IMPLEMENTATION);
> > > >>>>>>> 
> > > >>>>>>>      Object object = clazz.newInstance();
> > > >>>>>>>      factoryImpl = (ODataJPAFactory) object;
> > > >>>>>>> 
> > > >>>>>>>    } catch (Exception e) {
> > > >>>>>>>      throw new RuntimeException(e);
> > > >>>>>>>    }
> > > >>>>>>> 
> > > >>>>>>>    return factoryImpl;
> > > >>>>>>>  }
> > > >>>>>>> }
> > > >>>>>>> 
> > > >>>>>>> where private static final String IMPLEMENTATION =
> > > >>>>>>>    "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> Simple said - overriding this logic in the olingo project is next
> > > >>>>>>> to
> > > >>>>>>> impossible as you would end up with nearly the whole project
> > > >>>>>>> copy'n'pasted
> > > >>>>>>> over; Simple changing the e.g.  resolver etc. wont works as there
> > > >>>>>>> are
> > > >>>>>>> many
> > > >>>>>>> usages of the ODataJPAFactory createFactory() method;
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> Implementing JTA to work in olingo on the other hand is quite
> > > >>>>>>> easy.
> > > >>>>>>> You
> > > >>>>>>> can
> > > >>>>>>> check on the fly if your JTA or not via e.g.:
> > > >>>>>>> 
> > > >>>>>>> public static boolean isResourceLocal(EntityManager em) {
> > > >>>>>>>      try {
> > > >>>>>>>          EntityTransaction tx = em.getTransaction();
> > > >>>>>>>          return true;
> > > >>>>>>>      } catch (IllegalStateException ex) {
> > > >>>>>>>          return false;
> > > >>>>>>>      }
> > > >>>>>>>  }
> > > >>>>>>> 
> > > >>>>>>> and this one can then set into a boolean var classwide in the
> > > >>>>>>> JPAProcessorImpl; so the setTransaction would become:
> > > >>>>>>> 
> > > >>>>>>> private boolean setTransaction() {
> > > >>>>>>>    if(isLocalTX) {
> > > >>>>>>>        final EntityTransaction transaction = em.getTransaction();
> > > >>>>>>>        if (!transaction.isActive()) {
> > > >>>>>>>            em.getTransaction().begin();
> > > >>>>>>>            return true;
> > > >>>>>>>        }
> > > >>>>>>>    } else {
> > > >>>>>>>        try {
> > > >>>>>>>            transaction = (UserTransaction) new
> > > >>>>>>>            InitialContext().lookup("java:comp/UserTransaction");
> > > >>>>>>>            transaction.begin();
> > > >>>>>>>        } catch (NamingException e) {
> > > >>>>>>>            e.printStackTrace();
> > > >>>>>>>        } catch (NotSupportedException e) {
> > > >>>>>>>            e.printStackTrace();
> > > >>>>>>>        } catch (SystemException e) {
> > > >>>>>>>            e.printStackTrace();
> > > >>>>>>>        }
> > > >>>>>>>    }
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>>  return false;
> > > >>>>>>> }
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> and this would work on all JTA bases Servers. The rest of the
> > > >>>>>>> transaction
> > > >>>>>>> logic would simply look like e.g.:
> > > >>>>>>> 
> > > >>>>>>> if (isLocalTransaction) {
> > > >>>>>>>      em.getTransaction().commit();
> > > >>>>>>>    }
> > > >>>>>>> if(transaction != null) {
> > > >>>>>>>          transaction.commit();
> > > >>>>>>>    }
> > > >>>>>>> Or even
> > > >>>>>>> if (isLocalTransaction) {
> > > >>>>>>>      em.getTransaction().commit();
> > > >>>>>>>    }
> > > >>>>>>> else {
> > > >>>>>>>          transaction.commit();
> > > >>>>>>>    }
> > > >>>>>>> in case we expect a 100% availbilty of transactional context;
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> Problem is now that this needs at least the dependency of
> > > >>>>>>>      <dependency>
> > > >>>>>>>          <groupId>javax</groupId>
> > > >>>>>>>          <artifactId>javaee-api</artifactId>
> > > >>>>>>>          <version>6.0</version>
> > > >>>>>>>      </dependency>
> > > >>>>>>> as else there is no UserTransaction class available; Would this
> > > >>>>>>> dependency
> > > >>>>>>> be
> > > >>>>>>> ok for the JPA part of the olingo project?
> > > >>>>>>> 
> > > >>>>>>> What do you think?
> > > >>>>>>> 
> > > >>>>>>> Best,
> > > >>>>>>> 
> > > >>>>>>> Korbinian
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> 
> > > >>>>>>> ----- Ursprüngliche Mail -----
> > > >>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > > >>>>>>>> An: user@olingo.apache.org
> > > >>>>>>>> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
> > > >>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > > >>>>>>>> 
> > > >>>>>>>> Hello Korbinian,
> > > >>>>>>>> Please check the JIRA item -
> > > >>>>>>>> https://issues.apache.org/jira/browse/OLINGO-549
> > > >>>>>>>> for updates on Olingo V4 JPA processor. Current status is there
> > > >>>>>>>> is
> > > >>>>>>>> no
> > > >>>>>>>> support for V4 JPA processor and the development is in progress.
> > > >>>>>>>> 
> > > >>>>>>>> Thanks
> > > >>>>>>>> Kind Regards
> > > >>>>>>>> Chandan
> > > >>>>>>>> 
> > > >>>>>>>> -----Original Message-----
> > > >>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > >>>>>>>> Sent: Wednesday, February 18, 2015 2:48 PM
> > > >>>>>>>> To: user@olingo.apache.org
> > > >>>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> > > >>>>>>>> 
> > > >>>>>>>> Hello Chandan,
> > > >>>>>>>> 
> > > >>>>>>>> thank you for the info. Will try this. I've seen that Olingo
> > > >>>>>>>> also
> > > >>>>>>>> has
> > > >>>>>>>> a
> > > >>>>>>>> OData
> > > >>>>>>>> V4 in Beta2 - but I couldn't really find information about its
> > > >>>>>>>> "readyness".
> > > >>>>>>>> Would it work in a simple CRUD scenario with JPA? Reason is as
> > > >>>>>>>> it
> > > >>>>>>>> seems
> > > >>>>>>>> as
> > > >>>>>>>> my other system I talk to via OData is moving from V3 to V4
> > > >>>>>>>> currently,
> > > >>>>>>>> at
> > > >>>>>>>> least the doc of its alredy speaks of OData V4 ready.
> > > >>>>>>>> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
> > > >>>>>>>> 
> > > >>>>>>>> Best,
> > > >>>>>>>> 
> > > >>>>>>>> Korbinian
> > > >>>>>>>> 
> > > >>>>>>>> 
> > > >>>>>>>> 
> > > >>>>>>>> ----- Ursprüngliche Mail -----
> > > >>>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > > >>>>>>>>> An: user@olingo.apache.org
> > > >>>>>>>>> Gesendet: Dienstag, 17. Februar 2015 07:11:28
> > > >>>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > > >>>>>>>>> 
> > > >>>>>>>>> Hello Korbinian,
> > > >>>>>>>>> You can extend the
> > > >>>>>>>>> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor
> > > >>>>>>>>> and
> > > >>>>>>>>> implement
> > > >>>>>>>>> the processor methods as it is done in
> > > >>>>>>>>> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.
> > > >>>>>>>>> In
> > > >>>>>>>>> your implementation for Create, Update and Delete you could
> > > >>>>>>>>> begin
> > > >>>>>>>>> the
> > > >>>>>>>>> JTA
> > > >>>>>>>>> transaction and close the transaction by either commit or
> > > >>>>>>>>> rollback.
> > > >>>>>>>>> 
> > > >>>>>>>>> I have not tried the scenario with JTA based transactions but
> > > >>>>>>>>> only
> > > >>>>>>>>> Resource
> > > >>>>>>>>> Local based transactions. Please check and tell if the above
> > > >>>>>>>>> solution
> > > >>>>>>>>> works
> > > >>>>>>>>> for your case. Else raise a JIRA feature request to support JTA
> > > >>>>>>>>> based
> > > >>>>>>>>> transactions.
> > > >>>>>>>>> 
> > > >>>>>>>>> Regards
> > > >>>>>>>>> Chandan
> > > >>>>>>>>> 
> > > >>>>>>>>> -----Original Message-----
> > > >>>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > >>>>>>>>> Sent: Monday, February 16, 2015 2:16 PM
> > > >>>>>>>>> To: user@olingo.apache.org
> > > >>>>>>>>> Subject: olingo JPA / JTA - wrong transactions used
> > > >>>>>>>>> 
> > > >>>>>>>>> Hi,
> > > >>>>>>>>> 
> > > >>>>>>>>> I'm using Olingo 2.0.2 and I can query all items so far. When I
> > > >>>>>>>>> want
> > > >>>>>>>>> to
> > > >>>>>>>>> update content, I get error:
> > > >>>>>>>>> 
> > > >>>>>>>>> ...
> > > >>>>>>>>> <message xml:lang="en">"OData - JPA Runtime: JPA update request
> > > >>>>>>>>> is
> > > >>>>>>>>> not
> > > >>>>>>>>> correct"message>
> > > >>>>>>>>>  <innererror>class java.lang.IllegalStateException :
> > > >>>>>>>>> Exception Description: Cannot use an EntityTransaction while
> > > >>>>>>>>> using
> > > >>>>>>>>> JTA.innererror>
> > > >>>>>>>>> ....
> > > >>>>>>>>> 
> > > >>>>>>>>> Digging deeper into the code, I ended up in file
> > > >>>>>>>>> ODataJPAContextImpl
> > > >>>>>>>>> 
> > > >>>>>>>>> and there in the function
> > > >>>>>>>>> 
> > > >>>>>>>>> private  Object processUpdate(PutMergePatchUriInfo updateView,
> > > >>>>>>>>>    final InputStream content, final Map<String, Object>
> > > >>>>>>>>>    properties,
> > > >>>>>>>>>    final
> > > >>>>>>>>>    String requestContentType)
> > > >>>>>>>>>    throws ODataJPAModelException, ODataJPARuntimeException {
> > > >>>>>>>>> ...
> > > >>>>>>>>> boolean isLocalTransaction = setTransaction();
> > > >>>>>>>>> 
> > > >>>>>>>>> ...
> > > >>>>>>>>> }
> > > >>>>>>>>> 
> > > >>>>>>>>> with
> > > >>>>>>>>> 
> > > >>>>>>>>> private boolean setTransaction() {
> > > >>>>>>>>>  final EntityTransaction transaction = em.getTransaction();
> > > >>>>>>>>>  if (!transaction.isActive()) {
> > > >>>>>>>>>    em.getTransaction().begin();
> > > >>>>>>>>>    return true;
> > > >>>>>>>>>  }
> > > >>>>>>>>> 
> > > >>>>>>>>>  return false;
> > > >>>>>>>>> }
> > > >>>>>>>>> 
> > > >>>>>>>>> 
> > > >>>>>>>>> So far I understood this one is the function that collides with
> > > >>>>>>>>> my
> > > >>>>>>>>> JTA
> > > >>>>>>>>> setup.
> > > >>>>>>>>> I now wonder how I can suppress to initialize this method?
> > > >>>>>>>>> 
> > > >>>>>>>>> I've sending in the right EntityManagerFactory into Olingo,
> > > >>>>>>>>> e.g.:
> > > >>>>>>>>> 
> > > >>>>>>>>> public class ConnectorODataJPAServiceFactory extends
> > > >>>>>>>>> ODataJPAServiceFactory
> > > >>>>>>>>> {
> > > >>>>>>>>> 
> > > >>>>>>>>>  private static final String PERSISTENCE_UNIT_NAME = "myPU";
> > > >>>>>>>>> 
> > > >>>>>>>>>  @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
> > > >>>>>>>>>  EntityManagerFactory emf;
> > > >>>>>>>>> 
> > > >>>>>>>>> 
> > > >>>>>>>>>  @Override
> > > >>>>>>>>>  public ODataJPAContext initializeODataJPAContext() throws
> > > >>>>>>>>>  ODataJPARuntimeException {
> > > >>>>>>>>>      ODataJPAContext oDatJPAContext =
> > > >>>>>>>>>      this.getODataJPAContext();
> > > >>>>>>>>> 
> > > >>>>>>>>>      try {
> > > >>>>>>>>>          CdiContainer.get().getNonContextualManager().postConstruct(this);
> > > >>>>>>>>>          oDatJPAContext.setEntityManagerFactory(emf);
> > > >>>>>>>>>          oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
> > > >>>>>>>>>          oDatJPAContext.setPageSize(100);
> > > >>>>>>>>>          setDetailErrors(true);
> > > >>>>>>>>>          return oDatJPAContext;
> > > >>>>>>>>>      } catch (Exception e) {
> > > >>>>>>>>>          System.out.print(e);
> > > >>>>>>>>>          throw new RuntimeException(e);
> > > >>>>>>>>>      }
> > > >>>>>>>>>  }
> > > >>>>>>>>> 
> > > >>>>>>>>> ...
> > > >>>>>>>>> 
> > > >>>>>>>>> So where is the catch here?
> > > >>>>>>>>> 
> > > >>>>>>>>> 
> > > >>>>>>>>> Best,
> > > >>>>>>>>> 
> > > >>>>>>>>> Korbinian
> > > >>>>>>>>> 
> > > >>>>>>>> 
> > > >>>>>>> 
> > > >>>>>> 
> > > >>>> 
> > > >>>> 
> > > >> 
> > > >> 
> > > 
> > > 
> > 
> 

RE: olingo JPA / JTA - wrong transactions used

Posted by "Amend, Christian" <ch...@sap.com>.
Hi Korbinian,

the json specification defines UTF-8 as the default. Also the media type application/json doesn`t specify a charset parameter as registered here: http://www.iana.org/assignments/media-types/application/json

Quote: "Note:  No "charset" parameter is defined for this registration.   Adding one really has no effect on compliant recipients."

So any client that requests the json format should not treat the payload based on an unspecified charset header. I would not like to encourage uncompliant clients to use the charset header by adding it as a default in the Olingo library.

Best Regards,
Christian

-----Original Message-----
From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de] 
Sent: Donnerstag, 12. März 2015 12:57
To: user@olingo.apache.org
Subject: Re: olingo JPA / JTA - wrong transactions used

Hi Chandan,

thanks for fixing this!

I think I hit another problem with olingo odata v2. If you e.g. do:

...odata/Entites/?$top=10&$format=json

the returned data is correct. What is incorrect is the send out header. Via the JSON impl. the data is send using UTF-8 encoding, while the header is stated solely as:
Content-Type: application/json;

which then leads to incorrect pickup by clients as they chose any encoding they like or think it might be encoding xxx - leading to various problems with special chars.

The fix is as simple as correcting the header to:

Content-Type: application/json;charset=utf-8;

I did this using an filter wrapper around the response, yet IMHO this should be fixed inside olingo;



Best,

Korbinian


----- Ursprüngliche Mail -----
> Von: "Chandan V.A" <ch...@sap.com>
> An: user@olingo.apache.org
> Gesendet: Donnerstag, 12. März 2015 09:53:06
> Betreff: RE: olingo JPA / JTA - wrong transactions used
> 
> Hi All,
> The support for JTA is implemented by pulling the code from
> https://github.com/apache/olingo-odata2/pull/2 and applying some adjustments
> to the code line to be backward compatible. The changes are part of
> 2.0.4-SNAPSHOT version.
> 
> Refer issue - https://issues.apache.org/jira/browse/OLINGO-580 for more
> details that includes on how to use this feature. In case of bugs feel free
> to reopen the issue.
> 
> Regards
> Chandan
> 
> -----Original Message-----
> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> Sent: Thursday, February 26, 2015 5:43 PM
> To: user@olingo.apache.org
> Subject: Re: olingo JPA / JTA - wrong transactions used
> 
> everything in: https://github.com/apache/olingo-odata2/pull/2
> 
> Now, when will Chandan do the JPA for olingo OData V4? ;)
> 
> 
> 
> Best,
> 
> Korbinian
> 
> ----- Ursprüngliche Mail -----
> > Von: "Michael Bolz" <mi...@sap.com>
> > An: "Chandan V.A" <ch...@sap.com>
> > CC: user@olingo.apache.org
> > Gesendet: Donnerstag, 26. Februar 2015 12:59:46
> > Betreff: Re: olingo JPA / JTA - wrong transactions used
> > 
> > Hello all,
> > 
> > after a first look I agree with the suggestion from Chandan.
> > So from my side a +1 for a minor rename ;o)
> > 
> > Kind regards,
> > Michael
> > 
> > > On 26 Feb 2015, at 12:11, V.A, Chandan <ch...@sap.com> wrote:
> > > 
> > > Hello Korbinian,
> > > I did a quick review of the code and at first sight looks fine. I have
> > > few
> > > comments with respect to the name. I feel ODataJPATransaction will be
> > > more
> > > appropriate than ODataJPATransactionContext. Because we are executing
> > > transaction steps using this interface and not just setting and getting
> > > values.
> > > WDYT?
> > > 
> > > Proposal
> > > public interface ODataJPATransaction {
> > > 	void begin();
> > > 	void rollback();
> > > 	void commit();
> > > 	void isActive();
> > > }
> > > 
> > > The class name for default implementation can be
> > > ODataJPATransactionLocalDefault.
> > > 
> > > Thanks
> > > Kind Regards
> > > Chandan
> > > 
> > > -----Original Message-----
> > > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > Sent: Thursday, February 26, 2015 4:09 PM
> > > To: user@olingo.apache.org; Bolz, Michael
> > > Subject: Re: olingo JPA / JTA - wrong transactions used
> > > 
> > > Here you go: https://github.com/apache/olingo-odata2/pull/2
> > > 
> > > Best,
> > > 
> > > Korbinian
> > > 
> > > 
> > > ----- Ursprüngliche Mail -----
> > >> Von: "Michael Bolz" <mi...@sap.com>
> > >> An: user@olingo.apache.org
> > >> CC: "korbinian bachl" <ko...@whiskyworld.de>
> > >> Gesendet: Donnerstag, 26. Februar 2015 08:56:45
> > >> Betreff: Re: olingo JPA / JTA - wrong transactions used
> > >> 
> > >> Hello Korbinian,
> > >> 
> > >> I would prefer to add this just at “ODataJPAServiceFactory”.
> > >> First this way it is consistent with the “setODataTransactionContext”
> > >> and
> > >> second the callback is only related to database (JTA) dependent (using)
> > >> OData services.
> > >> @Korbinian and Chandan: I think (hope) you both agree with my opinion
> > >> ;o)
> > >> 
> > >> When you send me the pull request I will check it and afterwards merge
> > >> into
> > >> Olingo master.
> > >> 
> > >> Kind regards,
> > >> Michael
> > >> 
> > >>> On 25 Feb 2015, at 12:17, Korbinian Bachl
> > >>> <ko...@whiskyworld.de>
> > >>> wrote:
> > >>> 
> > >>> Hello Michael,
> > >>> 
> > >>> I've looked at the suggested OnJPAWriteContent-approach and this would
> > >>> work. Question is just if the callback should be implemented within
> > >>> ODataServiceFactory or just within ODataJPAServiceFactory;
> > >>> 
> > >>> Either way we would need one (1) interface
> > >>> 
> > >>> public interface ODataTransactionContext extends ODataCallback {
> > >>> 
> > >>> public void startTransaction();
> > >>> 
> > >>> public void commitTransaction();
> > >>> 
> > >>> public void rollbackTransaction();
> > >>> 
> > >>> public boolean transactionIsActive();
> > >>> 
> > >>> }
> > >>> 
> > >>> as well as 1 class that implements the current default;
> > >>> 
> > >>> it would be put into the Factory class like
> > >>> 
> > >>> protected void setODataTransactionContext(final ODataTransactionContext
> > >>> oDataTransactionContext) {
> > >>>   this.oDataTransactionContext = oDataTransactionContext;
> > >>> }
> > >>> 
> > >>> and any access to transactions would then need to run via
> > >>> getTransactionContext() e.g.:
> > >>> 
> > >>> FactoryClassInstace.getTransactionContext().startTransaction();
> > >>> 
> > >>> (or if you want the more noisy version:
> > >>> FactoryClassInstace.getCallback(ODataTransactionContext.class).startTransaction();
> > >>> - something I really dont like as this calling stack of
> > >>> if(callbackInterface.isAssignableFrom... ) is something I see waste of
> > >>> CPU
> > >>> cycles in regular and often called code areas, bad habbit IMHO)
> > >>> 
> > >>> 
> > >>> Any other usages like JTA can then override the
> > >>> setODataTransactionContext(...) and supply a class that "does" exactly
> > >>> what needed.
> > >>> 
> > >>> 
> > >>> If this is the way to go, then just let me know which "way" you want it
> > >>> and
> > >>> I can send you a pull request for it (on github);
> > >>> 
> > >>> 
> > >>> 
> > >>> Best,
> > >>> 
> > >>> Korbinian
> > >>> 
> > >>> ----- Ursprüngliche Mail -----
> > >>>> Von: "Michael Bolz" <mi...@sap.com>
> > >>>> An: user@olingo.apache.org
> > >>>> Gesendet: Montag, 23. Februar 2015 11:03:40
> > >>>> Betreff: Re: olingo JPA / JTA - wrong transactions used
> > >>>> 
> > >>>> Hi,
> > >>>> 
> > >>>> could a solution with the “Callback” approach (like the
> > >>>> “OnJPAWriteContent”)
> > >>>> work for this?
> > >>>> So that the “ODataTransactionContext” is implemented as
> > >>>> “ODataTransactionCallback”?
> > >>>> 
> > >>>> This way in the “ODataJPAServiceFactory” a method like: "protected
> > >>>> void
> > >>>> setTransactionCallback(final ODataTransactionCallback callback)” can
> > >>>> be
> > >>>> provided and
> > >>>> if someone want to implement (inherit) his own “ODataServiceFactory”
> > >>>> he
> > >>>> can
> > >>>> support the callback (interface) directly via the “getCallback(…)”
> > >>>> method.
> > >>>> 
> > >>>> Kind regards,
> > >>>> Michael
> > >>>> 
> > >>>> 
> > >>>>> On 23 Feb 2015, at 10:17, Korbinian Bachl
> > >>>>> <ko...@whiskyworld.de>
> > >>>>> wrote:
> > >>>>> 
> > >>>>> Hello Chandan,
> > >>>>> 
> > >>>>> I've looked into the ODataServiceFactory and its usages and I really
> > >>>>> dont
> > >>>>> think this is good. Problems are
> > >>>>> 
> > >>>>> a, ODataServiceFactory is in lib module - so no external dependency
> > >>>>> should
> > >>>>> be pulled into
> > >>>>> b, just extending the class like I suggested wont work as we would
> > >>>>> have
> > >>>>> to
> > >>>>> fix over 13 implementations of this Factory as well - not speaking
> > >>>>> about
> > >>>>> any custom implementations so far;
> > >>>>> c, I currently dont see the "need" to have JTA outside of JPA context
> > >>>>> -
> > >>>>> since no one ever asked for it;
> > >>>>> 
> > >>>>> What I can think of is a CustomTransaction class object that gets its
> > >>>>> "hold" within ODataServiceFactory and needs to be setup by the
> > >>>>> implementation of the ODataServiceFactory only if it needs to use it.
> > >>>>> Something like e.g.:
> > >>>>> 
> > >>>>> in ODataServiceFactory:
> > >>>>> ----------
> > >>>>> private ODataTransactionContext = null;
> > >>>>> 
> > >>>>> //stub - needs to be implemented if want to be used
> > >>>>> public void setUpTransactionContext() {};
> > >>>>> 
> > >>>>> public getODataTransactionContext() {
> > >>>>>     return ODataTransactionContext;
> > >>>>> }
> > >>>>> 
> > >>>>> public setODataTransactionContext(ODataTransactionContext ctx) {...}
> > >>>>> 
> > >>>>> ---------
> > >>>>> 
> > >>>>> 
> > >>>>> and ODataTransactionContext could be some kind of abstract class that
> > >>>>> has
> > >>>>> the methods
> > >>>>> 
> > >>>>> public abstract class ODataTransactionContext {
> > >>>>> 
> > >>>>> public abstract void commitTransaction();
> > >>>>> 
> > >>>>> public abstract void startTransaction();
> > >>>>> 
> > >>>>> public abstract void rollbackTransaction();
> > >>>>> 
> > >>>>> public abstract boolean transactionIsActive();
> > >>>>> 
> > >>>>> }
> > >>>>> 
> > >>>>> -------
> > >>>>> 
> > >>>>> IMHO looks ugly; But using an interface for this would be even more
> > >>>>> ugly....
> > >>>>> 
> > >>>>> 
> > >>>>> Best,
> > >>>>> 
> > >>>>> Korbinian
> > >>>>> 
> > >>>>> 
> > >>>>> ----- Ursprüngliche Mail -----
> > >>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > >>>>>> An: user@olingo.apache.org
> > >>>>>> Gesendet: Donnerstag, 19. Februar 2015 08:07:59
> > >>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > >>>>>> 
> > >>>>>> Hello Korbinian,
> > >>>>>> I could have kept the methods as part of ODataJPAServiceFactory but
> > >>>>>> the
> > >>>>>> problem is, extending the ODataJPAServiceFactory class for an
> > >>>>>> application
> > >>>>>> is
> > >>>>>> optional. Applications can create their own factory classes by
> > >>>>>> directly
> > >>>>>> inheriting ODataServiceFactory. We need to support such applications
> > >>>>>> as
> > >>>>>> well. I have created the JIRA issue
> > >>>>>> https://issues.apache.org/jira/browse/OLINGO-580 to implement
> > >>>>>> support
> > >>>>>> for
> > >>>>>> JTA based transactions.
> > >>>>>> 
> > >>>>>> Thanks
> > >>>>>> Kind Regards
> > >>>>>> Chandan
> > >>>>>> 
> > >>>>>> -----Original Message-----
> > >>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > >>>>>> Sent: Wednesday, February 18, 2015 7:30 PM
> > >>>>>> To: user@olingo.apache.org
> > >>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> > >>>>>> 
> > >>>>>> Hello Chandan,
> > >>>>>> 
> > >>>>>> sounds good. What I would do - based upon your idea - is to extend
> > >>>>>> the
> > >>>>>> ODataJPAServiceFactory with 4 methods (as this one has to be used in
> > >>>>>> any
> > >>>>>> case):
> > >>>>>> 
> > >>>>>> public static void startTransaction(EntityManager em, Object
> > >>>>>> transaction)
> > >>>>>> {
> > >>>>>>  em.getTransaction().begin();
> > >>>>>>  transaction = em.getTransaction();
> > >>>>>> }
> > >>>>>> 
> > >>>>>> public static void commitTransaction(Object transaction) {
> > >>>>>>  ((EntitiyTransaction) transaction).commit();
> > >>>>>> }
> > >>>>>> 
> > >>>>>> public static void rollbackTransaction(Object transaction) {
> > >>>>>>  ((EntitiyTransaction) transaction).rollback();
> > >>>>>> }
> > >>>>>> 
> > >>>>>> public static boolean transactionIsActive(Object transaction) {
> > >>>>>> return ((EntitiyTransaction) transaction).isActive();
> > >>>>>> }
> > >>>>>> 
> > >>>>>> These then would be called from wherever olingo JPA needs them.
> > >>>>>> 
> > >>>>>> That way any one needing JTA can override these methods while the
> > >>>>>> rest
> > >>>>>> won't
> > >>>>>> even notice them...
> > >>>>>> 
> > >>>>>> 
> > >>>>>> What do you think?
> > >>>>>> 
> > >>>>>> Best,
> > >>>>>> 
> > >>>>>> Korbinian
> > >>>>>> 
> > >>>>>> 
> > >>>>>> 
> > >>>>>> 
> > >>>>>> 
> > >>>>>> ----- Ursprüngliche Mail -----
> > >>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > >>>>>>> An: user@olingo.apache.org
> > >>>>>>> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
> > >>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > >>>>>>> 
> > >>>>>>> Hello Korbinian,
> > >>>>>>> I would at least keep the application managed transactions (like
> > >>>>>>> JTA)
> > >>>>>>> outside
> > >>>>>>> the context of JPA Processor for following reasons
> > >>>>>>> 1) Wiring the JTA transactions into JPA processor could make the
> > >>>>>>> processor
> > >>>>>>> to
> > >>>>>>> behave more like a framework than as a library (which is the
> > >>>>>>> current
> > >>>>>>> state).
> > >>>>>>> 2) JPA processor also need to take JNDI lookup as parameter from
> > >>>>>>> applications
> > >>>>>>> for looking up the datasource.
> > >>>>>>> 3) Olingo JPA processor should take care of just data
> > >>>>>>> transformations
> > >>>>>>> and
> > >>>>>>> need not worry about the scope of transactions
> > >>>>>>> 4) Olingo JPA processor should not take dependency to J2EE api
> > >>>>>>> because
> > >>>>>>> I
> > >>>>>>> am
> > >>>>>>> not sure will this artifact work in OSGI environments
> > >>>>>>> 
> > >>>>>>> One proposal from my side would be to provide a callback mechanism
> > >>>>>>> for
> > >>>>>>> transaction handling, where the library just calls a method in the
> > >>>>>>> interface
> > >>>>>>> to begin the transaction and end the transaction. If no one
> > >>>>>>> implements
> > >>>>>>> the
> > >>>>>>> callback mechanism the library would resort to "RESOURCE_LOCAL"
> > >>>>>>> based
> > >>>>>>> transaction handling. With this approach applications will have a
> > >>>>>>> greater
> > >>>>>>> control over transaction handling and also need not rewrite
> > >>>>>>> JPAProcessorImpl
> > >>>>>>> or extend ODataJPAProcessor.
> > >>>>>>> 
> > >>>>>>> What do you think? Do you foresee any shortcomings with this
> > >>>>>>> approach?
> > >>>>>>> 
> > >>>>>>> Thanks
> > >>>>>>> Kind Regards
> > >>>>>>> Chandan
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> -----Original Message-----
> > >>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > >>>>>>> Sent: Wednesday, February 18, 2015 6:22 PM
> > >>>>>>> To: user@olingo.apache.org
> > >>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> > >>>>>>> 
> > >>>>>>> Hello Chandan,
> > >>>>>>> 
> > >>>>>>> I finally had some success in using JTA based transactions.
> > >>>>>>> However,
> > >>>>>>> this
> > >>>>>>> only worked when I cloned the current git and changed it in the
> > >>>>>>> JPAProcessorImpl directly; If I try to do this from within my
> > >>>>>>> project
> > >>>>>>> onto
> > >>>>>>> the intialization with
> > >>>>>>> 
> > >>>>>>> oDatJPAContext.setODataProcessor(new
> > >>>>>>> ODataJPAProcessorJTA(oDatJPAContext));
> > >>>>>>> 
> > >>>>>>> I then have to do a ODataJPAProcessorJTA which is 99% copy n paste
> > >>>>>>> from
> > >>>>>>> ODataJPAProcessor and then also need a 95% copy n paste
> > >>>>>>> JPAProcessorImplJTA
> > >>>>>>> from JPAProcessorImpl;
> > >>>>>>> 
> > >>>>>>> As if this isn't ugly enough, it gets real dirty when trying to use
> > >>>>>>> it
> > >>>>>>> as
> > >>>>>>> you
> > >>>>>>> simply cant force olingo to use it! Problem is that it comes from
> > >>>>>>> the
> > >>>>>>> JPAAccessFactoryImpl class static; is a static one and sits in
> > >>>>>>> ODataJPAFactoryImpl and finally this one gets called in public
> > >>>>>>> abstract
> > >>>>>>> class ODataJPAFactory
> > >>>>>>> 
> > >>>>>>> using
> > >>>>>>> 
> > >>>>>>> public static ODataJPAFactory createFactory() {
> > >>>>>>> 
> > >>>>>>>  if (factoryImpl != null) {
> > >>>>>>>    return factoryImpl;
> > >>>>>>>  } else {
> > >>>>>>>    try {
> > >>>>>>>      Class<?> clazz =
> > >>>>>>>      Class.forName(ODataJPAFactory.IMPLEMENTATION);
> > >>>>>>> 
> > >>>>>>>      Object object = clazz.newInstance();
> > >>>>>>>      factoryImpl = (ODataJPAFactory) object;
> > >>>>>>> 
> > >>>>>>>    } catch (Exception e) {
> > >>>>>>>      throw new RuntimeException(e);
> > >>>>>>>    }
> > >>>>>>> 
> > >>>>>>>    return factoryImpl;
> > >>>>>>>  }
> > >>>>>>> }
> > >>>>>>> 
> > >>>>>>> where private static final String IMPLEMENTATION =
> > >>>>>>>    "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> Simple said - overriding this logic in the olingo project is next
> > >>>>>>> to
> > >>>>>>> impossible as you would end up with nearly the whole project
> > >>>>>>> copy'n'pasted
> > >>>>>>> over; Simple changing the e.g.  resolver etc. wont works as there
> > >>>>>>> are
> > >>>>>>> many
> > >>>>>>> usages of the ODataJPAFactory createFactory() method;
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> Implementing JTA to work in olingo on the other hand is quite easy.
> > >>>>>>> You
> > >>>>>>> can
> > >>>>>>> check on the fly if your JTA or not via e.g.:
> > >>>>>>> 
> > >>>>>>> public static boolean isResourceLocal(EntityManager em) {
> > >>>>>>>      try {
> > >>>>>>>          EntityTransaction tx = em.getTransaction();
> > >>>>>>>          return true;
> > >>>>>>>      } catch (IllegalStateException ex) {
> > >>>>>>>          return false;
> > >>>>>>>      }
> > >>>>>>>  }
> > >>>>>>> 
> > >>>>>>> and this one can then set into a boolean var classwide in the
> > >>>>>>> JPAProcessorImpl; so the setTransaction would become:
> > >>>>>>> 
> > >>>>>>> private boolean setTransaction() {
> > >>>>>>>    if(isLocalTX) {
> > >>>>>>>        final EntityTransaction transaction = em.getTransaction();
> > >>>>>>>        if (!transaction.isActive()) {
> > >>>>>>>            em.getTransaction().begin();
> > >>>>>>>            return true;
> > >>>>>>>        }
> > >>>>>>>    } else {
> > >>>>>>>        try {
> > >>>>>>>            transaction = (UserTransaction) new
> > >>>>>>>            InitialContext().lookup("java:comp/UserTransaction");
> > >>>>>>>            transaction.begin();
> > >>>>>>>        } catch (NamingException e) {
> > >>>>>>>            e.printStackTrace();
> > >>>>>>>        } catch (NotSupportedException e) {
> > >>>>>>>            e.printStackTrace();
> > >>>>>>>        } catch (SystemException e) {
> > >>>>>>>            e.printStackTrace();
> > >>>>>>>        }
> > >>>>>>>    }
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>>  return false;
> > >>>>>>> }
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> and this would work on all JTA bases Servers. The rest of the
> > >>>>>>> transaction
> > >>>>>>> logic would simply look like e.g.:
> > >>>>>>> 
> > >>>>>>> if (isLocalTransaction) {
> > >>>>>>>      em.getTransaction().commit();
> > >>>>>>>    }
> > >>>>>>> if(transaction != null) {
> > >>>>>>>          transaction.commit();
> > >>>>>>>    }
> > >>>>>>> Or even
> > >>>>>>> if (isLocalTransaction) {
> > >>>>>>>      em.getTransaction().commit();
> > >>>>>>>    }
> > >>>>>>> else {
> > >>>>>>>          transaction.commit();
> > >>>>>>>    }
> > >>>>>>> in case we expect a 100% availbilty of transactional context;
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> Problem is now that this needs at least the dependency of
> > >>>>>>>      <dependency>
> > >>>>>>>          <groupId>javax</groupId>
> > >>>>>>>          <artifactId>javaee-api</artifactId>
> > >>>>>>>          <version>6.0</version>
> > >>>>>>>      </dependency>
> > >>>>>>> as else there is no UserTransaction class available; Would this
> > >>>>>>> dependency
> > >>>>>>> be
> > >>>>>>> ok for the JPA part of the olingo project?
> > >>>>>>> 
> > >>>>>>> What do you think?
> > >>>>>>> 
> > >>>>>>> Best,
> > >>>>>>> 
> > >>>>>>> Korbinian
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> ----- Ursprüngliche Mail -----
> > >>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > >>>>>>>> An: user@olingo.apache.org
> > >>>>>>>> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
> > >>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > >>>>>>>> 
> > >>>>>>>> Hello Korbinian,
> > >>>>>>>> Please check the JIRA item -
> > >>>>>>>> https://issues.apache.org/jira/browse/OLINGO-549
> > >>>>>>>> for updates on Olingo V4 JPA processor. Current status is there is
> > >>>>>>>> no
> > >>>>>>>> support for V4 JPA processor and the development is in progress.
> > >>>>>>>> 
> > >>>>>>>> Thanks
> > >>>>>>>> Kind Regards
> > >>>>>>>> Chandan
> > >>>>>>>> 
> > >>>>>>>> -----Original Message-----
> > >>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > >>>>>>>> Sent: Wednesday, February 18, 2015 2:48 PM
> > >>>>>>>> To: user@olingo.apache.org
> > >>>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> > >>>>>>>> 
> > >>>>>>>> Hello Chandan,
> > >>>>>>>> 
> > >>>>>>>> thank you for the info. Will try this. I've seen that Olingo also
> > >>>>>>>> has
> > >>>>>>>> a
> > >>>>>>>> OData
> > >>>>>>>> V4 in Beta2 - but I couldn't really find information about its
> > >>>>>>>> "readyness".
> > >>>>>>>> Would it work in a simple CRUD scenario with JPA? Reason is as it
> > >>>>>>>> seems
> > >>>>>>>> as
> > >>>>>>>> my other system I talk to via OData is moving from V3 to V4
> > >>>>>>>> currently,
> > >>>>>>>> at
> > >>>>>>>> least the doc of its alredy speaks of OData V4 ready.
> > >>>>>>>> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
> > >>>>>>>> 
> > >>>>>>>> Best,
> > >>>>>>>> 
> > >>>>>>>> Korbinian
> > >>>>>>>> 
> > >>>>>>>> 
> > >>>>>>>> 
> > >>>>>>>> ----- Ursprüngliche Mail -----
> > >>>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > >>>>>>>>> An: user@olingo.apache.org
> > >>>>>>>>> Gesendet: Dienstag, 17. Februar 2015 07:11:28
> > >>>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > >>>>>>>>> 
> > >>>>>>>>> Hello Korbinian,
> > >>>>>>>>> You can extend the
> > >>>>>>>>> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and
> > >>>>>>>>> implement
> > >>>>>>>>> the processor methods as it is done in
> > >>>>>>>>> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.
> > >>>>>>>>> In
> > >>>>>>>>> your implementation for Create, Update and Delete you could begin
> > >>>>>>>>> the
> > >>>>>>>>> JTA
> > >>>>>>>>> transaction and close the transaction by either commit or
> > >>>>>>>>> rollback.
> > >>>>>>>>> 
> > >>>>>>>>> I have not tried the scenario with JTA based transactions but
> > >>>>>>>>> only
> > >>>>>>>>> Resource
> > >>>>>>>>> Local based transactions. Please check and tell if the above
> > >>>>>>>>> solution
> > >>>>>>>>> works
> > >>>>>>>>> for your case. Else raise a JIRA feature request to support JTA
> > >>>>>>>>> based
> > >>>>>>>>> transactions.
> > >>>>>>>>> 
> > >>>>>>>>> Regards
> > >>>>>>>>> Chandan
> > >>>>>>>>> 
> > >>>>>>>>> -----Original Message-----
> > >>>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > >>>>>>>>> Sent: Monday, February 16, 2015 2:16 PM
> > >>>>>>>>> To: user@olingo.apache.org
> > >>>>>>>>> Subject: olingo JPA / JTA - wrong transactions used
> > >>>>>>>>> 
> > >>>>>>>>> Hi,
> > >>>>>>>>> 
> > >>>>>>>>> I'm using Olingo 2.0.2 and I can query all items so far. When I
> > >>>>>>>>> want
> > >>>>>>>>> to
> > >>>>>>>>> update content, I get error:
> > >>>>>>>>> 
> > >>>>>>>>> ...
> > >>>>>>>>> <message xml:lang="en">"OData - JPA Runtime: JPA update request
> > >>>>>>>>> is
> > >>>>>>>>> not
> > >>>>>>>>> correct"message>
> > >>>>>>>>>  <innererror>class java.lang.IllegalStateException :
> > >>>>>>>>> Exception Description: Cannot use an EntityTransaction while
> > >>>>>>>>> using
> > >>>>>>>>> JTA.innererror>
> > >>>>>>>>> ....
> > >>>>>>>>> 
> > >>>>>>>>> Digging deeper into the code, I ended up in file
> > >>>>>>>>> ODataJPAContextImpl
> > >>>>>>>>> 
> > >>>>>>>>> and there in the function
> > >>>>>>>>> 
> > >>>>>>>>> private  Object processUpdate(PutMergePatchUriInfo updateView,
> > >>>>>>>>>    final InputStream content, final Map<String, Object>
> > >>>>>>>>>    properties,
> > >>>>>>>>>    final
> > >>>>>>>>>    String requestContentType)
> > >>>>>>>>>    throws ODataJPAModelException, ODataJPARuntimeException {
> > >>>>>>>>> ...
> > >>>>>>>>> boolean isLocalTransaction = setTransaction();
> > >>>>>>>>> 
> > >>>>>>>>> ...
> > >>>>>>>>> }
> > >>>>>>>>> 
> > >>>>>>>>> with
> > >>>>>>>>> 
> > >>>>>>>>> private boolean setTransaction() {
> > >>>>>>>>>  final EntityTransaction transaction = em.getTransaction();
> > >>>>>>>>>  if (!transaction.isActive()) {
> > >>>>>>>>>    em.getTransaction().begin();
> > >>>>>>>>>    return true;
> > >>>>>>>>>  }
> > >>>>>>>>> 
> > >>>>>>>>>  return false;
> > >>>>>>>>> }
> > >>>>>>>>> 
> > >>>>>>>>> 
> > >>>>>>>>> So far I understood this one is the function that collides with
> > >>>>>>>>> my
> > >>>>>>>>> JTA
> > >>>>>>>>> setup.
> > >>>>>>>>> I now wonder how I can suppress to initialize this method?
> > >>>>>>>>> 
> > >>>>>>>>> I've sending in the right EntityManagerFactory into Olingo, e.g.:
> > >>>>>>>>> 
> > >>>>>>>>> public class ConnectorODataJPAServiceFactory extends
> > >>>>>>>>> ODataJPAServiceFactory
> > >>>>>>>>> {
> > >>>>>>>>> 
> > >>>>>>>>>  private static final String PERSISTENCE_UNIT_NAME = "myPU";
> > >>>>>>>>> 
> > >>>>>>>>>  @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
> > >>>>>>>>>  EntityManagerFactory emf;
> > >>>>>>>>> 
> > >>>>>>>>> 
> > >>>>>>>>>  @Override
> > >>>>>>>>>  public ODataJPAContext initializeODataJPAContext() throws
> > >>>>>>>>>  ODataJPARuntimeException {
> > >>>>>>>>>      ODataJPAContext oDatJPAContext = this.getODataJPAContext();
> > >>>>>>>>> 
> > >>>>>>>>>      try {
> > >>>>>>>>>          CdiContainer.get().getNonContextualManager().postConstruct(this);
> > >>>>>>>>>          oDatJPAContext.setEntityManagerFactory(emf);
> > >>>>>>>>>          oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
> > >>>>>>>>>          oDatJPAContext.setPageSize(100);
> > >>>>>>>>>          setDetailErrors(true);
> > >>>>>>>>>          return oDatJPAContext;
> > >>>>>>>>>      } catch (Exception e) {
> > >>>>>>>>>          System.out.print(e);
> > >>>>>>>>>          throw new RuntimeException(e);
> > >>>>>>>>>      }
> > >>>>>>>>>  }
> > >>>>>>>>> 
> > >>>>>>>>> ...
> > >>>>>>>>> 
> > >>>>>>>>> So where is the catch here?
> > >>>>>>>>> 
> > >>>>>>>>> 
> > >>>>>>>>> Best,
> > >>>>>>>>> 
> > >>>>>>>>> Korbinian
> > >>>>>>>>> 
> > >>>>>>>> 
> > >>>>>>> 
> > >>>>>> 
> > >>>> 
> > >>>> 
> > >> 
> > >> 
> > 
> > 
> 

Re: olingo JPA / JTA - wrong transactions used

Posted by Korbinian Bachl <ko...@whiskyworld.de>.
Hi Chandan,

thanks for fixing this!

I think I hit another problem with olingo odata v2. If you e.g. do:

...odata/Entites/?$top=10&$format=json

the returned data is correct. What is incorrect is the send out header. Via the JSON impl. the data is send using UTF-8 encoding, while the header is stated solely as:
Content-Type: application/json;

which then leads to incorrect pickup by clients as they chose any encoding they like or think it might be encoding xxx - leading to various problems with special chars.

The fix is as simple as correcting the header to:

Content-Type: application/json;charset=utf-8;

I did this using an filter wrapper around the response, yet IMHO this should be fixed inside olingo;



Best,

Korbinian


----- Ursprüngliche Mail -----
> Von: "Chandan V.A" <ch...@sap.com>
> An: user@olingo.apache.org
> Gesendet: Donnerstag, 12. März 2015 09:53:06
> Betreff: RE: olingo JPA / JTA - wrong transactions used
> 
> Hi All,
> The support for JTA is implemented by pulling the code from
> https://github.com/apache/olingo-odata2/pull/2 and applying some adjustments
> to the code line to be backward compatible. The changes are part of
> 2.0.4-SNAPSHOT version.
> 
> Refer issue - https://issues.apache.org/jira/browse/OLINGO-580 for more
> details that includes on how to use this feature. In case of bugs feel free
> to reopen the issue.
> 
> Regards
> Chandan
> 
> -----Original Message-----
> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> Sent: Thursday, February 26, 2015 5:43 PM
> To: user@olingo.apache.org
> Subject: Re: olingo JPA / JTA - wrong transactions used
> 
> everything in: https://github.com/apache/olingo-odata2/pull/2
> 
> Now, when will Chandan do the JPA for olingo OData V4? ;)
> 
> 
> 
> Best,
> 
> Korbinian
> 
> ----- Ursprüngliche Mail -----
> > Von: "Michael Bolz" <mi...@sap.com>
> > An: "Chandan V.A" <ch...@sap.com>
> > CC: user@olingo.apache.org
> > Gesendet: Donnerstag, 26. Februar 2015 12:59:46
> > Betreff: Re: olingo JPA / JTA - wrong transactions used
> > 
> > Hello all,
> > 
> > after a first look I agree with the suggestion from Chandan.
> > So from my side a +1 for a minor rename ;o)
> > 
> > Kind regards,
> > Michael
> > 
> > > On 26 Feb 2015, at 12:11, V.A, Chandan <ch...@sap.com> wrote:
> > > 
> > > Hello Korbinian,
> > > I did a quick review of the code and at first sight looks fine. I have
> > > few
> > > comments with respect to the name. I feel ODataJPATransaction will be
> > > more
> > > appropriate than ODataJPATransactionContext. Because we are executing
> > > transaction steps using this interface and not just setting and getting
> > > values.
> > > WDYT?
> > > 
> > > Proposal
> > > public interface ODataJPATransaction {
> > > 	void begin();
> > > 	void rollback();
> > > 	void commit();
> > > 	void isActive();
> > > }
> > > 
> > > The class name for default implementation can be
> > > ODataJPATransactionLocalDefault.
> > > 
> > > Thanks
> > > Kind Regards
> > > Chandan
> > > 
> > > -----Original Message-----
> > > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > Sent: Thursday, February 26, 2015 4:09 PM
> > > To: user@olingo.apache.org; Bolz, Michael
> > > Subject: Re: olingo JPA / JTA - wrong transactions used
> > > 
> > > Here you go: https://github.com/apache/olingo-odata2/pull/2
> > > 
> > > Best,
> > > 
> > > Korbinian
> > > 
> > > 
> > > ----- Ursprüngliche Mail -----
> > >> Von: "Michael Bolz" <mi...@sap.com>
> > >> An: user@olingo.apache.org
> > >> CC: "korbinian bachl" <ko...@whiskyworld.de>
> > >> Gesendet: Donnerstag, 26. Februar 2015 08:56:45
> > >> Betreff: Re: olingo JPA / JTA - wrong transactions used
> > >> 
> > >> Hello Korbinian,
> > >> 
> > >> I would prefer to add this just at “ODataJPAServiceFactory”.
> > >> First this way it is consistent with the “setODataTransactionContext”
> > >> and
> > >> second the callback is only related to database (JTA) dependent (using)
> > >> OData services.
> > >> @Korbinian and Chandan: I think (hope) you both agree with my opinion
> > >> ;o)
> > >> 
> > >> When you send me the pull request I will check it and afterwards merge
> > >> into
> > >> Olingo master.
> > >> 
> > >> Kind regards,
> > >> Michael
> > >> 
> > >>> On 25 Feb 2015, at 12:17, Korbinian Bachl
> > >>> <ko...@whiskyworld.de>
> > >>> wrote:
> > >>> 
> > >>> Hello Michael,
> > >>> 
> > >>> I've looked at the suggested OnJPAWriteContent-approach and this would
> > >>> work. Question is just if the callback should be implemented within
> > >>> ODataServiceFactory or just within ODataJPAServiceFactory;
> > >>> 
> > >>> Either way we would need one (1) interface
> > >>> 
> > >>> public interface ODataTransactionContext extends ODataCallback {
> > >>> 
> > >>> public void startTransaction();
> > >>> 
> > >>> public void commitTransaction();
> > >>> 
> > >>> public void rollbackTransaction();
> > >>> 
> > >>> public boolean transactionIsActive();
> > >>> 
> > >>> }
> > >>> 
> > >>> as well as 1 class that implements the current default;
> > >>> 
> > >>> it would be put into the Factory class like
> > >>> 
> > >>> protected void setODataTransactionContext(final ODataTransactionContext
> > >>> oDataTransactionContext) {
> > >>>   this.oDataTransactionContext = oDataTransactionContext;
> > >>> }
> > >>> 
> > >>> and any access to transactions would then need to run via
> > >>> getTransactionContext() e.g.:
> > >>> 
> > >>> FactoryClassInstace.getTransactionContext().startTransaction();
> > >>> 
> > >>> (or if you want the more noisy version:
> > >>> FactoryClassInstace.getCallback(ODataTransactionContext.class).startTransaction();
> > >>> - something I really dont like as this calling stack of
> > >>> if(callbackInterface.isAssignableFrom... ) is something I see waste of
> > >>> CPU
> > >>> cycles in regular and often called code areas, bad habbit IMHO)
> > >>> 
> > >>> 
> > >>> Any other usages like JTA can then override the
> > >>> setODataTransactionContext(...) and supply a class that "does" exactly
> > >>> what needed.
> > >>> 
> > >>> 
> > >>> If this is the way to go, then just let me know which "way" you want it
> > >>> and
> > >>> I can send you a pull request for it (on github);
> > >>> 
> > >>> 
> > >>> 
> > >>> Best,
> > >>> 
> > >>> Korbinian
> > >>> 
> > >>> ----- Ursprüngliche Mail -----
> > >>>> Von: "Michael Bolz" <mi...@sap.com>
> > >>>> An: user@olingo.apache.org
> > >>>> Gesendet: Montag, 23. Februar 2015 11:03:40
> > >>>> Betreff: Re: olingo JPA / JTA - wrong transactions used
> > >>>> 
> > >>>> Hi,
> > >>>> 
> > >>>> could a solution with the “Callback” approach (like the
> > >>>> “OnJPAWriteContent”)
> > >>>> work for this?
> > >>>> So that the “ODataTransactionContext” is implemented as
> > >>>> “ODataTransactionCallback”?
> > >>>> 
> > >>>> This way in the “ODataJPAServiceFactory” a method like: "protected
> > >>>> void
> > >>>> setTransactionCallback(final ODataTransactionCallback callback)” can
> > >>>> be
> > >>>> provided and
> > >>>> if someone want to implement (inherit) his own “ODataServiceFactory”
> > >>>> he
> > >>>> can
> > >>>> support the callback (interface) directly via the “getCallback(…)”
> > >>>> method.
> > >>>> 
> > >>>> Kind regards,
> > >>>> Michael
> > >>>> 
> > >>>> 
> > >>>>> On 23 Feb 2015, at 10:17, Korbinian Bachl
> > >>>>> <ko...@whiskyworld.de>
> > >>>>> wrote:
> > >>>>> 
> > >>>>> Hello Chandan,
> > >>>>> 
> > >>>>> I've looked into the ODataServiceFactory and its usages and I really
> > >>>>> dont
> > >>>>> think this is good. Problems are
> > >>>>> 
> > >>>>> a, ODataServiceFactory is in lib module - so no external dependency
> > >>>>> should
> > >>>>> be pulled into
> > >>>>> b, just extending the class like I suggested wont work as we would
> > >>>>> have
> > >>>>> to
> > >>>>> fix over 13 implementations of this Factory as well - not speaking
> > >>>>> about
> > >>>>> any custom implementations so far;
> > >>>>> c, I currently dont see the "need" to have JTA outside of JPA context
> > >>>>> -
> > >>>>> since no one ever asked for it;
> > >>>>> 
> > >>>>> What I can think of is a CustomTransaction class object that gets its
> > >>>>> "hold" within ODataServiceFactory and needs to be setup by the
> > >>>>> implementation of the ODataServiceFactory only if it needs to use it.
> > >>>>> Something like e.g.:
> > >>>>> 
> > >>>>> in ODataServiceFactory:
> > >>>>> ----------
> > >>>>> private ODataTransactionContext = null;
> > >>>>> 
> > >>>>> //stub - needs to be implemented if want to be used
> > >>>>> public void setUpTransactionContext() {};
> > >>>>> 
> > >>>>> public getODataTransactionContext() {
> > >>>>>     return ODataTransactionContext;
> > >>>>> }
> > >>>>> 
> > >>>>> public setODataTransactionContext(ODataTransactionContext ctx) {...}
> > >>>>> 
> > >>>>> ---------
> > >>>>> 
> > >>>>> 
> > >>>>> and ODataTransactionContext could be some kind of abstract class that
> > >>>>> has
> > >>>>> the methods
> > >>>>> 
> > >>>>> public abstract class ODataTransactionContext {
> > >>>>> 
> > >>>>> public abstract void commitTransaction();
> > >>>>> 
> > >>>>> public abstract void startTransaction();
> > >>>>> 
> > >>>>> public abstract void rollbackTransaction();
> > >>>>> 
> > >>>>> public abstract boolean transactionIsActive();
> > >>>>> 
> > >>>>> }
> > >>>>> 
> > >>>>> -------
> > >>>>> 
> > >>>>> IMHO looks ugly; But using an interface for this would be even more
> > >>>>> ugly....
> > >>>>> 
> > >>>>> 
> > >>>>> Best,
> > >>>>> 
> > >>>>> Korbinian
> > >>>>> 
> > >>>>> 
> > >>>>> ----- Ursprüngliche Mail -----
> > >>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > >>>>>> An: user@olingo.apache.org
> > >>>>>> Gesendet: Donnerstag, 19. Februar 2015 08:07:59
> > >>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > >>>>>> 
> > >>>>>> Hello Korbinian,
> > >>>>>> I could have kept the methods as part of ODataJPAServiceFactory but
> > >>>>>> the
> > >>>>>> problem is, extending the ODataJPAServiceFactory class for an
> > >>>>>> application
> > >>>>>> is
> > >>>>>> optional. Applications can create their own factory classes by
> > >>>>>> directly
> > >>>>>> inheriting ODataServiceFactory. We need to support such applications
> > >>>>>> as
> > >>>>>> well. I have created the JIRA issue
> > >>>>>> https://issues.apache.org/jira/browse/OLINGO-580 to implement
> > >>>>>> support
> > >>>>>> for
> > >>>>>> JTA based transactions.
> > >>>>>> 
> > >>>>>> Thanks
> > >>>>>> Kind Regards
> > >>>>>> Chandan
> > >>>>>> 
> > >>>>>> -----Original Message-----
> > >>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > >>>>>> Sent: Wednesday, February 18, 2015 7:30 PM
> > >>>>>> To: user@olingo.apache.org
> > >>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> > >>>>>> 
> > >>>>>> Hello Chandan,
> > >>>>>> 
> > >>>>>> sounds good. What I would do - based upon your idea - is to extend
> > >>>>>> the
> > >>>>>> ODataJPAServiceFactory with 4 methods (as this one has to be used in
> > >>>>>> any
> > >>>>>> case):
> > >>>>>> 
> > >>>>>> public static void startTransaction(EntityManager em, Object
> > >>>>>> transaction)
> > >>>>>> {
> > >>>>>>  em.getTransaction().begin();
> > >>>>>>  transaction = em.getTransaction();
> > >>>>>> }
> > >>>>>> 
> > >>>>>> public static void commitTransaction(Object transaction) {
> > >>>>>>  ((EntitiyTransaction) transaction).commit();
> > >>>>>> }
> > >>>>>> 
> > >>>>>> public static void rollbackTransaction(Object transaction) {
> > >>>>>>  ((EntitiyTransaction) transaction).rollback();
> > >>>>>> }
> > >>>>>> 
> > >>>>>> public static boolean transactionIsActive(Object transaction) {
> > >>>>>> return ((EntitiyTransaction) transaction).isActive();
> > >>>>>> }
> > >>>>>> 
> > >>>>>> These then would be called from wherever olingo JPA needs them.
> > >>>>>> 
> > >>>>>> That way any one needing JTA can override these methods while the
> > >>>>>> rest
> > >>>>>> won't
> > >>>>>> even notice them...
> > >>>>>> 
> > >>>>>> 
> > >>>>>> What do you think?
> > >>>>>> 
> > >>>>>> Best,
> > >>>>>> 
> > >>>>>> Korbinian
> > >>>>>> 
> > >>>>>> 
> > >>>>>> 
> > >>>>>> 
> > >>>>>> 
> > >>>>>> ----- Ursprüngliche Mail -----
> > >>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > >>>>>>> An: user@olingo.apache.org
> > >>>>>>> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
> > >>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > >>>>>>> 
> > >>>>>>> Hello Korbinian,
> > >>>>>>> I would at least keep the application managed transactions (like
> > >>>>>>> JTA)
> > >>>>>>> outside
> > >>>>>>> the context of JPA Processor for following reasons
> > >>>>>>> 1) Wiring the JTA transactions into JPA processor could make the
> > >>>>>>> processor
> > >>>>>>> to
> > >>>>>>> behave more like a framework than as a library (which is the
> > >>>>>>> current
> > >>>>>>> state).
> > >>>>>>> 2) JPA processor also need to take JNDI lookup as parameter from
> > >>>>>>> applications
> > >>>>>>> for looking up the datasource.
> > >>>>>>> 3) Olingo JPA processor should take care of just data
> > >>>>>>> transformations
> > >>>>>>> and
> > >>>>>>> need not worry about the scope of transactions
> > >>>>>>> 4) Olingo JPA processor should not take dependency to J2EE api
> > >>>>>>> because
> > >>>>>>> I
> > >>>>>>> am
> > >>>>>>> not sure will this artifact work in OSGI environments
> > >>>>>>> 
> > >>>>>>> One proposal from my side would be to provide a callback mechanism
> > >>>>>>> for
> > >>>>>>> transaction handling, where the library just calls a method in the
> > >>>>>>> interface
> > >>>>>>> to begin the transaction and end the transaction. If no one
> > >>>>>>> implements
> > >>>>>>> the
> > >>>>>>> callback mechanism the library would resort to "RESOURCE_LOCAL"
> > >>>>>>> based
> > >>>>>>> transaction handling. With this approach applications will have a
> > >>>>>>> greater
> > >>>>>>> control over transaction handling and also need not rewrite
> > >>>>>>> JPAProcessorImpl
> > >>>>>>> or extend ODataJPAProcessor.
> > >>>>>>> 
> > >>>>>>> What do you think? Do you foresee any shortcomings with this
> > >>>>>>> approach?
> > >>>>>>> 
> > >>>>>>> Thanks
> > >>>>>>> Kind Regards
> > >>>>>>> Chandan
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> -----Original Message-----
> > >>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > >>>>>>> Sent: Wednesday, February 18, 2015 6:22 PM
> > >>>>>>> To: user@olingo.apache.org
> > >>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> > >>>>>>> 
> > >>>>>>> Hello Chandan,
> > >>>>>>> 
> > >>>>>>> I finally had some success in using JTA based transactions.
> > >>>>>>> However,
> > >>>>>>> this
> > >>>>>>> only worked when I cloned the current git and changed it in the
> > >>>>>>> JPAProcessorImpl directly; If I try to do this from within my
> > >>>>>>> project
> > >>>>>>> onto
> > >>>>>>> the intialization with
> > >>>>>>> 
> > >>>>>>> oDatJPAContext.setODataProcessor(new
> > >>>>>>> ODataJPAProcessorJTA(oDatJPAContext));
> > >>>>>>> 
> > >>>>>>> I then have to do a ODataJPAProcessorJTA which is 99% copy n paste
> > >>>>>>> from
> > >>>>>>> ODataJPAProcessor and then also need a 95% copy n paste
> > >>>>>>> JPAProcessorImplJTA
> > >>>>>>> from JPAProcessorImpl;
> > >>>>>>> 
> > >>>>>>> As if this isn't ugly enough, it gets real dirty when trying to use
> > >>>>>>> it
> > >>>>>>> as
> > >>>>>>> you
> > >>>>>>> simply cant force olingo to use it! Problem is that it comes from
> > >>>>>>> the
> > >>>>>>> JPAAccessFactoryImpl class static; is a static one and sits in
> > >>>>>>> ODataJPAFactoryImpl and finally this one gets called in public
> > >>>>>>> abstract
> > >>>>>>> class ODataJPAFactory
> > >>>>>>> 
> > >>>>>>> using
> > >>>>>>> 
> > >>>>>>> public static ODataJPAFactory createFactory() {
> > >>>>>>> 
> > >>>>>>>  if (factoryImpl != null) {
> > >>>>>>>    return factoryImpl;
> > >>>>>>>  } else {
> > >>>>>>>    try {
> > >>>>>>>      Class<?> clazz =
> > >>>>>>>      Class.forName(ODataJPAFactory.IMPLEMENTATION);
> > >>>>>>> 
> > >>>>>>>      Object object = clazz.newInstance();
> > >>>>>>>      factoryImpl = (ODataJPAFactory) object;
> > >>>>>>> 
> > >>>>>>>    } catch (Exception e) {
> > >>>>>>>      throw new RuntimeException(e);
> > >>>>>>>    }
> > >>>>>>> 
> > >>>>>>>    return factoryImpl;
> > >>>>>>>  }
> > >>>>>>> }
> > >>>>>>> 
> > >>>>>>> where private static final String IMPLEMENTATION =
> > >>>>>>>    "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> Simple said - overriding this logic in the olingo project is next
> > >>>>>>> to
> > >>>>>>> impossible as you would end up with nearly the whole project
> > >>>>>>> copy'n'pasted
> > >>>>>>> over; Simple changing the e.g.  resolver etc. wont works as there
> > >>>>>>> are
> > >>>>>>> many
> > >>>>>>> usages of the ODataJPAFactory createFactory() method;
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> Implementing JTA to work in olingo on the other hand is quite easy.
> > >>>>>>> You
> > >>>>>>> can
> > >>>>>>> check on the fly if your JTA or not via e.g.:
> > >>>>>>> 
> > >>>>>>> public static boolean isResourceLocal(EntityManager em) {
> > >>>>>>>      try {
> > >>>>>>>          EntityTransaction tx = em.getTransaction();
> > >>>>>>>          return true;
> > >>>>>>>      } catch (IllegalStateException ex) {
> > >>>>>>>          return false;
> > >>>>>>>      }
> > >>>>>>>  }
> > >>>>>>> 
> > >>>>>>> and this one can then set into a boolean var classwide in the
> > >>>>>>> JPAProcessorImpl; so the setTransaction would become:
> > >>>>>>> 
> > >>>>>>> private boolean setTransaction() {
> > >>>>>>>    if(isLocalTX) {
> > >>>>>>>        final EntityTransaction transaction = em.getTransaction();
> > >>>>>>>        if (!transaction.isActive()) {
> > >>>>>>>            em.getTransaction().begin();
> > >>>>>>>            return true;
> > >>>>>>>        }
> > >>>>>>>    } else {
> > >>>>>>>        try {
> > >>>>>>>            transaction = (UserTransaction) new
> > >>>>>>>            InitialContext().lookup("java:comp/UserTransaction");
> > >>>>>>>            transaction.begin();
> > >>>>>>>        } catch (NamingException e) {
> > >>>>>>>            e.printStackTrace();
> > >>>>>>>        } catch (NotSupportedException e) {
> > >>>>>>>            e.printStackTrace();
> > >>>>>>>        } catch (SystemException e) {
> > >>>>>>>            e.printStackTrace();
> > >>>>>>>        }
> > >>>>>>>    }
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>>  return false;
> > >>>>>>> }
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> and this would work on all JTA bases Servers. The rest of the
> > >>>>>>> transaction
> > >>>>>>> logic would simply look like e.g.:
> > >>>>>>> 
> > >>>>>>> if (isLocalTransaction) {
> > >>>>>>>      em.getTransaction().commit();
> > >>>>>>>    }
> > >>>>>>> if(transaction != null) {
> > >>>>>>>          transaction.commit();
> > >>>>>>>    }
> > >>>>>>> Or even
> > >>>>>>> if (isLocalTransaction) {
> > >>>>>>>      em.getTransaction().commit();
> > >>>>>>>    }
> > >>>>>>> else {
> > >>>>>>>          transaction.commit();
> > >>>>>>>    }
> > >>>>>>> in case we expect a 100% availbilty of transactional context;
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> Problem is now that this needs at least the dependency of
> > >>>>>>>      <dependency>
> > >>>>>>>          <groupId>javax</groupId>
> > >>>>>>>          <artifactId>javaee-api</artifactId>
> > >>>>>>>          <version>6.0</version>
> > >>>>>>>      </dependency>
> > >>>>>>> as else there is no UserTransaction class available; Would this
> > >>>>>>> dependency
> > >>>>>>> be
> > >>>>>>> ok for the JPA part of the olingo project?
> > >>>>>>> 
> > >>>>>>> What do you think?
> > >>>>>>> 
> > >>>>>>> Best,
> > >>>>>>> 
> > >>>>>>> Korbinian
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>>> ----- Ursprüngliche Mail -----
> > >>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > >>>>>>>> An: user@olingo.apache.org
> > >>>>>>>> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
> > >>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > >>>>>>>> 
> > >>>>>>>> Hello Korbinian,
> > >>>>>>>> Please check the JIRA item -
> > >>>>>>>> https://issues.apache.org/jira/browse/OLINGO-549
> > >>>>>>>> for updates on Olingo V4 JPA processor. Current status is there is
> > >>>>>>>> no
> > >>>>>>>> support for V4 JPA processor and the development is in progress.
> > >>>>>>>> 
> > >>>>>>>> Thanks
> > >>>>>>>> Kind Regards
> > >>>>>>>> Chandan
> > >>>>>>>> 
> > >>>>>>>> -----Original Message-----
> > >>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > >>>>>>>> Sent: Wednesday, February 18, 2015 2:48 PM
> > >>>>>>>> To: user@olingo.apache.org
> > >>>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> > >>>>>>>> 
> > >>>>>>>> Hello Chandan,
> > >>>>>>>> 
> > >>>>>>>> thank you for the info. Will try this. I've seen that Olingo also
> > >>>>>>>> has
> > >>>>>>>> a
> > >>>>>>>> OData
> > >>>>>>>> V4 in Beta2 - but I couldn't really find information about its
> > >>>>>>>> "readyness".
> > >>>>>>>> Would it work in a simple CRUD scenario with JPA? Reason is as it
> > >>>>>>>> seems
> > >>>>>>>> as
> > >>>>>>>> my other system I talk to via OData is moving from V3 to V4
> > >>>>>>>> currently,
> > >>>>>>>> at
> > >>>>>>>> least the doc of its alredy speaks of OData V4 ready.
> > >>>>>>>> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
> > >>>>>>>> 
> > >>>>>>>> Best,
> > >>>>>>>> 
> > >>>>>>>> Korbinian
> > >>>>>>>> 
> > >>>>>>>> 
> > >>>>>>>> 
> > >>>>>>>> ----- Ursprüngliche Mail -----
> > >>>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> > >>>>>>>>> An: user@olingo.apache.org
> > >>>>>>>>> Gesendet: Dienstag, 17. Februar 2015 07:11:28
> > >>>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> > >>>>>>>>> 
> > >>>>>>>>> Hello Korbinian,
> > >>>>>>>>> You can extend the
> > >>>>>>>>> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and
> > >>>>>>>>> implement
> > >>>>>>>>> the processor methods as it is done in
> > >>>>>>>>> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.
> > >>>>>>>>> In
> > >>>>>>>>> your implementation for Create, Update and Delete you could begin
> > >>>>>>>>> the
> > >>>>>>>>> JTA
> > >>>>>>>>> transaction and close the transaction by either commit or
> > >>>>>>>>> rollback.
> > >>>>>>>>> 
> > >>>>>>>>> I have not tried the scenario with JTA based transactions but
> > >>>>>>>>> only
> > >>>>>>>>> Resource
> > >>>>>>>>> Local based transactions. Please check and tell if the above
> > >>>>>>>>> solution
> > >>>>>>>>> works
> > >>>>>>>>> for your case. Else raise a JIRA feature request to support JTA
> > >>>>>>>>> based
> > >>>>>>>>> transactions.
> > >>>>>>>>> 
> > >>>>>>>>> Regards
> > >>>>>>>>> Chandan
> > >>>>>>>>> 
> > >>>>>>>>> -----Original Message-----
> > >>>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > >>>>>>>>> Sent: Monday, February 16, 2015 2:16 PM
> > >>>>>>>>> To: user@olingo.apache.org
> > >>>>>>>>> Subject: olingo JPA / JTA - wrong transactions used
> > >>>>>>>>> 
> > >>>>>>>>> Hi,
> > >>>>>>>>> 
> > >>>>>>>>> I'm using Olingo 2.0.2 and I can query all items so far. When I
> > >>>>>>>>> want
> > >>>>>>>>> to
> > >>>>>>>>> update content, I get error:
> > >>>>>>>>> 
> > >>>>>>>>> ...
> > >>>>>>>>> <message xml:lang="en">"OData - JPA Runtime: JPA update request
> > >>>>>>>>> is
> > >>>>>>>>> not
> > >>>>>>>>> correct"message>
> > >>>>>>>>>  <innererror>class java.lang.IllegalStateException :
> > >>>>>>>>> Exception Description: Cannot use an EntityTransaction while
> > >>>>>>>>> using
> > >>>>>>>>> JTA.innererror>
> > >>>>>>>>> ....
> > >>>>>>>>> 
> > >>>>>>>>> Digging deeper into the code, I ended up in file
> > >>>>>>>>> ODataJPAContextImpl
> > >>>>>>>>> 
> > >>>>>>>>> and there in the function
> > >>>>>>>>> 
> > >>>>>>>>> private  Object processUpdate(PutMergePatchUriInfo updateView,
> > >>>>>>>>>    final InputStream content, final Map<String, Object>
> > >>>>>>>>>    properties,
> > >>>>>>>>>    final
> > >>>>>>>>>    String requestContentType)
> > >>>>>>>>>    throws ODataJPAModelException, ODataJPARuntimeException {
> > >>>>>>>>> ...
> > >>>>>>>>> boolean isLocalTransaction = setTransaction();
> > >>>>>>>>> 
> > >>>>>>>>> ...
> > >>>>>>>>> }
> > >>>>>>>>> 
> > >>>>>>>>> with
> > >>>>>>>>> 
> > >>>>>>>>> private boolean setTransaction() {
> > >>>>>>>>>  final EntityTransaction transaction = em.getTransaction();
> > >>>>>>>>>  if (!transaction.isActive()) {
> > >>>>>>>>>    em.getTransaction().begin();
> > >>>>>>>>>    return true;
> > >>>>>>>>>  }
> > >>>>>>>>> 
> > >>>>>>>>>  return false;
> > >>>>>>>>> }
> > >>>>>>>>> 
> > >>>>>>>>> 
> > >>>>>>>>> So far I understood this one is the function that collides with
> > >>>>>>>>> my
> > >>>>>>>>> JTA
> > >>>>>>>>> setup.
> > >>>>>>>>> I now wonder how I can suppress to initialize this method?
> > >>>>>>>>> 
> > >>>>>>>>> I've sending in the right EntityManagerFactory into Olingo, e.g.:
> > >>>>>>>>> 
> > >>>>>>>>> public class ConnectorODataJPAServiceFactory extends
> > >>>>>>>>> ODataJPAServiceFactory
> > >>>>>>>>> {
> > >>>>>>>>> 
> > >>>>>>>>>  private static final String PERSISTENCE_UNIT_NAME = "myPU";
> > >>>>>>>>> 
> > >>>>>>>>>  @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
> > >>>>>>>>>  EntityManagerFactory emf;
> > >>>>>>>>> 
> > >>>>>>>>> 
> > >>>>>>>>>  @Override
> > >>>>>>>>>  public ODataJPAContext initializeODataJPAContext() throws
> > >>>>>>>>>  ODataJPARuntimeException {
> > >>>>>>>>>      ODataJPAContext oDatJPAContext = this.getODataJPAContext();
> > >>>>>>>>> 
> > >>>>>>>>>      try {
> > >>>>>>>>>          CdiContainer.get().getNonContextualManager().postConstruct(this);
> > >>>>>>>>>          oDatJPAContext.setEntityManagerFactory(emf);
> > >>>>>>>>>          oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
> > >>>>>>>>>          oDatJPAContext.setPageSize(100);
> > >>>>>>>>>          setDetailErrors(true);
> > >>>>>>>>>          return oDatJPAContext;
> > >>>>>>>>>      } catch (Exception e) {
> > >>>>>>>>>          System.out.print(e);
> > >>>>>>>>>          throw new RuntimeException(e);
> > >>>>>>>>>      }
> > >>>>>>>>>  }
> > >>>>>>>>> 
> > >>>>>>>>> ...
> > >>>>>>>>> 
> > >>>>>>>>> So where is the catch here?
> > >>>>>>>>> 
> > >>>>>>>>> 
> > >>>>>>>>> Best,
> > >>>>>>>>> 
> > >>>>>>>>> Korbinian
> > >>>>>>>>> 
> > >>>>>>>> 
> > >>>>>>> 
> > >>>>>> 
> > >>>> 
> > >>>> 
> > >> 
> > >> 
> > 
> > 
> 

Re: olingo JPA / JTA - wrong transactions used

Posted by Korbinian Bachl <ko...@whiskyworld.de>.
thanks to IDEA's magic.... https://github.com/kbachl/olingo-odata2/commit/28c662bc70000faa0c331c90d50a63f7f21c4c11

Best,

Korbinian 


----- Ursprüngliche Mail -----
> Von: "Michael Bolz" <mi...@sap.com>
> An: "Chandan V.A" <ch...@sap.com>
> CC: user@olingo.apache.org
> Gesendet: Donnerstag, 26. Februar 2015 12:59:46
> Betreff: Re: olingo JPA / JTA - wrong transactions used
> 
> Hello all,
> 
> after a first look I agree with the suggestion from Chandan.
> So from my side a +1 for a minor rename ;o)
> 
> Kind regards,
> Michael
> 
> > On 26 Feb 2015, at 12:11, V.A, Chandan <ch...@sap.com> wrote:
> > 
> > Hello Korbinian,
> > I did a quick review of the code and at first sight looks fine. I have few
> > comments with respect to the name. I feel ODataJPATransaction will be more
> > appropriate than ODataJPATransactionContext. Because we are executing
> > transaction steps using this interface and not just setting and getting
> > values.
> > WDYT?
> > 
> > Proposal
> > public interface ODataJPATransaction {
> > 	void begin();
> > 	void rollback();
> > 	void commit();
> > 	void isActive();
> > }
> > 
> > The class name for default implementation can be
> > ODataJPATransactionLocalDefault.
> > 
> > Thanks
> > Kind Regards
> > Chandan
> > 
> > -----Original Message-----
> > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > Sent: Thursday, February 26, 2015 4:09 PM
> > To: user@olingo.apache.org; Bolz, Michael
> > Subject: Re: olingo JPA / JTA - wrong transactions used
> > 
> > Here you go: https://github.com/apache/olingo-odata2/pull/2
> > 
> > Best,
> > 
> > Korbinian
> > 
> > 
> > ----- Ursprüngliche Mail -----
> >> Von: "Michael Bolz" <mi...@sap.com>
> >> An: user@olingo.apache.org
> >> CC: "korbinian bachl" <ko...@whiskyworld.de>
> >> Gesendet: Donnerstag, 26. Februar 2015 08:56:45
> >> Betreff: Re: olingo JPA / JTA - wrong transactions used
> >> 
> >> Hello Korbinian,
> >> 
> >> I would prefer to add this just at “ODataJPAServiceFactory”.
> >> First this way it is consistent with the “setODataTransactionContext” and
> >> second the callback is only related to database (JTA) dependent (using)
> >> OData services.
> >> @Korbinian and Chandan: I think (hope) you both agree with my opinion  ;o)
> >> 
> >> When you send me the pull request I will check it and afterwards merge
> >> into
> >> Olingo master.
> >> 
> >> Kind regards,
> >> Michael
> >> 
> >>> On 25 Feb 2015, at 12:17, Korbinian Bachl
> >>> <ko...@whiskyworld.de>
> >>> wrote:
> >>> 
> >>> Hello Michael,
> >>> 
> >>> I've looked at the suggested OnJPAWriteContent-approach and this would
> >>> work. Question is just if the callback should be implemented within
> >>> ODataServiceFactory or just within ODataJPAServiceFactory;
> >>> 
> >>> Either way we would need one (1) interface
> >>> 
> >>> public interface ODataTransactionContext extends ODataCallback {
> >>> 
> >>> public void startTransaction();
> >>> 
> >>> public void commitTransaction();
> >>> 
> >>> public void rollbackTransaction();
> >>> 
> >>> public boolean transactionIsActive();
> >>> 
> >>> }
> >>> 
> >>> as well as 1 class that implements the current default;
> >>> 
> >>> it would be put into the Factory class like
> >>> 
> >>> protected void setODataTransactionContext(final ODataTransactionContext
> >>> oDataTransactionContext) {
> >>>   this.oDataTransactionContext = oDataTransactionContext;
> >>> }
> >>> 
> >>> and any access to transactions would then need to run via
> >>> getTransactionContext() e.g.:
> >>> 
> >>> FactoryClassInstace.getTransactionContext().startTransaction();
> >>> 
> >>> (or if you want the more noisy version:
> >>> FactoryClassInstace.getCallback(ODataTransactionContext.class).startTransaction();
> >>> - something I really dont like as this calling stack of
> >>> if(callbackInterface.isAssignableFrom... ) is something I see waste of
> >>> CPU
> >>> cycles in regular and often called code areas, bad habbit IMHO)
> >>> 
> >>> 
> >>> Any other usages like JTA can then override the
> >>> setODataTransactionContext(...) and supply a class that "does" exactly
> >>> what needed.
> >>> 
> >>> 
> >>> If this is the way to go, then just let me know which "way" you want it
> >>> and
> >>> I can send you a pull request for it (on github);
> >>> 
> >>> 
> >>> 
> >>> Best,
> >>> 
> >>> Korbinian
> >>> 
> >>> ----- Ursprüngliche Mail -----
> >>>> Von: "Michael Bolz" <mi...@sap.com>
> >>>> An: user@olingo.apache.org
> >>>> Gesendet: Montag, 23. Februar 2015 11:03:40
> >>>> Betreff: Re: olingo JPA / JTA - wrong transactions used
> >>>> 
> >>>> Hi,
> >>>> 
> >>>> could a solution with the “Callback” approach (like the
> >>>> “OnJPAWriteContent”)
> >>>> work for this?
> >>>> So that the “ODataTransactionContext” is implemented as
> >>>> “ODataTransactionCallback”?
> >>>> 
> >>>> This way in the “ODataJPAServiceFactory” a method like: "protected void
> >>>> setTransactionCallback(final ODataTransactionCallback callback)” can be
> >>>> provided and
> >>>> if someone want to implement (inherit) his own “ODataServiceFactory” he
> >>>> can
> >>>> support the callback (interface) directly via the “getCallback(…)”
> >>>> method.
> >>>> 
> >>>> Kind regards,
> >>>> Michael
> >>>> 
> >>>> 
> >>>>> On 23 Feb 2015, at 10:17, Korbinian Bachl
> >>>>> <ko...@whiskyworld.de>
> >>>>> wrote:
> >>>>> 
> >>>>> Hello Chandan,
> >>>>> 
> >>>>> I've looked into the ODataServiceFactory and its usages and I really
> >>>>> dont
> >>>>> think this is good. Problems are
> >>>>> 
> >>>>> a, ODataServiceFactory is in lib module - so no external dependency
> >>>>> should
> >>>>> be pulled into
> >>>>> b, just extending the class like I suggested wont work as we would have
> >>>>> to
> >>>>> fix over 13 implementations of this Factory as well - not speaking
> >>>>> about
> >>>>> any custom implementations so far;
> >>>>> c, I currently dont see the "need" to have JTA outside of JPA context -
> >>>>> since no one ever asked for it;
> >>>>> 
> >>>>> What I can think of is a CustomTransaction class object that gets its
> >>>>> "hold" within ODataServiceFactory and needs to be setup by the
> >>>>> implementation of the ODataServiceFactory only if it needs to use it.
> >>>>> Something like e.g.:
> >>>>> 
> >>>>> in ODataServiceFactory:
> >>>>> ----------
> >>>>> private ODataTransactionContext = null;
> >>>>> 
> >>>>> //stub - needs to be implemented if want to be used
> >>>>> public void setUpTransactionContext() {};
> >>>>> 
> >>>>> public getODataTransactionContext() {
> >>>>>     return ODataTransactionContext;
> >>>>> }
> >>>>> 
> >>>>> public setODataTransactionContext(ODataTransactionContext ctx) {...}
> >>>>> 
> >>>>> ---------
> >>>>> 
> >>>>> 
> >>>>> and ODataTransactionContext could be some kind of abstract class that
> >>>>> has
> >>>>> the methods
> >>>>> 
> >>>>> public abstract class ODataTransactionContext {
> >>>>> 
> >>>>> public abstract void commitTransaction();
> >>>>> 
> >>>>> public abstract void startTransaction();
> >>>>> 
> >>>>> public abstract void rollbackTransaction();
> >>>>> 
> >>>>> public abstract boolean transactionIsActive();
> >>>>> 
> >>>>> }
> >>>>> 
> >>>>> -------
> >>>>> 
> >>>>> IMHO looks ugly; But using an interface for this would be even more
> >>>>> ugly....
> >>>>> 
> >>>>> 
> >>>>> Best,
> >>>>> 
> >>>>> Korbinian
> >>>>> 
> >>>>> 
> >>>>> ----- Ursprüngliche Mail -----
> >>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>> An: user@olingo.apache.org
> >>>>>> Gesendet: Donnerstag, 19. Februar 2015 08:07:59
> >>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>> 
> >>>>>> Hello Korbinian,
> >>>>>> I could have kept the methods as part of ODataJPAServiceFactory but
> >>>>>> the
> >>>>>> problem is, extending the ODataJPAServiceFactory class for an
> >>>>>> application
> >>>>>> is
> >>>>>> optional. Applications can create their own factory classes by
> >>>>>> directly
> >>>>>> inheriting ODataServiceFactory. We need to support such applications
> >>>>>> as
> >>>>>> well. I have created the JIRA issue
> >>>>>> https://issues.apache.org/jira/browse/OLINGO-580 to implement support
> >>>>>> for
> >>>>>> JTA based transactions.
> >>>>>> 
> >>>>>> Thanks
> >>>>>> Kind Regards
> >>>>>> Chandan
> >>>>>> 
> >>>>>> -----Original Message-----
> >>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>> Sent: Wednesday, February 18, 2015 7:30 PM
> >>>>>> To: user@olingo.apache.org
> >>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>>>> 
> >>>>>> Hello Chandan,
> >>>>>> 
> >>>>>> sounds good. What I would do - based upon your idea - is to extend the
> >>>>>> ODataJPAServiceFactory with 4 methods (as this one has to be used in
> >>>>>> any
> >>>>>> case):
> >>>>>> 
> >>>>>> public static void startTransaction(EntityManager em, Object
> >>>>>> transaction)
> >>>>>> {
> >>>>>>  em.getTransaction().begin();
> >>>>>>  transaction = em.getTransaction();
> >>>>>> }
> >>>>>> 
> >>>>>> public static void commitTransaction(Object transaction) {
> >>>>>>  ((EntitiyTransaction) transaction).commit();
> >>>>>> }
> >>>>>> 
> >>>>>> public static void rollbackTransaction(Object transaction) {
> >>>>>>  ((EntitiyTransaction) transaction).rollback();
> >>>>>> }
> >>>>>> 
> >>>>>> public static boolean transactionIsActive(Object transaction) {
> >>>>>> return ((EntitiyTransaction) transaction).isActive();
> >>>>>> }
> >>>>>> 
> >>>>>> These then would be called from wherever olingo JPA needs them.
> >>>>>> 
> >>>>>> That way any one needing JTA can override these methods while the rest
> >>>>>> won't
> >>>>>> even notice them...
> >>>>>> 
> >>>>>> 
> >>>>>> What do you think?
> >>>>>> 
> >>>>>> Best,
> >>>>>> 
> >>>>>> Korbinian
> >>>>>> 
> >>>>>> 
> >>>>>> 
> >>>>>> 
> >>>>>> 
> >>>>>> ----- Ursprüngliche Mail -----
> >>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>>> An: user@olingo.apache.org
> >>>>>>> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
> >>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>>> 
> >>>>>>> Hello Korbinian,
> >>>>>>> I would at least keep the application managed transactions (like JTA)
> >>>>>>> outside
> >>>>>>> the context of JPA Processor for following reasons
> >>>>>>> 1) Wiring the JTA transactions into JPA processor could make the
> >>>>>>> processor
> >>>>>>> to
> >>>>>>> behave more like a framework than as a library (which is the current
> >>>>>>> state).
> >>>>>>> 2) JPA processor also need to take JNDI lookup as parameter from
> >>>>>>> applications
> >>>>>>> for looking up the datasource.
> >>>>>>> 3) Olingo JPA processor should take care of just data transformations
> >>>>>>> and
> >>>>>>> need not worry about the scope of transactions
> >>>>>>> 4) Olingo JPA processor should not take dependency to J2EE api
> >>>>>>> because
> >>>>>>> I
> >>>>>>> am
> >>>>>>> not sure will this artifact work in OSGI environments
> >>>>>>> 
> >>>>>>> One proposal from my side would be to provide a callback mechanism
> >>>>>>> for
> >>>>>>> transaction handling, where the library just calls a method in the
> >>>>>>> interface
> >>>>>>> to begin the transaction and end the transaction. If no one
> >>>>>>> implements
> >>>>>>> the
> >>>>>>> callback mechanism the library would resort to "RESOURCE_LOCAL" based
> >>>>>>> transaction handling. With this approach applications will have a
> >>>>>>> greater
> >>>>>>> control over transaction handling and also need not rewrite
> >>>>>>> JPAProcessorImpl
> >>>>>>> or extend ODataJPAProcessor.
> >>>>>>> 
> >>>>>>> What do you think? Do you foresee any shortcomings with this
> >>>>>>> approach?
> >>>>>>> 
> >>>>>>> Thanks
> >>>>>>> Kind Regards
> >>>>>>> Chandan
> >>>>>>> 
> >>>>>>> 
> >>>>>>> 
> >>>>>>> -----Original Message-----
> >>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>>> Sent: Wednesday, February 18, 2015 6:22 PM
> >>>>>>> To: user@olingo.apache.org
> >>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>>>>> 
> >>>>>>> Hello Chandan,
> >>>>>>> 
> >>>>>>> I finally had some success in using JTA based transactions. However,
> >>>>>>> this
> >>>>>>> only worked when I cloned the current git and changed it in the
> >>>>>>> JPAProcessorImpl directly; If I try to do this from within my project
> >>>>>>> onto
> >>>>>>> the intialization with
> >>>>>>> 
> >>>>>>> oDatJPAContext.setODataProcessor(new
> >>>>>>> ODataJPAProcessorJTA(oDatJPAContext));
> >>>>>>> 
> >>>>>>> I then have to do a ODataJPAProcessorJTA which is 99% copy n paste
> >>>>>>> from
> >>>>>>> ODataJPAProcessor and then also need a 95% copy n paste
> >>>>>>> JPAProcessorImplJTA
> >>>>>>> from JPAProcessorImpl;
> >>>>>>> 
> >>>>>>> As if this isn't ugly enough, it gets real dirty when trying to use
> >>>>>>> it
> >>>>>>> as
> >>>>>>> you
> >>>>>>> simply cant force olingo to use it! Problem is that it comes from the
> >>>>>>> JPAAccessFactoryImpl class static; is a static one and sits in
> >>>>>>> ODataJPAFactoryImpl and finally this one gets called in public
> >>>>>>> abstract
> >>>>>>> class ODataJPAFactory
> >>>>>>> 
> >>>>>>> using
> >>>>>>> 
> >>>>>>> public static ODataJPAFactory createFactory() {
> >>>>>>> 
> >>>>>>>  if (factoryImpl != null) {
> >>>>>>>    return factoryImpl;
> >>>>>>>  } else {
> >>>>>>>    try {
> >>>>>>>      Class<?> clazz = Class.forName(ODataJPAFactory.IMPLEMENTATION);
> >>>>>>> 
> >>>>>>>      Object object = clazz.newInstance();
> >>>>>>>      factoryImpl = (ODataJPAFactory) object;
> >>>>>>> 
> >>>>>>>    } catch (Exception e) {
> >>>>>>>      throw new RuntimeException(e);
> >>>>>>>    }
> >>>>>>> 
> >>>>>>>    return factoryImpl;
> >>>>>>>  }
> >>>>>>> }
> >>>>>>> 
> >>>>>>> where private static final String IMPLEMENTATION =
> >>>>>>>    "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
> >>>>>>> 
> >>>>>>> 
> >>>>>>> Simple said - overriding this logic in the olingo project is next to
> >>>>>>> impossible as you would end up with nearly the whole project
> >>>>>>> copy'n'pasted
> >>>>>>> over; Simple changing the e.g.  resolver etc. wont works as there are
> >>>>>>> many
> >>>>>>> usages of the ODataJPAFactory createFactory() method;
> >>>>>>> 
> >>>>>>> 
> >>>>>>> Implementing JTA to work in olingo on the other hand is quite easy.
> >>>>>>> You
> >>>>>>> can
> >>>>>>> check on the fly if your JTA or not via e.g.:
> >>>>>>> 
> >>>>>>> public static boolean isResourceLocal(EntityManager em) {
> >>>>>>>      try {
> >>>>>>>          EntityTransaction tx = em.getTransaction();
> >>>>>>>          return true;
> >>>>>>>      } catch (IllegalStateException ex) {
> >>>>>>>          return false;
> >>>>>>>      }
> >>>>>>>  }
> >>>>>>> 
> >>>>>>> and this one can then set into a boolean var classwide in the
> >>>>>>> JPAProcessorImpl; so the setTransaction would become:
> >>>>>>> 
> >>>>>>> private boolean setTransaction() {
> >>>>>>>    if(isLocalTX) {
> >>>>>>>        final EntityTransaction transaction = em.getTransaction();
> >>>>>>>        if (!transaction.isActive()) {
> >>>>>>>            em.getTransaction().begin();
> >>>>>>>            return true;
> >>>>>>>        }
> >>>>>>>    } else {
> >>>>>>>        try {
> >>>>>>>            transaction = (UserTransaction) new
> >>>>>>>            InitialContext().lookup("java:comp/UserTransaction");
> >>>>>>>            transaction.begin();
> >>>>>>>        } catch (NamingException e) {
> >>>>>>>            e.printStackTrace();
> >>>>>>>        } catch (NotSupportedException e) {
> >>>>>>>            e.printStackTrace();
> >>>>>>>        } catch (SystemException e) {
> >>>>>>>            e.printStackTrace();
> >>>>>>>        }
> >>>>>>>    }
> >>>>>>> 
> >>>>>>> 
> >>>>>>>  return false;
> >>>>>>> }
> >>>>>>> 
> >>>>>>> 
> >>>>>>> and this would work on all JTA bases Servers. The rest of the
> >>>>>>> transaction
> >>>>>>> logic would simply look like e.g.:
> >>>>>>> 
> >>>>>>> if (isLocalTransaction) {
> >>>>>>>      em.getTransaction().commit();
> >>>>>>>    }
> >>>>>>> if(transaction != null) {
> >>>>>>>          transaction.commit();
> >>>>>>>    }
> >>>>>>> Or even
> >>>>>>> if (isLocalTransaction) {
> >>>>>>>      em.getTransaction().commit();
> >>>>>>>    }
> >>>>>>> else {
> >>>>>>>          transaction.commit();
> >>>>>>>    }
> >>>>>>> in case we expect a 100% availbilty of transactional context;
> >>>>>>> 
> >>>>>>> 
> >>>>>>> 
> >>>>>>> Problem is now that this needs at least the dependency of
> >>>>>>>      <dependency>
> >>>>>>>          <groupId>javax</groupId>
> >>>>>>>          <artifactId>javaee-api</artifactId>
> >>>>>>>          <version>6.0</version>
> >>>>>>>      </dependency>
> >>>>>>> as else there is no UserTransaction class available; Would this
> >>>>>>> dependency
> >>>>>>> be
> >>>>>>> ok for the JPA part of the olingo project?
> >>>>>>> 
> >>>>>>> What do you think?
> >>>>>>> 
> >>>>>>> Best,
> >>>>>>> 
> >>>>>>> Korbinian
> >>>>>>> 
> >>>>>>> 
> >>>>>>> 
> >>>>>>> ----- Ursprüngliche Mail -----
> >>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>>>> An: user@olingo.apache.org
> >>>>>>>> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
> >>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>>>> 
> >>>>>>>> Hello Korbinian,
> >>>>>>>> Please check the JIRA item -
> >>>>>>>> https://issues.apache.org/jira/browse/OLINGO-549
> >>>>>>>> for updates on Olingo V4 JPA processor. Current status is there is
> >>>>>>>> no
> >>>>>>>> support for V4 JPA processor and the development is in progress.
> >>>>>>>> 
> >>>>>>>> Thanks
> >>>>>>>> Kind Regards
> >>>>>>>> Chandan
> >>>>>>>> 
> >>>>>>>> -----Original Message-----
> >>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>>>> Sent: Wednesday, February 18, 2015 2:48 PM
> >>>>>>>> To: user@olingo.apache.org
> >>>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>>>>>> 
> >>>>>>>> Hello Chandan,
> >>>>>>>> 
> >>>>>>>> thank you for the info. Will try this. I've seen that Olingo also
> >>>>>>>> has
> >>>>>>>> a
> >>>>>>>> OData
> >>>>>>>> V4 in Beta2 - but I couldn't really find information about its
> >>>>>>>> "readyness".
> >>>>>>>> Would it work in a simple CRUD scenario with JPA? Reason is as it
> >>>>>>>> seems
> >>>>>>>> as
> >>>>>>>> my other system I talk to via OData is moving from V3 to V4
> >>>>>>>> currently,
> >>>>>>>> at
> >>>>>>>> least the doc of its alredy speaks of OData V4 ready.
> >>>>>>>> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
> >>>>>>>> 
> >>>>>>>> Best,
> >>>>>>>> 
> >>>>>>>> Korbinian
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>> ----- Ursprüngliche Mail -----
> >>>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>>>>> An: user@olingo.apache.org
> >>>>>>>>> Gesendet: Dienstag, 17. Februar 2015 07:11:28
> >>>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>>>>> 
> >>>>>>>>> Hello Korbinian,
> >>>>>>>>> You can extend the
> >>>>>>>>> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and
> >>>>>>>>> implement
> >>>>>>>>> the processor methods as it is done in
> >>>>>>>>> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.
> >>>>>>>>> In
> >>>>>>>>> your implementation for Create, Update and Delete you could begin
> >>>>>>>>> the
> >>>>>>>>> JTA
> >>>>>>>>> transaction and close the transaction by either commit or rollback.
> >>>>>>>>> 
> >>>>>>>>> I have not tried the scenario with JTA based transactions but only
> >>>>>>>>> Resource
> >>>>>>>>> Local based transactions. Please check and tell if the above
> >>>>>>>>> solution
> >>>>>>>>> works
> >>>>>>>>> for your case. Else raise a JIRA feature request to support JTA
> >>>>>>>>> based
> >>>>>>>>> transactions.
> >>>>>>>>> 
> >>>>>>>>> Regards
> >>>>>>>>> Chandan
> >>>>>>>>> 
> >>>>>>>>> -----Original Message-----
> >>>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>>>>> Sent: Monday, February 16, 2015 2:16 PM
> >>>>>>>>> To: user@olingo.apache.org
> >>>>>>>>> Subject: olingo JPA / JTA - wrong transactions used
> >>>>>>>>> 
> >>>>>>>>> Hi,
> >>>>>>>>> 
> >>>>>>>>> I'm using Olingo 2.0.2 and I can query all items so far. When I
> >>>>>>>>> want
> >>>>>>>>> to
> >>>>>>>>> update content, I get error:
> >>>>>>>>> 
> >>>>>>>>> ...
> >>>>>>>>> <message xml:lang="en">"OData - JPA Runtime: JPA update request is
> >>>>>>>>> not
> >>>>>>>>> correct"message>
> >>>>>>>>>  <innererror>class java.lang.IllegalStateException :
> >>>>>>>>> Exception Description: Cannot use an EntityTransaction while using
> >>>>>>>>> JTA.innererror>
> >>>>>>>>> ....
> >>>>>>>>> 
> >>>>>>>>> Digging deeper into the code, I ended up in file
> >>>>>>>>> ODataJPAContextImpl
> >>>>>>>>> 
> >>>>>>>>> and there in the function
> >>>>>>>>> 
> >>>>>>>>> private  Object processUpdate(PutMergePatchUriInfo updateView,
> >>>>>>>>>    final InputStream content, final Map<String, Object> properties,
> >>>>>>>>>    final
> >>>>>>>>>    String requestContentType)
> >>>>>>>>>    throws ODataJPAModelException, ODataJPARuntimeException {
> >>>>>>>>> ...
> >>>>>>>>> boolean isLocalTransaction = setTransaction();
> >>>>>>>>> 
> >>>>>>>>> ...
> >>>>>>>>> }
> >>>>>>>>> 
> >>>>>>>>> with
> >>>>>>>>> 
> >>>>>>>>> private boolean setTransaction() {
> >>>>>>>>>  final EntityTransaction transaction = em.getTransaction();
> >>>>>>>>>  if (!transaction.isActive()) {
> >>>>>>>>>    em.getTransaction().begin();
> >>>>>>>>>    return true;
> >>>>>>>>>  }
> >>>>>>>>> 
> >>>>>>>>>  return false;
> >>>>>>>>> }
> >>>>>>>>> 
> >>>>>>>>> 
> >>>>>>>>> So far I understood this one is the function that collides with my
> >>>>>>>>> JTA
> >>>>>>>>> setup.
> >>>>>>>>> I now wonder how I can suppress to initialize this method?
> >>>>>>>>> 
> >>>>>>>>> I've sending in the right EntityManagerFactory into Olingo, e.g.:
> >>>>>>>>> 
> >>>>>>>>> public class ConnectorODataJPAServiceFactory extends
> >>>>>>>>> ODataJPAServiceFactory
> >>>>>>>>> {
> >>>>>>>>> 
> >>>>>>>>>  private static final String PERSISTENCE_UNIT_NAME = "myPU";
> >>>>>>>>> 
> >>>>>>>>>  @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
> >>>>>>>>>  EntityManagerFactory emf;
> >>>>>>>>> 
> >>>>>>>>> 
> >>>>>>>>>  @Override
> >>>>>>>>>  public ODataJPAContext initializeODataJPAContext() throws
> >>>>>>>>>  ODataJPARuntimeException {
> >>>>>>>>>      ODataJPAContext oDatJPAContext = this.getODataJPAContext();
> >>>>>>>>> 
> >>>>>>>>>      try {
> >>>>>>>>>          CdiContainer.get().getNonContextualManager().postConstruct(this);
> >>>>>>>>>          oDatJPAContext.setEntityManagerFactory(emf);
> >>>>>>>>>          oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
> >>>>>>>>>          oDatJPAContext.setPageSize(100);
> >>>>>>>>>          setDetailErrors(true);
> >>>>>>>>>          return oDatJPAContext;
> >>>>>>>>>      } catch (Exception e) {
> >>>>>>>>>          System.out.print(e);
> >>>>>>>>>          throw new RuntimeException(e);
> >>>>>>>>>      }
> >>>>>>>>>  }
> >>>>>>>>> 
> >>>>>>>>> ...
> >>>>>>>>> 
> >>>>>>>>> So where is the catch here?
> >>>>>>>>> 
> >>>>>>>>> 
> >>>>>>>>> Best,
> >>>>>>>>> 
> >>>>>>>>> Korbinian
> >>>>>>>>> 
> >>>>>>>> 
> >>>>>>> 
> >>>>>> 
> >>>> 
> >>>> 
> >> 
> >> 
> 
> 

RE: olingo JPA / JTA - wrong transactions used

Posted by "V.A, Chandan" <ch...@sap.com>.
Hi All,
The support for JTA is implemented by pulling the code from https://github.com/apache/olingo-odata2/pull/2 and applying some adjustments to the code line to be backward compatible. The changes are part of 2.0.4-SNAPSHOT version.

Refer issue - https://issues.apache.org/jira/browse/OLINGO-580 for more details that includes on how to use this feature. In case of bugs feel free to reopen the issue.

Regards
Chandan

-----Original Message-----
From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de] 
Sent: Thursday, February 26, 2015 5:43 PM
To: user@olingo.apache.org
Subject: Re: olingo JPA / JTA - wrong transactions used

everything in: https://github.com/apache/olingo-odata2/pull/2

Now, when will Chandan do the JPA for olingo OData V4? ;)



Best,

Korbinian

----- Ursprüngliche Mail -----
> Von: "Michael Bolz" <mi...@sap.com>
> An: "Chandan V.A" <ch...@sap.com>
> CC: user@olingo.apache.org
> Gesendet: Donnerstag, 26. Februar 2015 12:59:46
> Betreff: Re: olingo JPA / JTA - wrong transactions used
> 
> Hello all,
> 
> after a first look I agree with the suggestion from Chandan.
> So from my side a +1 for a minor rename ;o)
> 
> Kind regards,
> Michael
> 
> > On 26 Feb 2015, at 12:11, V.A, Chandan <ch...@sap.com> wrote:
> > 
> > Hello Korbinian,
> > I did a quick review of the code and at first sight looks fine. I have few
> > comments with respect to the name. I feel ODataJPATransaction will be more
> > appropriate than ODataJPATransactionContext. Because we are executing
> > transaction steps using this interface and not just setting and getting
> > values.
> > WDYT?
> > 
> > Proposal
> > public interface ODataJPATransaction {
> > 	void begin();
> > 	void rollback();
> > 	void commit();
> > 	void isActive();
> > }
> > 
> > The class name for default implementation can be
> > ODataJPATransactionLocalDefault.
> > 
> > Thanks
> > Kind Regards
> > Chandan
> > 
> > -----Original Message-----
> > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > Sent: Thursday, February 26, 2015 4:09 PM
> > To: user@olingo.apache.org; Bolz, Michael
> > Subject: Re: olingo JPA / JTA - wrong transactions used
> > 
> > Here you go: https://github.com/apache/olingo-odata2/pull/2
> > 
> > Best,
> > 
> > Korbinian
> > 
> > 
> > ----- Ursprüngliche Mail -----
> >> Von: "Michael Bolz" <mi...@sap.com>
> >> An: user@olingo.apache.org
> >> CC: "korbinian bachl" <ko...@whiskyworld.de>
> >> Gesendet: Donnerstag, 26. Februar 2015 08:56:45
> >> Betreff: Re: olingo JPA / JTA - wrong transactions used
> >> 
> >> Hello Korbinian,
> >> 
> >> I would prefer to add this just at “ODataJPAServiceFactory”.
> >> First this way it is consistent with the “setODataTransactionContext” and
> >> second the callback is only related to database (JTA) dependent (using)
> >> OData services.
> >> @Korbinian and Chandan: I think (hope) you both agree with my opinion  ;o)
> >> 
> >> When you send me the pull request I will check it and afterwards merge
> >> into
> >> Olingo master.
> >> 
> >> Kind regards,
> >> Michael
> >> 
> >>> On 25 Feb 2015, at 12:17, Korbinian Bachl
> >>> <ko...@whiskyworld.de>
> >>> wrote:
> >>> 
> >>> Hello Michael,
> >>> 
> >>> I've looked at the suggested OnJPAWriteContent-approach and this would
> >>> work. Question is just if the callback should be implemented within
> >>> ODataServiceFactory or just within ODataJPAServiceFactory;
> >>> 
> >>> Either way we would need one (1) interface
> >>> 
> >>> public interface ODataTransactionContext extends ODataCallback {
> >>> 
> >>> public void startTransaction();
> >>> 
> >>> public void commitTransaction();
> >>> 
> >>> public void rollbackTransaction();
> >>> 
> >>> public boolean transactionIsActive();
> >>> 
> >>> }
> >>> 
> >>> as well as 1 class that implements the current default;
> >>> 
> >>> it would be put into the Factory class like
> >>> 
> >>> protected void setODataTransactionContext(final ODataTransactionContext
> >>> oDataTransactionContext) {
> >>>   this.oDataTransactionContext = oDataTransactionContext;
> >>> }
> >>> 
> >>> and any access to transactions would then need to run via
> >>> getTransactionContext() e.g.:
> >>> 
> >>> FactoryClassInstace.getTransactionContext().startTransaction();
> >>> 
> >>> (or if you want the more noisy version:
> >>> FactoryClassInstace.getCallback(ODataTransactionContext.class).startTransaction();
> >>> - something I really dont like as this calling stack of
> >>> if(callbackInterface.isAssignableFrom... ) is something I see waste of
> >>> CPU
> >>> cycles in regular and often called code areas, bad habbit IMHO)
> >>> 
> >>> 
> >>> Any other usages like JTA can then override the
> >>> setODataTransactionContext(...) and supply a class that "does" exactly
> >>> what needed.
> >>> 
> >>> 
> >>> If this is the way to go, then just let me know which "way" you want it
> >>> and
> >>> I can send you a pull request for it (on github);
> >>> 
> >>> 
> >>> 
> >>> Best,
> >>> 
> >>> Korbinian
> >>> 
> >>> ----- Ursprüngliche Mail -----
> >>>> Von: "Michael Bolz" <mi...@sap.com>
> >>>> An: user@olingo.apache.org
> >>>> Gesendet: Montag, 23. Februar 2015 11:03:40
> >>>> Betreff: Re: olingo JPA / JTA - wrong transactions used
> >>>> 
> >>>> Hi,
> >>>> 
> >>>> could a solution with the “Callback” approach (like the
> >>>> “OnJPAWriteContent”)
> >>>> work for this?
> >>>> So that the “ODataTransactionContext” is implemented as
> >>>> “ODataTransactionCallback”?
> >>>> 
> >>>> This way in the “ODataJPAServiceFactory” a method like: "protected void
> >>>> setTransactionCallback(final ODataTransactionCallback callback)” can be
> >>>> provided and
> >>>> if someone want to implement (inherit) his own “ODataServiceFactory” he
> >>>> can
> >>>> support the callback (interface) directly via the “getCallback(…)”
> >>>> method.
> >>>> 
> >>>> Kind regards,
> >>>> Michael
> >>>> 
> >>>> 
> >>>>> On 23 Feb 2015, at 10:17, Korbinian Bachl
> >>>>> <ko...@whiskyworld.de>
> >>>>> wrote:
> >>>>> 
> >>>>> Hello Chandan,
> >>>>> 
> >>>>> I've looked into the ODataServiceFactory and its usages and I really
> >>>>> dont
> >>>>> think this is good. Problems are
> >>>>> 
> >>>>> a, ODataServiceFactory is in lib module - so no external dependency
> >>>>> should
> >>>>> be pulled into
> >>>>> b, just extending the class like I suggested wont work as we would have
> >>>>> to
> >>>>> fix over 13 implementations of this Factory as well - not speaking
> >>>>> about
> >>>>> any custom implementations so far;
> >>>>> c, I currently dont see the "need" to have JTA outside of JPA context -
> >>>>> since no one ever asked for it;
> >>>>> 
> >>>>> What I can think of is a CustomTransaction class object that gets its
> >>>>> "hold" within ODataServiceFactory and needs to be setup by the
> >>>>> implementation of the ODataServiceFactory only if it needs to use it.
> >>>>> Something like e.g.:
> >>>>> 
> >>>>> in ODataServiceFactory:
> >>>>> ----------
> >>>>> private ODataTransactionContext = null;
> >>>>> 
> >>>>> //stub - needs to be implemented if want to be used
> >>>>> public void setUpTransactionContext() {};
> >>>>> 
> >>>>> public getODataTransactionContext() {
> >>>>>     return ODataTransactionContext;
> >>>>> }
> >>>>> 
> >>>>> public setODataTransactionContext(ODataTransactionContext ctx) {...}
> >>>>> 
> >>>>> ---------
> >>>>> 
> >>>>> 
> >>>>> and ODataTransactionContext could be some kind of abstract class that
> >>>>> has
> >>>>> the methods
> >>>>> 
> >>>>> public abstract class ODataTransactionContext {
> >>>>> 
> >>>>> public abstract void commitTransaction();
> >>>>> 
> >>>>> public abstract void startTransaction();
> >>>>> 
> >>>>> public abstract void rollbackTransaction();
> >>>>> 
> >>>>> public abstract boolean transactionIsActive();
> >>>>> 
> >>>>> }
> >>>>> 
> >>>>> -------
> >>>>> 
> >>>>> IMHO looks ugly; But using an interface for this would be even more
> >>>>> ugly....
> >>>>> 
> >>>>> 
> >>>>> Best,
> >>>>> 
> >>>>> Korbinian
> >>>>> 
> >>>>> 
> >>>>> ----- Ursprüngliche Mail -----
> >>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>> An: user@olingo.apache.org
> >>>>>> Gesendet: Donnerstag, 19. Februar 2015 08:07:59
> >>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>> 
> >>>>>> Hello Korbinian,
> >>>>>> I could have kept the methods as part of ODataJPAServiceFactory but
> >>>>>> the
> >>>>>> problem is, extending the ODataJPAServiceFactory class for an
> >>>>>> application
> >>>>>> is
> >>>>>> optional. Applications can create their own factory classes by
> >>>>>> directly
> >>>>>> inheriting ODataServiceFactory. We need to support such applications
> >>>>>> as
> >>>>>> well. I have created the JIRA issue
> >>>>>> https://issues.apache.org/jira/browse/OLINGO-580 to implement support
> >>>>>> for
> >>>>>> JTA based transactions.
> >>>>>> 
> >>>>>> Thanks
> >>>>>> Kind Regards
> >>>>>> Chandan
> >>>>>> 
> >>>>>> -----Original Message-----
> >>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>> Sent: Wednesday, February 18, 2015 7:30 PM
> >>>>>> To: user@olingo.apache.org
> >>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>>>> 
> >>>>>> Hello Chandan,
> >>>>>> 
> >>>>>> sounds good. What I would do - based upon your idea - is to extend the
> >>>>>> ODataJPAServiceFactory with 4 methods (as this one has to be used in
> >>>>>> any
> >>>>>> case):
> >>>>>> 
> >>>>>> public static void startTransaction(EntityManager em, Object
> >>>>>> transaction)
> >>>>>> {
> >>>>>>  em.getTransaction().begin();
> >>>>>>  transaction = em.getTransaction();
> >>>>>> }
> >>>>>> 
> >>>>>> public static void commitTransaction(Object transaction) {
> >>>>>>  ((EntitiyTransaction) transaction).commit();
> >>>>>> }
> >>>>>> 
> >>>>>> public static void rollbackTransaction(Object transaction) {
> >>>>>>  ((EntitiyTransaction) transaction).rollback();
> >>>>>> }
> >>>>>> 
> >>>>>> public static boolean transactionIsActive(Object transaction) {
> >>>>>> return ((EntitiyTransaction) transaction).isActive();
> >>>>>> }
> >>>>>> 
> >>>>>> These then would be called from wherever olingo JPA needs them.
> >>>>>> 
> >>>>>> That way any one needing JTA can override these methods while the rest
> >>>>>> won't
> >>>>>> even notice them...
> >>>>>> 
> >>>>>> 
> >>>>>> What do you think?
> >>>>>> 
> >>>>>> Best,
> >>>>>> 
> >>>>>> Korbinian
> >>>>>> 
> >>>>>> 
> >>>>>> 
> >>>>>> 
> >>>>>> 
> >>>>>> ----- Ursprüngliche Mail -----
> >>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>>> An: user@olingo.apache.org
> >>>>>>> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
> >>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>>> 
> >>>>>>> Hello Korbinian,
> >>>>>>> I would at least keep the application managed transactions (like JTA)
> >>>>>>> outside
> >>>>>>> the context of JPA Processor for following reasons
> >>>>>>> 1) Wiring the JTA transactions into JPA processor could make the
> >>>>>>> processor
> >>>>>>> to
> >>>>>>> behave more like a framework than as a library (which is the current
> >>>>>>> state).
> >>>>>>> 2) JPA processor also need to take JNDI lookup as parameter from
> >>>>>>> applications
> >>>>>>> for looking up the datasource.
> >>>>>>> 3) Olingo JPA processor should take care of just data transformations
> >>>>>>> and
> >>>>>>> need not worry about the scope of transactions
> >>>>>>> 4) Olingo JPA processor should not take dependency to J2EE api
> >>>>>>> because
> >>>>>>> I
> >>>>>>> am
> >>>>>>> not sure will this artifact work in OSGI environments
> >>>>>>> 
> >>>>>>> One proposal from my side would be to provide a callback mechanism
> >>>>>>> for
> >>>>>>> transaction handling, where the library just calls a method in the
> >>>>>>> interface
> >>>>>>> to begin the transaction and end the transaction. If no one
> >>>>>>> implements
> >>>>>>> the
> >>>>>>> callback mechanism the library would resort to "RESOURCE_LOCAL" based
> >>>>>>> transaction handling. With this approach applications will have a
> >>>>>>> greater
> >>>>>>> control over transaction handling and also need not rewrite
> >>>>>>> JPAProcessorImpl
> >>>>>>> or extend ODataJPAProcessor.
> >>>>>>> 
> >>>>>>> What do you think? Do you foresee any shortcomings with this
> >>>>>>> approach?
> >>>>>>> 
> >>>>>>> Thanks
> >>>>>>> Kind Regards
> >>>>>>> Chandan
> >>>>>>> 
> >>>>>>> 
> >>>>>>> 
> >>>>>>> -----Original Message-----
> >>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>>> Sent: Wednesday, February 18, 2015 6:22 PM
> >>>>>>> To: user@olingo.apache.org
> >>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>>>>> 
> >>>>>>> Hello Chandan,
> >>>>>>> 
> >>>>>>> I finally had some success in using JTA based transactions. However,
> >>>>>>> this
> >>>>>>> only worked when I cloned the current git and changed it in the
> >>>>>>> JPAProcessorImpl directly; If I try to do this from within my project
> >>>>>>> onto
> >>>>>>> the intialization with
> >>>>>>> 
> >>>>>>> oDatJPAContext.setODataProcessor(new
> >>>>>>> ODataJPAProcessorJTA(oDatJPAContext));
> >>>>>>> 
> >>>>>>> I then have to do a ODataJPAProcessorJTA which is 99% copy n paste
> >>>>>>> from
> >>>>>>> ODataJPAProcessor and then also need a 95% copy n paste
> >>>>>>> JPAProcessorImplJTA
> >>>>>>> from JPAProcessorImpl;
> >>>>>>> 
> >>>>>>> As if this isn't ugly enough, it gets real dirty when trying to use
> >>>>>>> it
> >>>>>>> as
> >>>>>>> you
> >>>>>>> simply cant force olingo to use it! Problem is that it comes from the
> >>>>>>> JPAAccessFactoryImpl class static; is a static one and sits in
> >>>>>>> ODataJPAFactoryImpl and finally this one gets called in public
> >>>>>>> abstract
> >>>>>>> class ODataJPAFactory
> >>>>>>> 
> >>>>>>> using
> >>>>>>> 
> >>>>>>> public static ODataJPAFactory createFactory() {
> >>>>>>> 
> >>>>>>>  if (factoryImpl != null) {
> >>>>>>>    return factoryImpl;
> >>>>>>>  } else {
> >>>>>>>    try {
> >>>>>>>      Class<?> clazz = Class.forName(ODataJPAFactory.IMPLEMENTATION);
> >>>>>>> 
> >>>>>>>      Object object = clazz.newInstance();
> >>>>>>>      factoryImpl = (ODataJPAFactory) object;
> >>>>>>> 
> >>>>>>>    } catch (Exception e) {
> >>>>>>>      throw new RuntimeException(e);
> >>>>>>>    }
> >>>>>>> 
> >>>>>>>    return factoryImpl;
> >>>>>>>  }
> >>>>>>> }
> >>>>>>> 
> >>>>>>> where private static final String IMPLEMENTATION =
> >>>>>>>    "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
> >>>>>>> 
> >>>>>>> 
> >>>>>>> Simple said - overriding this logic in the olingo project is next to
> >>>>>>> impossible as you would end up with nearly the whole project
> >>>>>>> copy'n'pasted
> >>>>>>> over; Simple changing the e.g.  resolver etc. wont works as there are
> >>>>>>> many
> >>>>>>> usages of the ODataJPAFactory createFactory() method;
> >>>>>>> 
> >>>>>>> 
> >>>>>>> Implementing JTA to work in olingo on the other hand is quite easy.
> >>>>>>> You
> >>>>>>> can
> >>>>>>> check on the fly if your JTA or not via e.g.:
> >>>>>>> 
> >>>>>>> public static boolean isResourceLocal(EntityManager em) {
> >>>>>>>      try {
> >>>>>>>          EntityTransaction tx = em.getTransaction();
> >>>>>>>          return true;
> >>>>>>>      } catch (IllegalStateException ex) {
> >>>>>>>          return false;
> >>>>>>>      }
> >>>>>>>  }
> >>>>>>> 
> >>>>>>> and this one can then set into a boolean var classwide in the
> >>>>>>> JPAProcessorImpl; so the setTransaction would become:
> >>>>>>> 
> >>>>>>> private boolean setTransaction() {
> >>>>>>>    if(isLocalTX) {
> >>>>>>>        final EntityTransaction transaction = em.getTransaction();
> >>>>>>>        if (!transaction.isActive()) {
> >>>>>>>            em.getTransaction().begin();
> >>>>>>>            return true;
> >>>>>>>        }
> >>>>>>>    } else {
> >>>>>>>        try {
> >>>>>>>            transaction = (UserTransaction) new
> >>>>>>>            InitialContext().lookup("java:comp/UserTransaction");
> >>>>>>>            transaction.begin();
> >>>>>>>        } catch (NamingException e) {
> >>>>>>>            e.printStackTrace();
> >>>>>>>        } catch (NotSupportedException e) {
> >>>>>>>            e.printStackTrace();
> >>>>>>>        } catch (SystemException e) {
> >>>>>>>            e.printStackTrace();
> >>>>>>>        }
> >>>>>>>    }
> >>>>>>> 
> >>>>>>> 
> >>>>>>>  return false;
> >>>>>>> }
> >>>>>>> 
> >>>>>>> 
> >>>>>>> and this would work on all JTA bases Servers. The rest of the
> >>>>>>> transaction
> >>>>>>> logic would simply look like e.g.:
> >>>>>>> 
> >>>>>>> if (isLocalTransaction) {
> >>>>>>>      em.getTransaction().commit();
> >>>>>>>    }
> >>>>>>> if(transaction != null) {
> >>>>>>>          transaction.commit();
> >>>>>>>    }
> >>>>>>> Or even
> >>>>>>> if (isLocalTransaction) {
> >>>>>>>      em.getTransaction().commit();
> >>>>>>>    }
> >>>>>>> else {
> >>>>>>>          transaction.commit();
> >>>>>>>    }
> >>>>>>> in case we expect a 100% availbilty of transactional context;
> >>>>>>> 
> >>>>>>> 
> >>>>>>> 
> >>>>>>> Problem is now that this needs at least the dependency of
> >>>>>>>      <dependency>
> >>>>>>>          <groupId>javax</groupId>
> >>>>>>>          <artifactId>javaee-api</artifactId>
> >>>>>>>          <version>6.0</version>
> >>>>>>>      </dependency>
> >>>>>>> as else there is no UserTransaction class available; Would this
> >>>>>>> dependency
> >>>>>>> be
> >>>>>>> ok for the JPA part of the olingo project?
> >>>>>>> 
> >>>>>>> What do you think?
> >>>>>>> 
> >>>>>>> Best,
> >>>>>>> 
> >>>>>>> Korbinian
> >>>>>>> 
> >>>>>>> 
> >>>>>>> 
> >>>>>>> ----- Ursprüngliche Mail -----
> >>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>>>> An: user@olingo.apache.org
> >>>>>>>> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
> >>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>>>> 
> >>>>>>>> Hello Korbinian,
> >>>>>>>> Please check the JIRA item -
> >>>>>>>> https://issues.apache.org/jira/browse/OLINGO-549
> >>>>>>>> for updates on Olingo V4 JPA processor. Current status is there is
> >>>>>>>> no
> >>>>>>>> support for V4 JPA processor and the development is in progress.
> >>>>>>>> 
> >>>>>>>> Thanks
> >>>>>>>> Kind Regards
> >>>>>>>> Chandan
> >>>>>>>> 
> >>>>>>>> -----Original Message-----
> >>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>>>> Sent: Wednesday, February 18, 2015 2:48 PM
> >>>>>>>> To: user@olingo.apache.org
> >>>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>>>>>> 
> >>>>>>>> Hello Chandan,
> >>>>>>>> 
> >>>>>>>> thank you for the info. Will try this. I've seen that Olingo also
> >>>>>>>> has
> >>>>>>>> a
> >>>>>>>> OData
> >>>>>>>> V4 in Beta2 - but I couldn't really find information about its
> >>>>>>>> "readyness".
> >>>>>>>> Would it work in a simple CRUD scenario with JPA? Reason is as it
> >>>>>>>> seems
> >>>>>>>> as
> >>>>>>>> my other system I talk to via OData is moving from V3 to V4
> >>>>>>>> currently,
> >>>>>>>> at
> >>>>>>>> least the doc of its alredy speaks of OData V4 ready.
> >>>>>>>> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
> >>>>>>>> 
> >>>>>>>> Best,
> >>>>>>>> 
> >>>>>>>> Korbinian
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>> ----- Ursprüngliche Mail -----
> >>>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>>>>> An: user@olingo.apache.org
> >>>>>>>>> Gesendet: Dienstag, 17. Februar 2015 07:11:28
> >>>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>>>>> 
> >>>>>>>>> Hello Korbinian,
> >>>>>>>>> You can extend the
> >>>>>>>>> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and
> >>>>>>>>> implement
> >>>>>>>>> the processor methods as it is done in
> >>>>>>>>> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.
> >>>>>>>>> In
> >>>>>>>>> your implementation for Create, Update and Delete you could begin
> >>>>>>>>> the
> >>>>>>>>> JTA
> >>>>>>>>> transaction and close the transaction by either commit or rollback.
> >>>>>>>>> 
> >>>>>>>>> I have not tried the scenario with JTA based transactions but only
> >>>>>>>>> Resource
> >>>>>>>>> Local based transactions. Please check and tell if the above
> >>>>>>>>> solution
> >>>>>>>>> works
> >>>>>>>>> for your case. Else raise a JIRA feature request to support JTA
> >>>>>>>>> based
> >>>>>>>>> transactions.
> >>>>>>>>> 
> >>>>>>>>> Regards
> >>>>>>>>> Chandan
> >>>>>>>>> 
> >>>>>>>>> -----Original Message-----
> >>>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>>>>> Sent: Monday, February 16, 2015 2:16 PM
> >>>>>>>>> To: user@olingo.apache.org
> >>>>>>>>> Subject: olingo JPA / JTA - wrong transactions used
> >>>>>>>>> 
> >>>>>>>>> Hi,
> >>>>>>>>> 
> >>>>>>>>> I'm using Olingo 2.0.2 and I can query all items so far. When I
> >>>>>>>>> want
> >>>>>>>>> to
> >>>>>>>>> update content, I get error:
> >>>>>>>>> 
> >>>>>>>>> ...
> >>>>>>>>> <message xml:lang="en">"OData - JPA Runtime: JPA update request is
> >>>>>>>>> not
> >>>>>>>>> correct"message>
> >>>>>>>>>  <innererror>class java.lang.IllegalStateException :
> >>>>>>>>> Exception Description: Cannot use an EntityTransaction while using
> >>>>>>>>> JTA.innererror>
> >>>>>>>>> ....
> >>>>>>>>> 
> >>>>>>>>> Digging deeper into the code, I ended up in file
> >>>>>>>>> ODataJPAContextImpl
> >>>>>>>>> 
> >>>>>>>>> and there in the function
> >>>>>>>>> 
> >>>>>>>>> private  Object processUpdate(PutMergePatchUriInfo updateView,
> >>>>>>>>>    final InputStream content, final Map<String, Object> properties,
> >>>>>>>>>    final
> >>>>>>>>>    String requestContentType)
> >>>>>>>>>    throws ODataJPAModelException, ODataJPARuntimeException {
> >>>>>>>>> ...
> >>>>>>>>> boolean isLocalTransaction = setTransaction();
> >>>>>>>>> 
> >>>>>>>>> ...
> >>>>>>>>> }
> >>>>>>>>> 
> >>>>>>>>> with
> >>>>>>>>> 
> >>>>>>>>> private boolean setTransaction() {
> >>>>>>>>>  final EntityTransaction transaction = em.getTransaction();
> >>>>>>>>>  if (!transaction.isActive()) {
> >>>>>>>>>    em.getTransaction().begin();
> >>>>>>>>>    return true;
> >>>>>>>>>  }
> >>>>>>>>> 
> >>>>>>>>>  return false;
> >>>>>>>>> }
> >>>>>>>>> 
> >>>>>>>>> 
> >>>>>>>>> So far I understood this one is the function that collides with my
> >>>>>>>>> JTA
> >>>>>>>>> setup.
> >>>>>>>>> I now wonder how I can suppress to initialize this method?
> >>>>>>>>> 
> >>>>>>>>> I've sending in the right EntityManagerFactory into Olingo, e.g.:
> >>>>>>>>> 
> >>>>>>>>> public class ConnectorODataJPAServiceFactory extends
> >>>>>>>>> ODataJPAServiceFactory
> >>>>>>>>> {
> >>>>>>>>> 
> >>>>>>>>>  private static final String PERSISTENCE_UNIT_NAME = "myPU";
> >>>>>>>>> 
> >>>>>>>>>  @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
> >>>>>>>>>  EntityManagerFactory emf;
> >>>>>>>>> 
> >>>>>>>>> 
> >>>>>>>>>  @Override
> >>>>>>>>>  public ODataJPAContext initializeODataJPAContext() throws
> >>>>>>>>>  ODataJPARuntimeException {
> >>>>>>>>>      ODataJPAContext oDatJPAContext = this.getODataJPAContext();
> >>>>>>>>> 
> >>>>>>>>>      try {
> >>>>>>>>>          CdiContainer.get().getNonContextualManager().postConstruct(this);
> >>>>>>>>>          oDatJPAContext.setEntityManagerFactory(emf);
> >>>>>>>>>          oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
> >>>>>>>>>          oDatJPAContext.setPageSize(100);
> >>>>>>>>>          setDetailErrors(true);
> >>>>>>>>>          return oDatJPAContext;
> >>>>>>>>>      } catch (Exception e) {
> >>>>>>>>>          System.out.print(e);
> >>>>>>>>>          throw new RuntimeException(e);
> >>>>>>>>>      }
> >>>>>>>>>  }
> >>>>>>>>> 
> >>>>>>>>> ...
> >>>>>>>>> 
> >>>>>>>>> So where is the catch here?
> >>>>>>>>> 
> >>>>>>>>> 
> >>>>>>>>> Best,
> >>>>>>>>> 
> >>>>>>>>> Korbinian
> >>>>>>>>> 
> >>>>>>>> 
> >>>>>>> 
> >>>>>> 
> >>>> 
> >>>> 
> >> 
> >> 
> 
> 

Re: olingo JPA / JTA - wrong transactions used

Posted by Korbinian Bachl <ko...@whiskyworld.de>.
everything in: https://github.com/apache/olingo-odata2/pull/2

Now, when will Chandan do the JPA for olingo OData V4? ;)



Best,

Korbinian

----- Ursprüngliche Mail -----
> Von: "Michael Bolz" <mi...@sap.com>
> An: "Chandan V.A" <ch...@sap.com>
> CC: user@olingo.apache.org
> Gesendet: Donnerstag, 26. Februar 2015 12:59:46
> Betreff: Re: olingo JPA / JTA - wrong transactions used
> 
> Hello all,
> 
> after a first look I agree with the suggestion from Chandan.
> So from my side a +1 for a minor rename ;o)
> 
> Kind regards,
> Michael
> 
> > On 26 Feb 2015, at 12:11, V.A, Chandan <ch...@sap.com> wrote:
> > 
> > Hello Korbinian,
> > I did a quick review of the code and at first sight looks fine. I have few
> > comments with respect to the name. I feel ODataJPATransaction will be more
> > appropriate than ODataJPATransactionContext. Because we are executing
> > transaction steps using this interface and not just setting and getting
> > values.
> > WDYT?
> > 
> > Proposal
> > public interface ODataJPATransaction {
> > 	void begin();
> > 	void rollback();
> > 	void commit();
> > 	void isActive();
> > }
> > 
> > The class name for default implementation can be
> > ODataJPATransactionLocalDefault.
> > 
> > Thanks
> > Kind Regards
> > Chandan
> > 
> > -----Original Message-----
> > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > Sent: Thursday, February 26, 2015 4:09 PM
> > To: user@olingo.apache.org; Bolz, Michael
> > Subject: Re: olingo JPA / JTA - wrong transactions used
> > 
> > Here you go: https://github.com/apache/olingo-odata2/pull/2
> > 
> > Best,
> > 
> > Korbinian
> > 
> > 
> > ----- Ursprüngliche Mail -----
> >> Von: "Michael Bolz" <mi...@sap.com>
> >> An: user@olingo.apache.org
> >> CC: "korbinian bachl" <ko...@whiskyworld.de>
> >> Gesendet: Donnerstag, 26. Februar 2015 08:56:45
> >> Betreff: Re: olingo JPA / JTA - wrong transactions used
> >> 
> >> Hello Korbinian,
> >> 
> >> I would prefer to add this just at “ODataJPAServiceFactory”.
> >> First this way it is consistent with the “setODataTransactionContext” and
> >> second the callback is only related to database (JTA) dependent (using)
> >> OData services.
> >> @Korbinian and Chandan: I think (hope) you both agree with my opinion  ;o)
> >> 
> >> When you send me the pull request I will check it and afterwards merge
> >> into
> >> Olingo master.
> >> 
> >> Kind regards,
> >> Michael
> >> 
> >>> On 25 Feb 2015, at 12:17, Korbinian Bachl
> >>> <ko...@whiskyworld.de>
> >>> wrote:
> >>> 
> >>> Hello Michael,
> >>> 
> >>> I've looked at the suggested OnJPAWriteContent-approach and this would
> >>> work. Question is just if the callback should be implemented within
> >>> ODataServiceFactory or just within ODataJPAServiceFactory;
> >>> 
> >>> Either way we would need one (1) interface
> >>> 
> >>> public interface ODataTransactionContext extends ODataCallback {
> >>> 
> >>> public void startTransaction();
> >>> 
> >>> public void commitTransaction();
> >>> 
> >>> public void rollbackTransaction();
> >>> 
> >>> public boolean transactionIsActive();
> >>> 
> >>> }
> >>> 
> >>> as well as 1 class that implements the current default;
> >>> 
> >>> it would be put into the Factory class like
> >>> 
> >>> protected void setODataTransactionContext(final ODataTransactionContext
> >>> oDataTransactionContext) {
> >>>   this.oDataTransactionContext = oDataTransactionContext;
> >>> }
> >>> 
> >>> and any access to transactions would then need to run via
> >>> getTransactionContext() e.g.:
> >>> 
> >>> FactoryClassInstace.getTransactionContext().startTransaction();
> >>> 
> >>> (or if you want the more noisy version:
> >>> FactoryClassInstace.getCallback(ODataTransactionContext.class).startTransaction();
> >>> - something I really dont like as this calling stack of
> >>> if(callbackInterface.isAssignableFrom... ) is something I see waste of
> >>> CPU
> >>> cycles in regular and often called code areas, bad habbit IMHO)
> >>> 
> >>> 
> >>> Any other usages like JTA can then override the
> >>> setODataTransactionContext(...) and supply a class that "does" exactly
> >>> what needed.
> >>> 
> >>> 
> >>> If this is the way to go, then just let me know which "way" you want it
> >>> and
> >>> I can send you a pull request for it (on github);
> >>> 
> >>> 
> >>> 
> >>> Best,
> >>> 
> >>> Korbinian
> >>> 
> >>> ----- Ursprüngliche Mail -----
> >>>> Von: "Michael Bolz" <mi...@sap.com>
> >>>> An: user@olingo.apache.org
> >>>> Gesendet: Montag, 23. Februar 2015 11:03:40
> >>>> Betreff: Re: olingo JPA / JTA - wrong transactions used
> >>>> 
> >>>> Hi,
> >>>> 
> >>>> could a solution with the “Callback” approach (like the
> >>>> “OnJPAWriteContent”)
> >>>> work for this?
> >>>> So that the “ODataTransactionContext” is implemented as
> >>>> “ODataTransactionCallback”?
> >>>> 
> >>>> This way in the “ODataJPAServiceFactory” a method like: "protected void
> >>>> setTransactionCallback(final ODataTransactionCallback callback)” can be
> >>>> provided and
> >>>> if someone want to implement (inherit) his own “ODataServiceFactory” he
> >>>> can
> >>>> support the callback (interface) directly via the “getCallback(…)”
> >>>> method.
> >>>> 
> >>>> Kind regards,
> >>>> Michael
> >>>> 
> >>>> 
> >>>>> On 23 Feb 2015, at 10:17, Korbinian Bachl
> >>>>> <ko...@whiskyworld.de>
> >>>>> wrote:
> >>>>> 
> >>>>> Hello Chandan,
> >>>>> 
> >>>>> I've looked into the ODataServiceFactory and its usages and I really
> >>>>> dont
> >>>>> think this is good. Problems are
> >>>>> 
> >>>>> a, ODataServiceFactory is in lib module - so no external dependency
> >>>>> should
> >>>>> be pulled into
> >>>>> b, just extending the class like I suggested wont work as we would have
> >>>>> to
> >>>>> fix over 13 implementations of this Factory as well - not speaking
> >>>>> about
> >>>>> any custom implementations so far;
> >>>>> c, I currently dont see the "need" to have JTA outside of JPA context -
> >>>>> since no one ever asked for it;
> >>>>> 
> >>>>> What I can think of is a CustomTransaction class object that gets its
> >>>>> "hold" within ODataServiceFactory and needs to be setup by the
> >>>>> implementation of the ODataServiceFactory only if it needs to use it.
> >>>>> Something like e.g.:
> >>>>> 
> >>>>> in ODataServiceFactory:
> >>>>> ----------
> >>>>> private ODataTransactionContext = null;
> >>>>> 
> >>>>> //stub - needs to be implemented if want to be used
> >>>>> public void setUpTransactionContext() {};
> >>>>> 
> >>>>> public getODataTransactionContext() {
> >>>>>     return ODataTransactionContext;
> >>>>> }
> >>>>> 
> >>>>> public setODataTransactionContext(ODataTransactionContext ctx) {...}
> >>>>> 
> >>>>> ---------
> >>>>> 
> >>>>> 
> >>>>> and ODataTransactionContext could be some kind of abstract class that
> >>>>> has
> >>>>> the methods
> >>>>> 
> >>>>> public abstract class ODataTransactionContext {
> >>>>> 
> >>>>> public abstract void commitTransaction();
> >>>>> 
> >>>>> public abstract void startTransaction();
> >>>>> 
> >>>>> public abstract void rollbackTransaction();
> >>>>> 
> >>>>> public abstract boolean transactionIsActive();
> >>>>> 
> >>>>> }
> >>>>> 
> >>>>> -------
> >>>>> 
> >>>>> IMHO looks ugly; But using an interface for this would be even more
> >>>>> ugly....
> >>>>> 
> >>>>> 
> >>>>> Best,
> >>>>> 
> >>>>> Korbinian
> >>>>> 
> >>>>> 
> >>>>> ----- Ursprüngliche Mail -----
> >>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>> An: user@olingo.apache.org
> >>>>>> Gesendet: Donnerstag, 19. Februar 2015 08:07:59
> >>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>> 
> >>>>>> Hello Korbinian,
> >>>>>> I could have kept the methods as part of ODataJPAServiceFactory but
> >>>>>> the
> >>>>>> problem is, extending the ODataJPAServiceFactory class for an
> >>>>>> application
> >>>>>> is
> >>>>>> optional. Applications can create their own factory classes by
> >>>>>> directly
> >>>>>> inheriting ODataServiceFactory. We need to support such applications
> >>>>>> as
> >>>>>> well. I have created the JIRA issue
> >>>>>> https://issues.apache.org/jira/browse/OLINGO-580 to implement support
> >>>>>> for
> >>>>>> JTA based transactions.
> >>>>>> 
> >>>>>> Thanks
> >>>>>> Kind Regards
> >>>>>> Chandan
> >>>>>> 
> >>>>>> -----Original Message-----
> >>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>> Sent: Wednesday, February 18, 2015 7:30 PM
> >>>>>> To: user@olingo.apache.org
> >>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>>>> 
> >>>>>> Hello Chandan,
> >>>>>> 
> >>>>>> sounds good. What I would do - based upon your idea - is to extend the
> >>>>>> ODataJPAServiceFactory with 4 methods (as this one has to be used in
> >>>>>> any
> >>>>>> case):
> >>>>>> 
> >>>>>> public static void startTransaction(EntityManager em, Object
> >>>>>> transaction)
> >>>>>> {
> >>>>>>  em.getTransaction().begin();
> >>>>>>  transaction = em.getTransaction();
> >>>>>> }
> >>>>>> 
> >>>>>> public static void commitTransaction(Object transaction) {
> >>>>>>  ((EntitiyTransaction) transaction).commit();
> >>>>>> }
> >>>>>> 
> >>>>>> public static void rollbackTransaction(Object transaction) {
> >>>>>>  ((EntitiyTransaction) transaction).rollback();
> >>>>>> }
> >>>>>> 
> >>>>>> public static boolean transactionIsActive(Object transaction) {
> >>>>>> return ((EntitiyTransaction) transaction).isActive();
> >>>>>> }
> >>>>>> 
> >>>>>> These then would be called from wherever olingo JPA needs them.
> >>>>>> 
> >>>>>> That way any one needing JTA can override these methods while the rest
> >>>>>> won't
> >>>>>> even notice them...
> >>>>>> 
> >>>>>> 
> >>>>>> What do you think?
> >>>>>> 
> >>>>>> Best,
> >>>>>> 
> >>>>>> Korbinian
> >>>>>> 
> >>>>>> 
> >>>>>> 
> >>>>>> 
> >>>>>> 
> >>>>>> ----- Ursprüngliche Mail -----
> >>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>>> An: user@olingo.apache.org
> >>>>>>> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
> >>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>>> 
> >>>>>>> Hello Korbinian,
> >>>>>>> I would at least keep the application managed transactions (like JTA)
> >>>>>>> outside
> >>>>>>> the context of JPA Processor for following reasons
> >>>>>>> 1) Wiring the JTA transactions into JPA processor could make the
> >>>>>>> processor
> >>>>>>> to
> >>>>>>> behave more like a framework than as a library (which is the current
> >>>>>>> state).
> >>>>>>> 2) JPA processor also need to take JNDI lookup as parameter from
> >>>>>>> applications
> >>>>>>> for looking up the datasource.
> >>>>>>> 3) Olingo JPA processor should take care of just data transformations
> >>>>>>> and
> >>>>>>> need not worry about the scope of transactions
> >>>>>>> 4) Olingo JPA processor should not take dependency to J2EE api
> >>>>>>> because
> >>>>>>> I
> >>>>>>> am
> >>>>>>> not sure will this artifact work in OSGI environments
> >>>>>>> 
> >>>>>>> One proposal from my side would be to provide a callback mechanism
> >>>>>>> for
> >>>>>>> transaction handling, where the library just calls a method in the
> >>>>>>> interface
> >>>>>>> to begin the transaction and end the transaction. If no one
> >>>>>>> implements
> >>>>>>> the
> >>>>>>> callback mechanism the library would resort to "RESOURCE_LOCAL" based
> >>>>>>> transaction handling. With this approach applications will have a
> >>>>>>> greater
> >>>>>>> control over transaction handling and also need not rewrite
> >>>>>>> JPAProcessorImpl
> >>>>>>> or extend ODataJPAProcessor.
> >>>>>>> 
> >>>>>>> What do you think? Do you foresee any shortcomings with this
> >>>>>>> approach?
> >>>>>>> 
> >>>>>>> Thanks
> >>>>>>> Kind Regards
> >>>>>>> Chandan
> >>>>>>> 
> >>>>>>> 
> >>>>>>> 
> >>>>>>> -----Original Message-----
> >>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>>> Sent: Wednesday, February 18, 2015 6:22 PM
> >>>>>>> To: user@olingo.apache.org
> >>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>>>>> 
> >>>>>>> Hello Chandan,
> >>>>>>> 
> >>>>>>> I finally had some success in using JTA based transactions. However,
> >>>>>>> this
> >>>>>>> only worked when I cloned the current git and changed it in the
> >>>>>>> JPAProcessorImpl directly; If I try to do this from within my project
> >>>>>>> onto
> >>>>>>> the intialization with
> >>>>>>> 
> >>>>>>> oDatJPAContext.setODataProcessor(new
> >>>>>>> ODataJPAProcessorJTA(oDatJPAContext));
> >>>>>>> 
> >>>>>>> I then have to do a ODataJPAProcessorJTA which is 99% copy n paste
> >>>>>>> from
> >>>>>>> ODataJPAProcessor and then also need a 95% copy n paste
> >>>>>>> JPAProcessorImplJTA
> >>>>>>> from JPAProcessorImpl;
> >>>>>>> 
> >>>>>>> As if this isn't ugly enough, it gets real dirty when trying to use
> >>>>>>> it
> >>>>>>> as
> >>>>>>> you
> >>>>>>> simply cant force olingo to use it! Problem is that it comes from the
> >>>>>>> JPAAccessFactoryImpl class static; is a static one and sits in
> >>>>>>> ODataJPAFactoryImpl and finally this one gets called in public
> >>>>>>> abstract
> >>>>>>> class ODataJPAFactory
> >>>>>>> 
> >>>>>>> using
> >>>>>>> 
> >>>>>>> public static ODataJPAFactory createFactory() {
> >>>>>>> 
> >>>>>>>  if (factoryImpl != null) {
> >>>>>>>    return factoryImpl;
> >>>>>>>  } else {
> >>>>>>>    try {
> >>>>>>>      Class<?> clazz = Class.forName(ODataJPAFactory.IMPLEMENTATION);
> >>>>>>> 
> >>>>>>>      Object object = clazz.newInstance();
> >>>>>>>      factoryImpl = (ODataJPAFactory) object;
> >>>>>>> 
> >>>>>>>    } catch (Exception e) {
> >>>>>>>      throw new RuntimeException(e);
> >>>>>>>    }
> >>>>>>> 
> >>>>>>>    return factoryImpl;
> >>>>>>>  }
> >>>>>>> }
> >>>>>>> 
> >>>>>>> where private static final String IMPLEMENTATION =
> >>>>>>>    "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
> >>>>>>> 
> >>>>>>> 
> >>>>>>> Simple said - overriding this logic in the olingo project is next to
> >>>>>>> impossible as you would end up with nearly the whole project
> >>>>>>> copy'n'pasted
> >>>>>>> over; Simple changing the e.g.  resolver etc. wont works as there are
> >>>>>>> many
> >>>>>>> usages of the ODataJPAFactory createFactory() method;
> >>>>>>> 
> >>>>>>> 
> >>>>>>> Implementing JTA to work in olingo on the other hand is quite easy.
> >>>>>>> You
> >>>>>>> can
> >>>>>>> check on the fly if your JTA or not via e.g.:
> >>>>>>> 
> >>>>>>> public static boolean isResourceLocal(EntityManager em) {
> >>>>>>>      try {
> >>>>>>>          EntityTransaction tx = em.getTransaction();
> >>>>>>>          return true;
> >>>>>>>      } catch (IllegalStateException ex) {
> >>>>>>>          return false;
> >>>>>>>      }
> >>>>>>>  }
> >>>>>>> 
> >>>>>>> and this one can then set into a boolean var classwide in the
> >>>>>>> JPAProcessorImpl; so the setTransaction would become:
> >>>>>>> 
> >>>>>>> private boolean setTransaction() {
> >>>>>>>    if(isLocalTX) {
> >>>>>>>        final EntityTransaction transaction = em.getTransaction();
> >>>>>>>        if (!transaction.isActive()) {
> >>>>>>>            em.getTransaction().begin();
> >>>>>>>            return true;
> >>>>>>>        }
> >>>>>>>    } else {
> >>>>>>>        try {
> >>>>>>>            transaction = (UserTransaction) new
> >>>>>>>            InitialContext().lookup("java:comp/UserTransaction");
> >>>>>>>            transaction.begin();
> >>>>>>>        } catch (NamingException e) {
> >>>>>>>            e.printStackTrace();
> >>>>>>>        } catch (NotSupportedException e) {
> >>>>>>>            e.printStackTrace();
> >>>>>>>        } catch (SystemException e) {
> >>>>>>>            e.printStackTrace();
> >>>>>>>        }
> >>>>>>>    }
> >>>>>>> 
> >>>>>>> 
> >>>>>>>  return false;
> >>>>>>> }
> >>>>>>> 
> >>>>>>> 
> >>>>>>> and this would work on all JTA bases Servers. The rest of the
> >>>>>>> transaction
> >>>>>>> logic would simply look like e.g.:
> >>>>>>> 
> >>>>>>> if (isLocalTransaction) {
> >>>>>>>      em.getTransaction().commit();
> >>>>>>>    }
> >>>>>>> if(transaction != null) {
> >>>>>>>          transaction.commit();
> >>>>>>>    }
> >>>>>>> Or even
> >>>>>>> if (isLocalTransaction) {
> >>>>>>>      em.getTransaction().commit();
> >>>>>>>    }
> >>>>>>> else {
> >>>>>>>          transaction.commit();
> >>>>>>>    }
> >>>>>>> in case we expect a 100% availbilty of transactional context;
> >>>>>>> 
> >>>>>>> 
> >>>>>>> 
> >>>>>>> Problem is now that this needs at least the dependency of
> >>>>>>>      <dependency>
> >>>>>>>          <groupId>javax</groupId>
> >>>>>>>          <artifactId>javaee-api</artifactId>
> >>>>>>>          <version>6.0</version>
> >>>>>>>      </dependency>
> >>>>>>> as else there is no UserTransaction class available; Would this
> >>>>>>> dependency
> >>>>>>> be
> >>>>>>> ok for the JPA part of the olingo project?
> >>>>>>> 
> >>>>>>> What do you think?
> >>>>>>> 
> >>>>>>> Best,
> >>>>>>> 
> >>>>>>> Korbinian
> >>>>>>> 
> >>>>>>> 
> >>>>>>> 
> >>>>>>> ----- Ursprüngliche Mail -----
> >>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>>>> An: user@olingo.apache.org
> >>>>>>>> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
> >>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>>>> 
> >>>>>>>> Hello Korbinian,
> >>>>>>>> Please check the JIRA item -
> >>>>>>>> https://issues.apache.org/jira/browse/OLINGO-549
> >>>>>>>> for updates on Olingo V4 JPA processor. Current status is there is
> >>>>>>>> no
> >>>>>>>> support for V4 JPA processor and the development is in progress.
> >>>>>>>> 
> >>>>>>>> Thanks
> >>>>>>>> Kind Regards
> >>>>>>>> Chandan
> >>>>>>>> 
> >>>>>>>> -----Original Message-----
> >>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>>>> Sent: Wednesday, February 18, 2015 2:48 PM
> >>>>>>>> To: user@olingo.apache.org
> >>>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>>>>>> 
> >>>>>>>> Hello Chandan,
> >>>>>>>> 
> >>>>>>>> thank you for the info. Will try this. I've seen that Olingo also
> >>>>>>>> has
> >>>>>>>> a
> >>>>>>>> OData
> >>>>>>>> V4 in Beta2 - but I couldn't really find information about its
> >>>>>>>> "readyness".
> >>>>>>>> Would it work in a simple CRUD scenario with JPA? Reason is as it
> >>>>>>>> seems
> >>>>>>>> as
> >>>>>>>> my other system I talk to via OData is moving from V3 to V4
> >>>>>>>> currently,
> >>>>>>>> at
> >>>>>>>> least the doc of its alredy speaks of OData V4 ready.
> >>>>>>>> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
> >>>>>>>> 
> >>>>>>>> Best,
> >>>>>>>> 
> >>>>>>>> Korbinian
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>> ----- Ursprüngliche Mail -----
> >>>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>>>>> An: user@olingo.apache.org
> >>>>>>>>> Gesendet: Dienstag, 17. Februar 2015 07:11:28
> >>>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>>>>> 
> >>>>>>>>> Hello Korbinian,
> >>>>>>>>> You can extend the
> >>>>>>>>> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and
> >>>>>>>>> implement
> >>>>>>>>> the processor methods as it is done in
> >>>>>>>>> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.
> >>>>>>>>> In
> >>>>>>>>> your implementation for Create, Update and Delete you could begin
> >>>>>>>>> the
> >>>>>>>>> JTA
> >>>>>>>>> transaction and close the transaction by either commit or rollback.
> >>>>>>>>> 
> >>>>>>>>> I have not tried the scenario with JTA based transactions but only
> >>>>>>>>> Resource
> >>>>>>>>> Local based transactions. Please check and tell if the above
> >>>>>>>>> solution
> >>>>>>>>> works
> >>>>>>>>> for your case. Else raise a JIRA feature request to support JTA
> >>>>>>>>> based
> >>>>>>>>> transactions.
> >>>>>>>>> 
> >>>>>>>>> Regards
> >>>>>>>>> Chandan
> >>>>>>>>> 
> >>>>>>>>> -----Original Message-----
> >>>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>>>>> Sent: Monday, February 16, 2015 2:16 PM
> >>>>>>>>> To: user@olingo.apache.org
> >>>>>>>>> Subject: olingo JPA / JTA - wrong transactions used
> >>>>>>>>> 
> >>>>>>>>> Hi,
> >>>>>>>>> 
> >>>>>>>>> I'm using Olingo 2.0.2 and I can query all items so far. When I
> >>>>>>>>> want
> >>>>>>>>> to
> >>>>>>>>> update content, I get error:
> >>>>>>>>> 
> >>>>>>>>> ...
> >>>>>>>>> <message xml:lang="en">"OData - JPA Runtime: JPA update request is
> >>>>>>>>> not
> >>>>>>>>> correct"message>
> >>>>>>>>>  <innererror>class java.lang.IllegalStateException :
> >>>>>>>>> Exception Description: Cannot use an EntityTransaction while using
> >>>>>>>>> JTA.innererror>
> >>>>>>>>> ....
> >>>>>>>>> 
> >>>>>>>>> Digging deeper into the code, I ended up in file
> >>>>>>>>> ODataJPAContextImpl
> >>>>>>>>> 
> >>>>>>>>> and there in the function
> >>>>>>>>> 
> >>>>>>>>> private  Object processUpdate(PutMergePatchUriInfo updateView,
> >>>>>>>>>    final InputStream content, final Map<String, Object> properties,
> >>>>>>>>>    final
> >>>>>>>>>    String requestContentType)
> >>>>>>>>>    throws ODataJPAModelException, ODataJPARuntimeException {
> >>>>>>>>> ...
> >>>>>>>>> boolean isLocalTransaction = setTransaction();
> >>>>>>>>> 
> >>>>>>>>> ...
> >>>>>>>>> }
> >>>>>>>>> 
> >>>>>>>>> with
> >>>>>>>>> 
> >>>>>>>>> private boolean setTransaction() {
> >>>>>>>>>  final EntityTransaction transaction = em.getTransaction();
> >>>>>>>>>  if (!transaction.isActive()) {
> >>>>>>>>>    em.getTransaction().begin();
> >>>>>>>>>    return true;
> >>>>>>>>>  }
> >>>>>>>>> 
> >>>>>>>>>  return false;
> >>>>>>>>> }
> >>>>>>>>> 
> >>>>>>>>> 
> >>>>>>>>> So far I understood this one is the function that collides with my
> >>>>>>>>> JTA
> >>>>>>>>> setup.
> >>>>>>>>> I now wonder how I can suppress to initialize this method?
> >>>>>>>>> 
> >>>>>>>>> I've sending in the right EntityManagerFactory into Olingo, e.g.:
> >>>>>>>>> 
> >>>>>>>>> public class ConnectorODataJPAServiceFactory extends
> >>>>>>>>> ODataJPAServiceFactory
> >>>>>>>>> {
> >>>>>>>>> 
> >>>>>>>>>  private static final String PERSISTENCE_UNIT_NAME = "myPU";
> >>>>>>>>> 
> >>>>>>>>>  @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
> >>>>>>>>>  EntityManagerFactory emf;
> >>>>>>>>> 
> >>>>>>>>> 
> >>>>>>>>>  @Override
> >>>>>>>>>  public ODataJPAContext initializeODataJPAContext() throws
> >>>>>>>>>  ODataJPARuntimeException {
> >>>>>>>>>      ODataJPAContext oDatJPAContext = this.getODataJPAContext();
> >>>>>>>>> 
> >>>>>>>>>      try {
> >>>>>>>>>          CdiContainer.get().getNonContextualManager().postConstruct(this);
> >>>>>>>>>          oDatJPAContext.setEntityManagerFactory(emf);
> >>>>>>>>>          oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
> >>>>>>>>>          oDatJPAContext.setPageSize(100);
> >>>>>>>>>          setDetailErrors(true);
> >>>>>>>>>          return oDatJPAContext;
> >>>>>>>>>      } catch (Exception e) {
> >>>>>>>>>          System.out.print(e);
> >>>>>>>>>          throw new RuntimeException(e);
> >>>>>>>>>      }
> >>>>>>>>>  }
> >>>>>>>>> 
> >>>>>>>>> ...
> >>>>>>>>> 
> >>>>>>>>> So where is the catch here?
> >>>>>>>>> 
> >>>>>>>>> 
> >>>>>>>>> Best,
> >>>>>>>>> 
> >>>>>>>>> Korbinian
> >>>>>>>>> 
> >>>>>>>> 
> >>>>>>> 
> >>>>>> 
> >>>> 
> >>>> 
> >> 
> >> 
> 
> 

Re: olingo JPA / JTA - wrong transactions used

Posted by "Bolz, Michael" <mi...@sap.com>.
Hello all,

after a first look I agree with the suggestion from Chandan.
So from my side a +1 for a minor rename ;o)

Kind regards, 
Michael

> On 26 Feb 2015, at 12:11, V.A, Chandan <ch...@sap.com> wrote:
> 
> Hello Korbinian,
> I did a quick review of the code and at first sight looks fine. I have few comments with respect to the name. I feel ODataJPATransaction will be more appropriate than ODataJPATransactionContext. Because we are executing transaction steps using this interface and not just setting and getting values.
> WDYT?
> 
> Proposal
> public interface ODataJPATransaction {
> 	void begin();
> 	void rollback();
> 	void commit();
> 	void isActive();
> }
> 
> The class name for default implementation can be ODataJPATransactionLocalDefault.
> 
> Thanks
> Kind Regards
> Chandan
> 
> -----Original Message-----
> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de] 
> Sent: Thursday, February 26, 2015 4:09 PM
> To: user@olingo.apache.org; Bolz, Michael
> Subject: Re: olingo JPA / JTA - wrong transactions used
> 
> Here you go: https://github.com/apache/olingo-odata2/pull/2
> 
> Best,
> 
> Korbinian
> 
> 
> ----- Ursprüngliche Mail -----
>> Von: "Michael Bolz" <mi...@sap.com>
>> An: user@olingo.apache.org
>> CC: "korbinian bachl" <ko...@whiskyworld.de>
>> Gesendet: Donnerstag, 26. Februar 2015 08:56:45
>> Betreff: Re: olingo JPA / JTA - wrong transactions used
>> 
>> Hello Korbinian,
>> 
>> I would prefer to add this just at “ODataJPAServiceFactory”.
>> First this way it is consistent with the “setODataTransactionContext” and
>> second the callback is only related to database (JTA) dependent (using)
>> OData services.
>> @Korbinian and Chandan: I think (hope) you both agree with my opinion  ;o)
>> 
>> When you send me the pull request I will check it and afterwards merge into
>> Olingo master.
>> 
>> Kind regards,
>> Michael
>> 
>>> On 25 Feb 2015, at 12:17, Korbinian Bachl <ko...@whiskyworld.de>
>>> wrote:
>>> 
>>> Hello Michael,
>>> 
>>> I've looked at the suggested OnJPAWriteContent-approach and this would
>>> work. Question is just if the callback should be implemented within
>>> ODataServiceFactory or just within ODataJPAServiceFactory;
>>> 
>>> Either way we would need one (1) interface
>>> 
>>> public interface ODataTransactionContext extends ODataCallback {
>>> 
>>> public void startTransaction();
>>> 
>>> public void commitTransaction();
>>> 
>>> public void rollbackTransaction();
>>> 
>>> public boolean transactionIsActive();
>>> 
>>> }
>>> 
>>> as well as 1 class that implements the current default;
>>> 
>>> it would be put into the Factory class like
>>> 
>>> protected void setODataTransactionContext(final ODataTransactionContext
>>> oDataTransactionContext) {
>>>   this.oDataTransactionContext = oDataTransactionContext;
>>> }
>>> 
>>> and any access to transactions would then need to run via
>>> getTransactionContext() e.g.:
>>> 
>>> FactoryClassInstace.getTransactionContext().startTransaction();
>>> 
>>> (or if you want the more noisy version:
>>> FactoryClassInstace.getCallback(ODataTransactionContext.class).startTransaction();
>>> - something I really dont like as this calling stack of
>>> if(callbackInterface.isAssignableFrom... ) is something I see waste of CPU
>>> cycles in regular and often called code areas, bad habbit IMHO)
>>> 
>>> 
>>> Any other usages like JTA can then override the
>>> setODataTransactionContext(...) and supply a class that "does" exactly
>>> what needed.
>>> 
>>> 
>>> If this is the way to go, then just let me know which "way" you want it and
>>> I can send you a pull request for it (on github);
>>> 
>>> 
>>> 
>>> Best,
>>> 
>>> Korbinian
>>> 
>>> ----- Ursprüngliche Mail -----
>>>> Von: "Michael Bolz" <mi...@sap.com>
>>>> An: user@olingo.apache.org
>>>> Gesendet: Montag, 23. Februar 2015 11:03:40
>>>> Betreff: Re: olingo JPA / JTA - wrong transactions used
>>>> 
>>>> Hi,
>>>> 
>>>> could a solution with the “Callback” approach (like the
>>>> “OnJPAWriteContent”)
>>>> work for this?
>>>> So that the “ODataTransactionContext” is implemented as
>>>> “ODataTransactionCallback”?
>>>> 
>>>> This way in the “ODataJPAServiceFactory” a method like: "protected void
>>>> setTransactionCallback(final ODataTransactionCallback callback)” can be
>>>> provided and
>>>> if someone want to implement (inherit) his own “ODataServiceFactory” he
>>>> can
>>>> support the callback (interface) directly via the “getCallback(…)” method.
>>>> 
>>>> Kind regards,
>>>> Michael
>>>> 
>>>> 
>>>>> On 23 Feb 2015, at 10:17, Korbinian Bachl
>>>>> <ko...@whiskyworld.de>
>>>>> wrote:
>>>>> 
>>>>> Hello Chandan,
>>>>> 
>>>>> I've looked into the ODataServiceFactory and its usages and I really dont
>>>>> think this is good. Problems are
>>>>> 
>>>>> a, ODataServiceFactory is in lib module - so no external dependency
>>>>> should
>>>>> be pulled into
>>>>> b, just extending the class like I suggested wont work as we would have
>>>>> to
>>>>> fix over 13 implementations of this Factory as well - not speaking about
>>>>> any custom implementations so far;
>>>>> c, I currently dont see the "need" to have JTA outside of JPA context -
>>>>> since no one ever asked for it;
>>>>> 
>>>>> What I can think of is a CustomTransaction class object that gets its
>>>>> "hold" within ODataServiceFactory and needs to be setup by the
>>>>> implementation of the ODataServiceFactory only if it needs to use it.
>>>>> Something like e.g.:
>>>>> 
>>>>> in ODataServiceFactory:
>>>>> ----------
>>>>> private ODataTransactionContext = null;
>>>>> 
>>>>> //stub - needs to be implemented if want to be used
>>>>> public void setUpTransactionContext() {};
>>>>> 
>>>>> public getODataTransactionContext() {
>>>>>     return ODataTransactionContext;
>>>>> }
>>>>> 
>>>>> public setODataTransactionContext(ODataTransactionContext ctx) {...}
>>>>> 
>>>>> ---------
>>>>> 
>>>>> 
>>>>> and ODataTransactionContext could be some kind of abstract class that has
>>>>> the methods
>>>>> 
>>>>> public abstract class ODataTransactionContext {
>>>>> 
>>>>> public abstract void commitTransaction();
>>>>> 
>>>>> public abstract void startTransaction();
>>>>> 
>>>>> public abstract void rollbackTransaction();
>>>>> 
>>>>> public abstract boolean transactionIsActive();
>>>>> 
>>>>> }
>>>>> 
>>>>> -------
>>>>> 
>>>>> IMHO looks ugly; But using an interface for this would be even more
>>>>> ugly....
>>>>> 
>>>>> 
>>>>> Best,
>>>>> 
>>>>> Korbinian
>>>>> 
>>>>> 
>>>>> ----- Ursprüngliche Mail -----
>>>>>> Von: "Chandan V.A" <ch...@sap.com>
>>>>>> An: user@olingo.apache.org
>>>>>> Gesendet: Donnerstag, 19. Februar 2015 08:07:59
>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>>>>>> 
>>>>>> Hello Korbinian,
>>>>>> I could have kept the methods as part of ODataJPAServiceFactory but the
>>>>>> problem is, extending the ODataJPAServiceFactory class for an
>>>>>> application
>>>>>> is
>>>>>> optional. Applications can create their own factory classes by directly
>>>>>> inheriting ODataServiceFactory. We need to support such applications as
>>>>>> well. I have created the JIRA issue
>>>>>> https://issues.apache.org/jira/browse/OLINGO-580 to implement support
>>>>>> for
>>>>>> JTA based transactions.
>>>>>> 
>>>>>> Thanks
>>>>>> Kind Regards
>>>>>> Chandan
>>>>>> 
>>>>>> -----Original Message-----
>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>>>>>> Sent: Wednesday, February 18, 2015 7:30 PM
>>>>>> To: user@olingo.apache.org
>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
>>>>>> 
>>>>>> Hello Chandan,
>>>>>> 
>>>>>> sounds good. What I would do - based upon your idea - is to extend the
>>>>>> ODataJPAServiceFactory with 4 methods (as this one has to be used in any
>>>>>> case):
>>>>>> 
>>>>>> public static void startTransaction(EntityManager em, Object
>>>>>> transaction)
>>>>>> {
>>>>>>  em.getTransaction().begin();
>>>>>>  transaction = em.getTransaction();
>>>>>> }
>>>>>> 
>>>>>> public static void commitTransaction(Object transaction) {
>>>>>>  ((EntitiyTransaction) transaction).commit();
>>>>>> }
>>>>>> 
>>>>>> public static void rollbackTransaction(Object transaction) {
>>>>>>  ((EntitiyTransaction) transaction).rollback();
>>>>>> }
>>>>>> 
>>>>>> public static boolean transactionIsActive(Object transaction) {
>>>>>> return ((EntitiyTransaction) transaction).isActive();
>>>>>> }
>>>>>> 
>>>>>> These then would be called from wherever olingo JPA needs them.
>>>>>> 
>>>>>> That way any one needing JTA can override these methods while the rest
>>>>>> won't
>>>>>> even notice them...
>>>>>> 
>>>>>> 
>>>>>> What do you think?
>>>>>> 
>>>>>> Best,
>>>>>> 
>>>>>> Korbinian
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> ----- Ursprüngliche Mail -----
>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
>>>>>>> An: user@olingo.apache.org
>>>>>>> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>>>>>>> 
>>>>>>> Hello Korbinian,
>>>>>>> I would at least keep the application managed transactions (like JTA)
>>>>>>> outside
>>>>>>> the context of JPA Processor for following reasons
>>>>>>> 1) Wiring the JTA transactions into JPA processor could make the
>>>>>>> processor
>>>>>>> to
>>>>>>> behave more like a framework than as a library (which is the current
>>>>>>> state).
>>>>>>> 2) JPA processor also need to take JNDI lookup as parameter from
>>>>>>> applications
>>>>>>> for looking up the datasource.
>>>>>>> 3) Olingo JPA processor should take care of just data transformations
>>>>>>> and
>>>>>>> need not worry about the scope of transactions
>>>>>>> 4) Olingo JPA processor should not take dependency to J2EE api because
>>>>>>> I
>>>>>>> am
>>>>>>> not sure will this artifact work in OSGI environments
>>>>>>> 
>>>>>>> One proposal from my side would be to provide a callback mechanism for
>>>>>>> transaction handling, where the library just calls a method in the
>>>>>>> interface
>>>>>>> to begin the transaction and end the transaction. If no one implements
>>>>>>> the
>>>>>>> callback mechanism the library would resort to "RESOURCE_LOCAL" based
>>>>>>> transaction handling. With this approach applications will have a
>>>>>>> greater
>>>>>>> control over transaction handling and also need not rewrite
>>>>>>> JPAProcessorImpl
>>>>>>> or extend ODataJPAProcessor.
>>>>>>> 
>>>>>>> What do you think? Do you foresee any shortcomings with this approach?
>>>>>>> 
>>>>>>> Thanks
>>>>>>> Kind Regards
>>>>>>> Chandan
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> -----Original Message-----
>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>>>>>>> Sent: Wednesday, February 18, 2015 6:22 PM
>>>>>>> To: user@olingo.apache.org
>>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
>>>>>>> 
>>>>>>> Hello Chandan,
>>>>>>> 
>>>>>>> I finally had some success in using JTA based transactions. However,
>>>>>>> this
>>>>>>> only worked when I cloned the current git and changed it in the
>>>>>>> JPAProcessorImpl directly; If I try to do this from within my project
>>>>>>> onto
>>>>>>> the intialization with
>>>>>>> 
>>>>>>> oDatJPAContext.setODataProcessor(new
>>>>>>> ODataJPAProcessorJTA(oDatJPAContext));
>>>>>>> 
>>>>>>> I then have to do a ODataJPAProcessorJTA which is 99% copy n paste from
>>>>>>> ODataJPAProcessor and then also need a 95% copy n paste
>>>>>>> JPAProcessorImplJTA
>>>>>>> from JPAProcessorImpl;
>>>>>>> 
>>>>>>> As if this isn't ugly enough, it gets real dirty when trying to use it
>>>>>>> as
>>>>>>> you
>>>>>>> simply cant force olingo to use it! Problem is that it comes from the
>>>>>>> JPAAccessFactoryImpl class static; is a static one and sits in
>>>>>>> ODataJPAFactoryImpl and finally this one gets called in public abstract
>>>>>>> class ODataJPAFactory
>>>>>>> 
>>>>>>> using
>>>>>>> 
>>>>>>> public static ODataJPAFactory createFactory() {
>>>>>>> 
>>>>>>>  if (factoryImpl != null) {
>>>>>>>    return factoryImpl;
>>>>>>>  } else {
>>>>>>>    try {
>>>>>>>      Class<?> clazz = Class.forName(ODataJPAFactory.IMPLEMENTATION);
>>>>>>> 
>>>>>>>      Object object = clazz.newInstance();
>>>>>>>      factoryImpl = (ODataJPAFactory) object;
>>>>>>> 
>>>>>>>    } catch (Exception e) {
>>>>>>>      throw new RuntimeException(e);
>>>>>>>    }
>>>>>>> 
>>>>>>>    return factoryImpl;
>>>>>>>  }
>>>>>>> }
>>>>>>> 
>>>>>>> where private static final String IMPLEMENTATION =
>>>>>>>    "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
>>>>>>> 
>>>>>>> 
>>>>>>> Simple said - overriding this logic in the olingo project is next to
>>>>>>> impossible as you would end up with nearly the whole project
>>>>>>> copy'n'pasted
>>>>>>> over; Simple changing the e.g.  resolver etc. wont works as there are
>>>>>>> many
>>>>>>> usages of the ODataJPAFactory createFactory() method;
>>>>>>> 
>>>>>>> 
>>>>>>> Implementing JTA to work in olingo on the other hand is quite easy. You
>>>>>>> can
>>>>>>> check on the fly if your JTA or not via e.g.:
>>>>>>> 
>>>>>>> public static boolean isResourceLocal(EntityManager em) {
>>>>>>>      try {
>>>>>>>          EntityTransaction tx = em.getTransaction();
>>>>>>>          return true;
>>>>>>>      } catch (IllegalStateException ex) {
>>>>>>>          return false;
>>>>>>>      }
>>>>>>>  }
>>>>>>> 
>>>>>>> and this one can then set into a boolean var classwide in the
>>>>>>> JPAProcessorImpl; so the setTransaction would become:
>>>>>>> 
>>>>>>> private boolean setTransaction() {
>>>>>>>    if(isLocalTX) {
>>>>>>>        final EntityTransaction transaction = em.getTransaction();
>>>>>>>        if (!transaction.isActive()) {
>>>>>>>            em.getTransaction().begin();
>>>>>>>            return true;
>>>>>>>        }
>>>>>>>    } else {
>>>>>>>        try {
>>>>>>>            transaction = (UserTransaction) new
>>>>>>>            InitialContext().lookup("java:comp/UserTransaction");
>>>>>>>            transaction.begin();
>>>>>>>        } catch (NamingException e) {
>>>>>>>            e.printStackTrace();
>>>>>>>        } catch (NotSupportedException e) {
>>>>>>>            e.printStackTrace();
>>>>>>>        } catch (SystemException e) {
>>>>>>>            e.printStackTrace();
>>>>>>>        }
>>>>>>>    }
>>>>>>> 
>>>>>>> 
>>>>>>>  return false;
>>>>>>> }
>>>>>>> 
>>>>>>> 
>>>>>>> and this would work on all JTA bases Servers. The rest of the
>>>>>>> transaction
>>>>>>> logic would simply look like e.g.:
>>>>>>> 
>>>>>>> if (isLocalTransaction) {
>>>>>>>      em.getTransaction().commit();
>>>>>>>    }
>>>>>>> if(transaction != null) {
>>>>>>>          transaction.commit();
>>>>>>>    }
>>>>>>> Or even
>>>>>>> if (isLocalTransaction) {
>>>>>>>      em.getTransaction().commit();
>>>>>>>    }
>>>>>>> else {
>>>>>>>          transaction.commit();
>>>>>>>    }
>>>>>>> in case we expect a 100% availbilty of transactional context;
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> Problem is now that this needs at least the dependency of
>>>>>>>      <dependency>
>>>>>>>          <groupId>javax</groupId>
>>>>>>>          <artifactId>javaee-api</artifactId>
>>>>>>>          <version>6.0</version>
>>>>>>>      </dependency>
>>>>>>> as else there is no UserTransaction class available; Would this
>>>>>>> dependency
>>>>>>> be
>>>>>>> ok for the JPA part of the olingo project?
>>>>>>> 
>>>>>>> What do you think?
>>>>>>> 
>>>>>>> Best,
>>>>>>> 
>>>>>>> Korbinian
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> ----- Ursprüngliche Mail -----
>>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
>>>>>>>> An: user@olingo.apache.org
>>>>>>>> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
>>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>>>>>>>> 
>>>>>>>> Hello Korbinian,
>>>>>>>> Please check the JIRA item -
>>>>>>>> https://issues.apache.org/jira/browse/OLINGO-549
>>>>>>>> for updates on Olingo V4 JPA processor. Current status is there is no
>>>>>>>> support for V4 JPA processor and the development is in progress.
>>>>>>>> 
>>>>>>>> Thanks
>>>>>>>> Kind Regards
>>>>>>>> Chandan
>>>>>>>> 
>>>>>>>> -----Original Message-----
>>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>>>>>>>> Sent: Wednesday, February 18, 2015 2:48 PM
>>>>>>>> To: user@olingo.apache.org
>>>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
>>>>>>>> 
>>>>>>>> Hello Chandan,
>>>>>>>> 
>>>>>>>> thank you for the info. Will try this. I've seen that Olingo also has
>>>>>>>> a
>>>>>>>> OData
>>>>>>>> V4 in Beta2 - but I couldn't really find information about its
>>>>>>>> "readyness".
>>>>>>>> Would it work in a simple CRUD scenario with JPA? Reason is as it
>>>>>>>> seems
>>>>>>>> as
>>>>>>>> my other system I talk to via OData is moving from V3 to V4 currently,
>>>>>>>> at
>>>>>>>> least the doc of its alredy speaks of OData V4 ready.
>>>>>>>> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
>>>>>>>> 
>>>>>>>> Best,
>>>>>>>> 
>>>>>>>> Korbinian
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> ----- Ursprüngliche Mail -----
>>>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
>>>>>>>>> An: user@olingo.apache.org
>>>>>>>>> Gesendet: Dienstag, 17. Februar 2015 07:11:28
>>>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>>>>>>>>> 
>>>>>>>>> Hello Korbinian,
>>>>>>>>> You can extend the
>>>>>>>>> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and
>>>>>>>>> implement
>>>>>>>>> the processor methods as it is done in
>>>>>>>>> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.
>>>>>>>>> In
>>>>>>>>> your implementation for Create, Update and Delete you could begin the
>>>>>>>>> JTA
>>>>>>>>> transaction and close the transaction by either commit or rollback.
>>>>>>>>> 
>>>>>>>>> I have not tried the scenario with JTA based transactions but only
>>>>>>>>> Resource
>>>>>>>>> Local based transactions. Please check and tell if the above solution
>>>>>>>>> works
>>>>>>>>> for your case. Else raise a JIRA feature request to support JTA based
>>>>>>>>> transactions.
>>>>>>>>> 
>>>>>>>>> Regards
>>>>>>>>> Chandan
>>>>>>>>> 
>>>>>>>>> -----Original Message-----
>>>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>>>>>>>>> Sent: Monday, February 16, 2015 2:16 PM
>>>>>>>>> To: user@olingo.apache.org
>>>>>>>>> Subject: olingo JPA / JTA - wrong transactions used
>>>>>>>>> 
>>>>>>>>> Hi,
>>>>>>>>> 
>>>>>>>>> I'm using Olingo 2.0.2 and I can query all items so far. When I want
>>>>>>>>> to
>>>>>>>>> update content, I get error:
>>>>>>>>> 
>>>>>>>>> ...
>>>>>>>>> <message xml:lang="en">"OData - JPA Runtime: JPA update request is
>>>>>>>>> not
>>>>>>>>> correct"message>
>>>>>>>>>  <innererror>class java.lang.IllegalStateException :
>>>>>>>>> Exception Description: Cannot use an EntityTransaction while using
>>>>>>>>> JTA.innererror>
>>>>>>>>> ....
>>>>>>>>> 
>>>>>>>>> Digging deeper into the code, I ended up in file ODataJPAContextImpl
>>>>>>>>> 
>>>>>>>>> and there in the function
>>>>>>>>> 
>>>>>>>>> private  Object processUpdate(PutMergePatchUriInfo updateView,
>>>>>>>>>    final InputStream content, final Map<String, Object> properties,
>>>>>>>>>    final
>>>>>>>>>    String requestContentType)
>>>>>>>>>    throws ODataJPAModelException, ODataJPARuntimeException {
>>>>>>>>> ...
>>>>>>>>> boolean isLocalTransaction = setTransaction();
>>>>>>>>> 
>>>>>>>>> ...
>>>>>>>>> }
>>>>>>>>> 
>>>>>>>>> with
>>>>>>>>> 
>>>>>>>>> private boolean setTransaction() {
>>>>>>>>>  final EntityTransaction transaction = em.getTransaction();
>>>>>>>>>  if (!transaction.isActive()) {
>>>>>>>>>    em.getTransaction().begin();
>>>>>>>>>    return true;
>>>>>>>>>  }
>>>>>>>>> 
>>>>>>>>>  return false;
>>>>>>>>> }
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> So far I understood this one is the function that collides with my
>>>>>>>>> JTA
>>>>>>>>> setup.
>>>>>>>>> I now wonder how I can suppress to initialize this method?
>>>>>>>>> 
>>>>>>>>> I've sending in the right EntityManagerFactory into Olingo, e.g.:
>>>>>>>>> 
>>>>>>>>> public class ConnectorODataJPAServiceFactory extends
>>>>>>>>> ODataJPAServiceFactory
>>>>>>>>> {
>>>>>>>>> 
>>>>>>>>>  private static final String PERSISTENCE_UNIT_NAME = "myPU";
>>>>>>>>> 
>>>>>>>>>  @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
>>>>>>>>>  EntityManagerFactory emf;
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>>  @Override
>>>>>>>>>  public ODataJPAContext initializeODataJPAContext() throws
>>>>>>>>>  ODataJPARuntimeException {
>>>>>>>>>      ODataJPAContext oDatJPAContext = this.getODataJPAContext();
>>>>>>>>> 
>>>>>>>>>      try {
>>>>>>>>>          CdiContainer.get().getNonContextualManager().postConstruct(this);
>>>>>>>>>          oDatJPAContext.setEntityManagerFactory(emf);
>>>>>>>>>          oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
>>>>>>>>>          oDatJPAContext.setPageSize(100);
>>>>>>>>>          setDetailErrors(true);
>>>>>>>>>          return oDatJPAContext;
>>>>>>>>>      } catch (Exception e) {
>>>>>>>>>          System.out.print(e);
>>>>>>>>>          throw new RuntimeException(e);
>>>>>>>>>      }
>>>>>>>>>  }
>>>>>>>>> 
>>>>>>>>> ...
>>>>>>>>> 
>>>>>>>>> So where is the catch here?
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> Best,
>>>>>>>>> 
>>>>>>>>> Korbinian
>>>>>>>>> 
>>>>>>>> 
>>>>>>> 
>>>>>> 
>>>> 
>>>> 
>> 
>> 


RE: olingo JPA / JTA - wrong transactions used

Posted by "V.A, Chandan" <ch...@sap.com>.
Hello Korbinian,
I did a quick review of the code and at first sight looks fine. I have few comments with respect to the name. I feel ODataJPATransaction will be more appropriate than ODataJPATransactionContext. Because we are executing transaction steps using this interface and not just setting and getting values.
WDYT?

Proposal
public interface ODataJPATransaction {
	void begin();
	void rollback();
	void commit();
	void isActive();
}

The class name for default implementation can be ODataJPATransactionLocalDefault.

Thanks
Kind Regards
Chandan

-----Original Message-----
From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de] 
Sent: Thursday, February 26, 2015 4:09 PM
To: user@olingo.apache.org; Bolz, Michael
Subject: Re: olingo JPA / JTA - wrong transactions used

Here you go: https://github.com/apache/olingo-odata2/pull/2

Best,

Korbinian


----- Ursprüngliche Mail -----
> Von: "Michael Bolz" <mi...@sap.com>
> An: user@olingo.apache.org
> CC: "korbinian bachl" <ko...@whiskyworld.de>
> Gesendet: Donnerstag, 26. Februar 2015 08:56:45
> Betreff: Re: olingo JPA / JTA - wrong transactions used
> 
> Hello Korbinian,
> 
> I would prefer to add this just at “ODataJPAServiceFactory”.
> First this way it is consistent with the “setODataTransactionContext” and
> second the callback is only related to database (JTA) dependent (using)
> OData services.
> @Korbinian and Chandan: I think (hope) you both agree with my opinion  ;o)
> 
> When you send me the pull request I will check it and afterwards merge into
> Olingo master.
> 
> Kind regards,
> Michael
> 
> > On 25 Feb 2015, at 12:17, Korbinian Bachl <ko...@whiskyworld.de>
> > wrote:
> > 
> > Hello Michael,
> > 
> > I've looked at the suggested OnJPAWriteContent-approach and this would
> > work. Question is just if the callback should be implemented within
> > ODataServiceFactory or just within ODataJPAServiceFactory;
> > 
> > Either way we would need one (1) interface
> > 
> > public interface ODataTransactionContext extends ODataCallback {
> > 
> > public void startTransaction();
> > 
> > public void commitTransaction();
> > 
> > public void rollbackTransaction();
> > 
> > public boolean transactionIsActive();
> > 
> > }
> > 
> > as well as 1 class that implements the current default;
> > 
> > it would be put into the Factory class like
> > 
> > protected void setODataTransactionContext(final ODataTransactionContext
> > oDataTransactionContext) {
> >    this.oDataTransactionContext = oDataTransactionContext;
> > }
> > 
> > and any access to transactions would then need to run via
> > getTransactionContext() e.g.:
> > 
> > FactoryClassInstace.getTransactionContext().startTransaction();
> > 
> > (or if you want the more noisy version:
> > FactoryClassInstace.getCallback(ODataTransactionContext.class).startTransaction();
> > - something I really dont like as this calling stack of
> > if(callbackInterface.isAssignableFrom... ) is something I see waste of CPU
> > cycles in regular and often called code areas, bad habbit IMHO)
> > 
> > 
> > Any other usages like JTA can then override the
> > setODataTransactionContext(...) and supply a class that "does" exactly
> > what needed.
> > 
> > 
> > If this is the way to go, then just let me know which "way" you want it and
> > I can send you a pull request for it (on github);
> > 
> > 
> > 
> > Best,
> > 
> > Korbinian
> > 
> > ----- Ursprüngliche Mail -----
> >> Von: "Michael Bolz" <mi...@sap.com>
> >> An: user@olingo.apache.org
> >> Gesendet: Montag, 23. Februar 2015 11:03:40
> >> Betreff: Re: olingo JPA / JTA - wrong transactions used
> >> 
> >> Hi,
> >> 
> >> could a solution with the “Callback” approach (like the
> >> “OnJPAWriteContent”)
> >> work for this?
> >> So that the “ODataTransactionContext” is implemented as
> >> “ODataTransactionCallback”?
> >> 
> >> This way in the “ODataJPAServiceFactory” a method like: "protected void
> >> setTransactionCallback(final ODataTransactionCallback callback)” can be
> >> provided and
> >> if someone want to implement (inherit) his own “ODataServiceFactory” he
> >> can
> >> support the callback (interface) directly via the “getCallback(…)” method.
> >> 
> >> Kind regards,
> >> Michael
> >> 
> >> 
> >>> On 23 Feb 2015, at 10:17, Korbinian Bachl
> >>> <ko...@whiskyworld.de>
> >>> wrote:
> >>> 
> >>> Hello Chandan,
> >>> 
> >>> I've looked into the ODataServiceFactory and its usages and I really dont
> >>> think this is good. Problems are
> >>> 
> >>> a, ODataServiceFactory is in lib module - so no external dependency
> >>> should
> >>> be pulled into
> >>> b, just extending the class like I suggested wont work as we would have
> >>> to
> >>> fix over 13 implementations of this Factory as well - not speaking about
> >>> any custom implementations so far;
> >>> c, I currently dont see the "need" to have JTA outside of JPA context -
> >>> since no one ever asked for it;
> >>> 
> >>> What I can think of is a CustomTransaction class object that gets its
> >>> "hold" within ODataServiceFactory and needs to be setup by the
> >>> implementation of the ODataServiceFactory only if it needs to use it.
> >>> Something like e.g.:
> >>> 
> >>> in ODataServiceFactory:
> >>> ----------
> >>> private ODataTransactionContext = null;
> >>> 
> >>> //stub - needs to be implemented if want to be used
> >>> public void setUpTransactionContext() {};
> >>> 
> >>> public getODataTransactionContext() {
> >>>      return ODataTransactionContext;
> >>> }
> >>> 
> >>> public setODataTransactionContext(ODataTransactionContext ctx) {...}
> >>> 
> >>> ---------
> >>> 
> >>> 
> >>> and ODataTransactionContext could be some kind of abstract class that has
> >>> the methods
> >>> 
> >>> public abstract class ODataTransactionContext {
> >>> 
> >>> public abstract void commitTransaction();
> >>> 
> >>> public abstract void startTransaction();
> >>> 
> >>> public abstract void rollbackTransaction();
> >>> 
> >>> public abstract boolean transactionIsActive();
> >>> 
> >>> }
> >>> 
> >>> -------
> >>> 
> >>> IMHO looks ugly; But using an interface for this would be even more
> >>> ugly....
> >>> 
> >>> 
> >>> Best,
> >>> 
> >>> Korbinian
> >>> 
> >>> 
> >>> ----- Ursprüngliche Mail -----
> >>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>> An: user@olingo.apache.org
> >>>> Gesendet: Donnerstag, 19. Februar 2015 08:07:59
> >>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>> 
> >>>> Hello Korbinian,
> >>>> I could have kept the methods as part of ODataJPAServiceFactory but the
> >>>> problem is, extending the ODataJPAServiceFactory class for an
> >>>> application
> >>>> is
> >>>> optional. Applications can create their own factory classes by directly
> >>>> inheriting ODataServiceFactory. We need to support such applications as
> >>>> well. I have created the JIRA issue
> >>>> https://issues.apache.org/jira/browse/OLINGO-580 to implement support
> >>>> for
> >>>> JTA based transactions.
> >>>> 
> >>>> Thanks
> >>>> Kind Regards
> >>>> Chandan
> >>>> 
> >>>> -----Original Message-----
> >>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>> Sent: Wednesday, February 18, 2015 7:30 PM
> >>>> To: user@olingo.apache.org
> >>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>> 
> >>>> Hello Chandan,
> >>>> 
> >>>> sounds good. What I would do - based upon your idea - is to extend the
> >>>> ODataJPAServiceFactory with 4 methods (as this one has to be used in any
> >>>> case):
> >>>> 
> >>>> public static void startTransaction(EntityManager em, Object
> >>>> transaction)
> >>>> {
> >>>>   em.getTransaction().begin();
> >>>>   transaction = em.getTransaction();
> >>>> }
> >>>> 
> >>>> public static void commitTransaction(Object transaction) {
> >>>>   ((EntitiyTransaction) transaction).commit();
> >>>> }
> >>>> 
> >>>> public static void rollbackTransaction(Object transaction) {
> >>>>   ((EntitiyTransaction) transaction).rollback();
> >>>> }
> >>>> 
> >>>> public static boolean transactionIsActive(Object transaction) {
> >>>>  return ((EntitiyTransaction) transaction).isActive();
> >>>> }
> >>>> 
> >>>> These then would be called from wherever olingo JPA needs them.
> >>>> 
> >>>> That way any one needing JTA can override these methods while the rest
> >>>> won't
> >>>> even notice them...
> >>>> 
> >>>> 
> >>>> What do you think?
> >>>> 
> >>>> Best,
> >>>> 
> >>>> Korbinian
> >>>> 
> >>>> 
> >>>> 
> >>>> 
> >>>> 
> >>>> ----- Ursprüngliche Mail -----
> >>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>> An: user@olingo.apache.org
> >>>>> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
> >>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>> 
> >>>>> Hello Korbinian,
> >>>>> I would at least keep the application managed transactions (like JTA)
> >>>>> outside
> >>>>> the context of JPA Processor for following reasons
> >>>>> 1) Wiring the JTA transactions into JPA processor could make the
> >>>>> processor
> >>>>> to
> >>>>> behave more like a framework than as a library (which is the current
> >>>>> state).
> >>>>> 2) JPA processor also need to take JNDI lookup as parameter from
> >>>>> applications
> >>>>> for looking up the datasource.
> >>>>> 3) Olingo JPA processor should take care of just data transformations
> >>>>> and
> >>>>> need not worry about the scope of transactions
> >>>>> 4) Olingo JPA processor should not take dependency to J2EE api because
> >>>>> I
> >>>>> am
> >>>>> not sure will this artifact work in OSGI environments
> >>>>> 
> >>>>> One proposal from my side would be to provide a callback mechanism for
> >>>>> transaction handling, where the library just calls a method in the
> >>>>> interface
> >>>>> to begin the transaction and end the transaction. If no one implements
> >>>>> the
> >>>>> callback mechanism the library would resort to "RESOURCE_LOCAL" based
> >>>>> transaction handling. With this approach applications will have a
> >>>>> greater
> >>>>> control over transaction handling and also need not rewrite
> >>>>> JPAProcessorImpl
> >>>>> or extend ODataJPAProcessor.
> >>>>> 
> >>>>> What do you think? Do you foresee any shortcomings with this approach?
> >>>>> 
> >>>>> Thanks
> >>>>> Kind Regards
> >>>>> Chandan
> >>>>> 
> >>>>> 
> >>>>> 
> >>>>> -----Original Message-----
> >>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>> Sent: Wednesday, February 18, 2015 6:22 PM
> >>>>> To: user@olingo.apache.org
> >>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>>> 
> >>>>> Hello Chandan,
> >>>>> 
> >>>>> I finally had some success in using JTA based transactions. However,
> >>>>> this
> >>>>> only worked when I cloned the current git and changed it in the
> >>>>> JPAProcessorImpl directly; If I try to do this from within my project
> >>>>> onto
> >>>>> the intialization with
> >>>>> 
> >>>>> oDatJPAContext.setODataProcessor(new
> >>>>> ODataJPAProcessorJTA(oDatJPAContext));
> >>>>> 
> >>>>> I then have to do a ODataJPAProcessorJTA which is 99% copy n paste from
> >>>>> ODataJPAProcessor and then also need a 95% copy n paste
> >>>>> JPAProcessorImplJTA
> >>>>> from JPAProcessorImpl;
> >>>>> 
> >>>>> As if this isn't ugly enough, it gets real dirty when trying to use it
> >>>>> as
> >>>>> you
> >>>>> simply cant force olingo to use it! Problem is that it comes from the
> >>>>> JPAAccessFactoryImpl class static; is a static one and sits in
> >>>>> ODataJPAFactoryImpl and finally this one gets called in public abstract
> >>>>> class ODataJPAFactory
> >>>>> 
> >>>>> using
> >>>>> 
> >>>>> public static ODataJPAFactory createFactory() {
> >>>>> 
> >>>>>   if (factoryImpl != null) {
> >>>>>     return factoryImpl;
> >>>>>   } else {
> >>>>>     try {
> >>>>>       Class<?> clazz = Class.forName(ODataJPAFactory.IMPLEMENTATION);
> >>>>> 
> >>>>>       Object object = clazz.newInstance();
> >>>>>       factoryImpl = (ODataJPAFactory) object;
> >>>>> 
> >>>>>     } catch (Exception e) {
> >>>>>       throw new RuntimeException(e);
> >>>>>     }
> >>>>> 
> >>>>>     return factoryImpl;
> >>>>>   }
> >>>>> }
> >>>>> 
> >>>>> where private static final String IMPLEMENTATION =
> >>>>>     "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
> >>>>> 
> >>>>> 
> >>>>> Simple said - overriding this logic in the olingo project is next to
> >>>>> impossible as you would end up with nearly the whole project
> >>>>> copy'n'pasted
> >>>>> over; Simple changing the e.g.  resolver etc. wont works as there are
> >>>>> many
> >>>>> usages of the ODataJPAFactory createFactory() method;
> >>>>> 
> >>>>> 
> >>>>> Implementing JTA to work in olingo on the other hand is quite easy. You
> >>>>> can
> >>>>> check on the fly if your JTA or not via e.g.:
> >>>>> 
> >>>>> public static boolean isResourceLocal(EntityManager em) {
> >>>>>       try {
> >>>>>           EntityTransaction tx = em.getTransaction();
> >>>>>           return true;
> >>>>>       } catch (IllegalStateException ex) {
> >>>>>           return false;
> >>>>>       }
> >>>>>   }
> >>>>> 
> >>>>> and this one can then set into a boolean var classwide in the
> >>>>> JPAProcessorImpl; so the setTransaction would become:
> >>>>> 
> >>>>> private boolean setTransaction() {
> >>>>>     if(isLocalTX) {
> >>>>>         final EntityTransaction transaction = em.getTransaction();
> >>>>>         if (!transaction.isActive()) {
> >>>>>             em.getTransaction().begin();
> >>>>>             return true;
> >>>>>         }
> >>>>>     } else {
> >>>>>         try {
> >>>>>             transaction = (UserTransaction) new
> >>>>>             InitialContext().lookup("java:comp/UserTransaction");
> >>>>>             transaction.begin();
> >>>>>         } catch (NamingException e) {
> >>>>>             e.printStackTrace();
> >>>>>         } catch (NotSupportedException e) {
> >>>>>             e.printStackTrace();
> >>>>>         } catch (SystemException e) {
> >>>>>             e.printStackTrace();
> >>>>>         }
> >>>>>     }
> >>>>> 
> >>>>> 
> >>>>>   return false;
> >>>>> }
> >>>>> 
> >>>>> 
> >>>>> and this would work on all JTA bases Servers. The rest of the
> >>>>> transaction
> >>>>> logic would simply look like e.g.:
> >>>>> 
> >>>>> if (isLocalTransaction) {
> >>>>>       em.getTransaction().commit();
> >>>>>     }
> >>>>> if(transaction != null) {
> >>>>>           transaction.commit();
> >>>>>     }
> >>>>> Or even
> >>>>> if (isLocalTransaction) {
> >>>>>       em.getTransaction().commit();
> >>>>>     }
> >>>>> else {
> >>>>>           transaction.commit();
> >>>>>     }
> >>>>> in case we expect a 100% availbilty of transactional context;
> >>>>> 
> >>>>> 
> >>>>> 
> >>>>> Problem is now that this needs at least the dependency of
> >>>>>       <dependency>
> >>>>>           <groupId>javax</groupId>
> >>>>>           <artifactId>javaee-api</artifactId>
> >>>>>           <version>6.0</version>
> >>>>>       </dependency>
> >>>>> as else there is no UserTransaction class available; Would this
> >>>>> dependency
> >>>>> be
> >>>>> ok for the JPA part of the olingo project?
> >>>>> 
> >>>>> What do you think?
> >>>>> 
> >>>>> Best,
> >>>>> 
> >>>>> Korbinian
> >>>>> 
> >>>>> 
> >>>>> 
> >>>>> ----- Ursprüngliche Mail -----
> >>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>> An: user@olingo.apache.org
> >>>>>> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
> >>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>> 
> >>>>>> Hello Korbinian,
> >>>>>> Please check the JIRA item -
> >>>>>> https://issues.apache.org/jira/browse/OLINGO-549
> >>>>>> for updates on Olingo V4 JPA processor. Current status is there is no
> >>>>>> support for V4 JPA processor and the development is in progress.
> >>>>>> 
> >>>>>> Thanks
> >>>>>> Kind Regards
> >>>>>> Chandan
> >>>>>> 
> >>>>>> -----Original Message-----
> >>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>> Sent: Wednesday, February 18, 2015 2:48 PM
> >>>>>> To: user@olingo.apache.org
> >>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>>>> 
> >>>>>> Hello Chandan,
> >>>>>> 
> >>>>>> thank you for the info. Will try this. I've seen that Olingo also has
> >>>>>> a
> >>>>>> OData
> >>>>>> V4 in Beta2 - but I couldn't really find information about its
> >>>>>> "readyness".
> >>>>>> Would it work in a simple CRUD scenario with JPA? Reason is as it
> >>>>>> seems
> >>>>>> as
> >>>>>> my other system I talk to via OData is moving from V3 to V4 currently,
> >>>>>> at
> >>>>>> least the doc of its alredy speaks of OData V4 ready.
> >>>>>> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
> >>>>>> 
> >>>>>> Best,
> >>>>>> 
> >>>>>> Korbinian
> >>>>>> 
> >>>>>> 
> >>>>>> 
> >>>>>> ----- Ursprüngliche Mail -----
> >>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>>> An: user@olingo.apache.org
> >>>>>>> Gesendet: Dienstag, 17. Februar 2015 07:11:28
> >>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>>> 
> >>>>>>> Hello Korbinian,
> >>>>>>> You can extend the
> >>>>>>> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and
> >>>>>>> implement
> >>>>>>> the processor methods as it is done in
> >>>>>>> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.
> >>>>>>> In
> >>>>>>> your implementation for Create, Update and Delete you could begin the
> >>>>>>> JTA
> >>>>>>> transaction and close the transaction by either commit or rollback.
> >>>>>>> 
> >>>>>>> I have not tried the scenario with JTA based transactions but only
> >>>>>>> Resource
> >>>>>>> Local based transactions. Please check and tell if the above solution
> >>>>>>> works
> >>>>>>> for your case. Else raise a JIRA feature request to support JTA based
> >>>>>>> transactions.
> >>>>>>> 
> >>>>>>> Regards
> >>>>>>> Chandan
> >>>>>>> 
> >>>>>>> -----Original Message-----
> >>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>>> Sent: Monday, February 16, 2015 2:16 PM
> >>>>>>> To: user@olingo.apache.org
> >>>>>>> Subject: olingo JPA / JTA - wrong transactions used
> >>>>>>> 
> >>>>>>> Hi,
> >>>>>>> 
> >>>>>>> I'm using Olingo 2.0.2 and I can query all items so far. When I want
> >>>>>>> to
> >>>>>>> update content, I get error:
> >>>>>>> 
> >>>>>>> ...
> >>>>>>> <message xml:lang="en">"OData - JPA Runtime: JPA update request is
> >>>>>>> not
> >>>>>>> correct"message>
> >>>>>>>   <innererror>class java.lang.IllegalStateException :
> >>>>>>> Exception Description: Cannot use an EntityTransaction while using
> >>>>>>> JTA.innererror>
> >>>>>>> ....
> >>>>>>> 
> >>>>>>> Digging deeper into the code, I ended up in file ODataJPAContextImpl
> >>>>>>> 
> >>>>>>> and there in the function
> >>>>>>> 
> >>>>>>> private  Object processUpdate(PutMergePatchUriInfo updateView,
> >>>>>>>     final InputStream content, final Map<String, Object> properties,
> >>>>>>>     final
> >>>>>>>     String requestContentType)
> >>>>>>>     throws ODataJPAModelException, ODataJPARuntimeException {
> >>>>>>> ...
> >>>>>>> boolean isLocalTransaction = setTransaction();
> >>>>>>> 
> >>>>>>> ...
> >>>>>>> }
> >>>>>>> 
> >>>>>>> with
> >>>>>>> 
> >>>>>>> private boolean setTransaction() {
> >>>>>>>   final EntityTransaction transaction = em.getTransaction();
> >>>>>>>   if (!transaction.isActive()) {
> >>>>>>>     em.getTransaction().begin();
> >>>>>>>     return true;
> >>>>>>>   }
> >>>>>>> 
> >>>>>>>   return false;
> >>>>>>> }
> >>>>>>> 
> >>>>>>> 
> >>>>>>> So far I understood this one is the function that collides with my
> >>>>>>> JTA
> >>>>>>> setup.
> >>>>>>> I now wonder how I can suppress to initialize this method?
> >>>>>>> 
> >>>>>>> I've sending in the right EntityManagerFactory into Olingo, e.g.:
> >>>>>>> 
> >>>>>>> public class ConnectorODataJPAServiceFactory extends
> >>>>>>> ODataJPAServiceFactory
> >>>>>>> {
> >>>>>>> 
> >>>>>>>   private static final String PERSISTENCE_UNIT_NAME = "myPU";
> >>>>>>> 
> >>>>>>>   @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
> >>>>>>>   EntityManagerFactory emf;
> >>>>>>> 
> >>>>>>> 
> >>>>>>>   @Override
> >>>>>>>   public ODataJPAContext initializeODataJPAContext() throws
> >>>>>>>   ODataJPARuntimeException {
> >>>>>>>       ODataJPAContext oDatJPAContext = this.getODataJPAContext();
> >>>>>>> 
> >>>>>>>       try {
> >>>>>>>           CdiContainer.get().getNonContextualManager().postConstruct(this);
> >>>>>>>           oDatJPAContext.setEntityManagerFactory(emf);
> >>>>>>>           oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
> >>>>>>>           oDatJPAContext.setPageSize(100);
> >>>>>>>           setDetailErrors(true);
> >>>>>>>           return oDatJPAContext;
> >>>>>>>       } catch (Exception e) {
> >>>>>>>           System.out.print(e);
> >>>>>>>           throw new RuntimeException(e);
> >>>>>>>       }
> >>>>>>>   }
> >>>>>>> 
> >>>>>>> ...
> >>>>>>> 
> >>>>>>> So where is the catch here?
> >>>>>>> 
> >>>>>>> 
> >>>>>>> Best,
> >>>>>>> 
> >>>>>>> Korbinian
> >>>>>>> 
> >>>>>> 
> >>>>> 
> >>>> 
> >> 
> >> 
> 
> 

Re: olingo JPA / JTA - wrong transactions used

Posted by Korbinian Bachl <ko...@whiskyworld.de>.
Here you go: https://github.com/apache/olingo-odata2/pull/2

Best,

Korbinian


----- Ursprüngliche Mail -----
> Von: "Michael Bolz" <mi...@sap.com>
> An: user@olingo.apache.org
> CC: "korbinian bachl" <ko...@whiskyworld.de>
> Gesendet: Donnerstag, 26. Februar 2015 08:56:45
> Betreff: Re: olingo JPA / JTA - wrong transactions used
> 
> Hello Korbinian,
> 
> I would prefer to add this just at “ODataJPAServiceFactory”.
> First this way it is consistent with the “setODataTransactionContext” and
> second the callback is only related to database (JTA) dependent (using)
> OData services.
> @Korbinian and Chandan: I think (hope) you both agree with my opinion  ;o)
> 
> When you send me the pull request I will check it and afterwards merge into
> Olingo master.
> 
> Kind regards,
> Michael
> 
> > On 25 Feb 2015, at 12:17, Korbinian Bachl <ko...@whiskyworld.de>
> > wrote:
> > 
> > Hello Michael,
> > 
> > I've looked at the suggested OnJPAWriteContent-approach and this would
> > work. Question is just if the callback should be implemented within
> > ODataServiceFactory or just within ODataJPAServiceFactory;
> > 
> > Either way we would need one (1) interface
> > 
> > public interface ODataTransactionContext extends ODataCallback {
> > 
> > public void startTransaction();
> > 
> > public void commitTransaction();
> > 
> > public void rollbackTransaction();
> > 
> > public boolean transactionIsActive();
> > 
> > }
> > 
> > as well as 1 class that implements the current default;
> > 
> > it would be put into the Factory class like
> > 
> > protected void setODataTransactionContext(final ODataTransactionContext
> > oDataTransactionContext) {
> >    this.oDataTransactionContext = oDataTransactionContext;
> > }
> > 
> > and any access to transactions would then need to run via
> > getTransactionContext() e.g.:
> > 
> > FactoryClassInstace.getTransactionContext().startTransaction();
> > 
> > (or if you want the more noisy version:
> > FactoryClassInstace.getCallback(ODataTransactionContext.class).startTransaction();
> > - something I really dont like as this calling stack of
> > if(callbackInterface.isAssignableFrom... ) is something I see waste of CPU
> > cycles in regular and often called code areas, bad habbit IMHO)
> > 
> > 
> > Any other usages like JTA can then override the
> > setODataTransactionContext(...) and supply a class that "does" exactly
> > what needed.
> > 
> > 
> > If this is the way to go, then just let me know which "way" you want it and
> > I can send you a pull request for it (on github);
> > 
> > 
> > 
> > Best,
> > 
> > Korbinian
> > 
> > ----- Ursprüngliche Mail -----
> >> Von: "Michael Bolz" <mi...@sap.com>
> >> An: user@olingo.apache.org
> >> Gesendet: Montag, 23. Februar 2015 11:03:40
> >> Betreff: Re: olingo JPA / JTA - wrong transactions used
> >> 
> >> Hi,
> >> 
> >> could a solution with the “Callback” approach (like the
> >> “OnJPAWriteContent”)
> >> work for this?
> >> So that the “ODataTransactionContext” is implemented as
> >> “ODataTransactionCallback”?
> >> 
> >> This way in the “ODataJPAServiceFactory” a method like: "protected void
> >> setTransactionCallback(final ODataTransactionCallback callback)” can be
> >> provided and
> >> if someone want to implement (inherit) his own “ODataServiceFactory” he
> >> can
> >> support the callback (interface) directly via the “getCallback(…)” method.
> >> 
> >> Kind regards,
> >> Michael
> >> 
> >> 
> >>> On 23 Feb 2015, at 10:17, Korbinian Bachl
> >>> <ko...@whiskyworld.de>
> >>> wrote:
> >>> 
> >>> Hello Chandan,
> >>> 
> >>> I've looked into the ODataServiceFactory and its usages and I really dont
> >>> think this is good. Problems are
> >>> 
> >>> a, ODataServiceFactory is in lib module - so no external dependency
> >>> should
> >>> be pulled into
> >>> b, just extending the class like I suggested wont work as we would have
> >>> to
> >>> fix over 13 implementations of this Factory as well - not speaking about
> >>> any custom implementations so far;
> >>> c, I currently dont see the "need" to have JTA outside of JPA context -
> >>> since no one ever asked for it;
> >>> 
> >>> What I can think of is a CustomTransaction class object that gets its
> >>> "hold" within ODataServiceFactory and needs to be setup by the
> >>> implementation of the ODataServiceFactory only if it needs to use it.
> >>> Something like e.g.:
> >>> 
> >>> in ODataServiceFactory:
> >>> ----------
> >>> private ODataTransactionContext = null;
> >>> 
> >>> //stub - needs to be implemented if want to be used
> >>> public void setUpTransactionContext() {};
> >>> 
> >>> public getODataTransactionContext() {
> >>>      return ODataTransactionContext;
> >>> }
> >>> 
> >>> public setODataTransactionContext(ODataTransactionContext ctx) {...}
> >>> 
> >>> ---------
> >>> 
> >>> 
> >>> and ODataTransactionContext could be some kind of abstract class that has
> >>> the methods
> >>> 
> >>> public abstract class ODataTransactionContext {
> >>> 
> >>> public abstract void commitTransaction();
> >>> 
> >>> public abstract void startTransaction();
> >>> 
> >>> public abstract void rollbackTransaction();
> >>> 
> >>> public abstract boolean transactionIsActive();
> >>> 
> >>> }
> >>> 
> >>> -------
> >>> 
> >>> IMHO looks ugly; But using an interface for this would be even more
> >>> ugly....
> >>> 
> >>> 
> >>> Best,
> >>> 
> >>> Korbinian
> >>> 
> >>> 
> >>> ----- Ursprüngliche Mail -----
> >>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>> An: user@olingo.apache.org
> >>>> Gesendet: Donnerstag, 19. Februar 2015 08:07:59
> >>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>> 
> >>>> Hello Korbinian,
> >>>> I could have kept the methods as part of ODataJPAServiceFactory but the
> >>>> problem is, extending the ODataJPAServiceFactory class for an
> >>>> application
> >>>> is
> >>>> optional. Applications can create their own factory classes by directly
> >>>> inheriting ODataServiceFactory. We need to support such applications as
> >>>> well. I have created the JIRA issue
> >>>> https://issues.apache.org/jira/browse/OLINGO-580 to implement support
> >>>> for
> >>>> JTA based transactions.
> >>>> 
> >>>> Thanks
> >>>> Kind Regards
> >>>> Chandan
> >>>> 
> >>>> -----Original Message-----
> >>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>> Sent: Wednesday, February 18, 2015 7:30 PM
> >>>> To: user@olingo.apache.org
> >>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>> 
> >>>> Hello Chandan,
> >>>> 
> >>>> sounds good. What I would do - based upon your idea - is to extend the
> >>>> ODataJPAServiceFactory with 4 methods (as this one has to be used in any
> >>>> case):
> >>>> 
> >>>> public static void startTransaction(EntityManager em, Object
> >>>> transaction)
> >>>> {
> >>>>   em.getTransaction().begin();
> >>>>   transaction = em.getTransaction();
> >>>> }
> >>>> 
> >>>> public static void commitTransaction(Object transaction) {
> >>>>   ((EntitiyTransaction) transaction).commit();
> >>>> }
> >>>> 
> >>>> public static void rollbackTransaction(Object transaction) {
> >>>>   ((EntitiyTransaction) transaction).rollback();
> >>>> }
> >>>> 
> >>>> public static boolean transactionIsActive(Object transaction) {
> >>>>  return ((EntitiyTransaction) transaction).isActive();
> >>>> }
> >>>> 
> >>>> These then would be called from wherever olingo JPA needs them.
> >>>> 
> >>>> That way any one needing JTA can override these methods while the rest
> >>>> won't
> >>>> even notice them...
> >>>> 
> >>>> 
> >>>> What do you think?
> >>>> 
> >>>> Best,
> >>>> 
> >>>> Korbinian
> >>>> 
> >>>> 
> >>>> 
> >>>> 
> >>>> 
> >>>> ----- Ursprüngliche Mail -----
> >>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>> An: user@olingo.apache.org
> >>>>> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
> >>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>> 
> >>>>> Hello Korbinian,
> >>>>> I would at least keep the application managed transactions (like JTA)
> >>>>> outside
> >>>>> the context of JPA Processor for following reasons
> >>>>> 1) Wiring the JTA transactions into JPA processor could make the
> >>>>> processor
> >>>>> to
> >>>>> behave more like a framework than as a library (which is the current
> >>>>> state).
> >>>>> 2) JPA processor also need to take JNDI lookup as parameter from
> >>>>> applications
> >>>>> for looking up the datasource.
> >>>>> 3) Olingo JPA processor should take care of just data transformations
> >>>>> and
> >>>>> need not worry about the scope of transactions
> >>>>> 4) Olingo JPA processor should not take dependency to J2EE api because
> >>>>> I
> >>>>> am
> >>>>> not sure will this artifact work in OSGI environments
> >>>>> 
> >>>>> One proposal from my side would be to provide a callback mechanism for
> >>>>> transaction handling, where the library just calls a method in the
> >>>>> interface
> >>>>> to begin the transaction and end the transaction. If no one implements
> >>>>> the
> >>>>> callback mechanism the library would resort to "RESOURCE_LOCAL" based
> >>>>> transaction handling. With this approach applications will have a
> >>>>> greater
> >>>>> control over transaction handling and also need not rewrite
> >>>>> JPAProcessorImpl
> >>>>> or extend ODataJPAProcessor.
> >>>>> 
> >>>>> What do you think? Do you foresee any shortcomings with this approach?
> >>>>> 
> >>>>> Thanks
> >>>>> Kind Regards
> >>>>> Chandan
> >>>>> 
> >>>>> 
> >>>>> 
> >>>>> -----Original Message-----
> >>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>> Sent: Wednesday, February 18, 2015 6:22 PM
> >>>>> To: user@olingo.apache.org
> >>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>>> 
> >>>>> Hello Chandan,
> >>>>> 
> >>>>> I finally had some success in using JTA based transactions. However,
> >>>>> this
> >>>>> only worked when I cloned the current git and changed it in the
> >>>>> JPAProcessorImpl directly; If I try to do this from within my project
> >>>>> onto
> >>>>> the intialization with
> >>>>> 
> >>>>> oDatJPAContext.setODataProcessor(new
> >>>>> ODataJPAProcessorJTA(oDatJPAContext));
> >>>>> 
> >>>>> I then have to do a ODataJPAProcessorJTA which is 99% copy n paste from
> >>>>> ODataJPAProcessor and then also need a 95% copy n paste
> >>>>> JPAProcessorImplJTA
> >>>>> from JPAProcessorImpl;
> >>>>> 
> >>>>> As if this isn't ugly enough, it gets real dirty when trying to use it
> >>>>> as
> >>>>> you
> >>>>> simply cant force olingo to use it! Problem is that it comes from the
> >>>>> JPAAccessFactoryImpl class static; is a static one and sits in
> >>>>> ODataJPAFactoryImpl and finally this one gets called in public abstract
> >>>>> class ODataJPAFactory
> >>>>> 
> >>>>> using
> >>>>> 
> >>>>> public static ODataJPAFactory createFactory() {
> >>>>> 
> >>>>>   if (factoryImpl != null) {
> >>>>>     return factoryImpl;
> >>>>>   } else {
> >>>>>     try {
> >>>>>       Class<?> clazz = Class.forName(ODataJPAFactory.IMPLEMENTATION);
> >>>>> 
> >>>>>       Object object = clazz.newInstance();
> >>>>>       factoryImpl = (ODataJPAFactory) object;
> >>>>> 
> >>>>>     } catch (Exception e) {
> >>>>>       throw new RuntimeException(e);
> >>>>>     }
> >>>>> 
> >>>>>     return factoryImpl;
> >>>>>   }
> >>>>> }
> >>>>> 
> >>>>> where private static final String IMPLEMENTATION =
> >>>>>     "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
> >>>>> 
> >>>>> 
> >>>>> Simple said - overriding this logic in the olingo project is next to
> >>>>> impossible as you would end up with nearly the whole project
> >>>>> copy'n'pasted
> >>>>> over; Simple changing the e.g.  resolver etc. wont works as there are
> >>>>> many
> >>>>> usages of the ODataJPAFactory createFactory() method;
> >>>>> 
> >>>>> 
> >>>>> Implementing JTA to work in olingo on the other hand is quite easy. You
> >>>>> can
> >>>>> check on the fly if your JTA or not via e.g.:
> >>>>> 
> >>>>> public static boolean isResourceLocal(EntityManager em) {
> >>>>>       try {
> >>>>>           EntityTransaction tx = em.getTransaction();
> >>>>>           return true;
> >>>>>       } catch (IllegalStateException ex) {
> >>>>>           return false;
> >>>>>       }
> >>>>>   }
> >>>>> 
> >>>>> and this one can then set into a boolean var classwide in the
> >>>>> JPAProcessorImpl; so the setTransaction would become:
> >>>>> 
> >>>>> private boolean setTransaction() {
> >>>>>     if(isLocalTX) {
> >>>>>         final EntityTransaction transaction = em.getTransaction();
> >>>>>         if (!transaction.isActive()) {
> >>>>>             em.getTransaction().begin();
> >>>>>             return true;
> >>>>>         }
> >>>>>     } else {
> >>>>>         try {
> >>>>>             transaction = (UserTransaction) new
> >>>>>             InitialContext().lookup("java:comp/UserTransaction");
> >>>>>             transaction.begin();
> >>>>>         } catch (NamingException e) {
> >>>>>             e.printStackTrace();
> >>>>>         } catch (NotSupportedException e) {
> >>>>>             e.printStackTrace();
> >>>>>         } catch (SystemException e) {
> >>>>>             e.printStackTrace();
> >>>>>         }
> >>>>>     }
> >>>>> 
> >>>>> 
> >>>>>   return false;
> >>>>> }
> >>>>> 
> >>>>> 
> >>>>> and this would work on all JTA bases Servers. The rest of the
> >>>>> transaction
> >>>>> logic would simply look like e.g.:
> >>>>> 
> >>>>> if (isLocalTransaction) {
> >>>>>       em.getTransaction().commit();
> >>>>>     }
> >>>>> if(transaction != null) {
> >>>>>           transaction.commit();
> >>>>>     }
> >>>>> Or even
> >>>>> if (isLocalTransaction) {
> >>>>>       em.getTransaction().commit();
> >>>>>     }
> >>>>> else {
> >>>>>           transaction.commit();
> >>>>>     }
> >>>>> in case we expect a 100% availbilty of transactional context;
> >>>>> 
> >>>>> 
> >>>>> 
> >>>>> Problem is now that this needs at least the dependency of
> >>>>>       <dependency>
> >>>>>           <groupId>javax</groupId>
> >>>>>           <artifactId>javaee-api</artifactId>
> >>>>>           <version>6.0</version>
> >>>>>       </dependency>
> >>>>> as else there is no UserTransaction class available; Would this
> >>>>> dependency
> >>>>> be
> >>>>> ok for the JPA part of the olingo project?
> >>>>> 
> >>>>> What do you think?
> >>>>> 
> >>>>> Best,
> >>>>> 
> >>>>> Korbinian
> >>>>> 
> >>>>> 
> >>>>> 
> >>>>> ----- Ursprüngliche Mail -----
> >>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>> An: user@olingo.apache.org
> >>>>>> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
> >>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>> 
> >>>>>> Hello Korbinian,
> >>>>>> Please check the JIRA item -
> >>>>>> https://issues.apache.org/jira/browse/OLINGO-549
> >>>>>> for updates on Olingo V4 JPA processor. Current status is there is no
> >>>>>> support for V4 JPA processor and the development is in progress.
> >>>>>> 
> >>>>>> Thanks
> >>>>>> Kind Regards
> >>>>>> Chandan
> >>>>>> 
> >>>>>> -----Original Message-----
> >>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>> Sent: Wednesday, February 18, 2015 2:48 PM
> >>>>>> To: user@olingo.apache.org
> >>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>>>> 
> >>>>>> Hello Chandan,
> >>>>>> 
> >>>>>> thank you for the info. Will try this. I've seen that Olingo also has
> >>>>>> a
> >>>>>> OData
> >>>>>> V4 in Beta2 - but I couldn't really find information about its
> >>>>>> "readyness".
> >>>>>> Would it work in a simple CRUD scenario with JPA? Reason is as it
> >>>>>> seems
> >>>>>> as
> >>>>>> my other system I talk to via OData is moving from V3 to V4 currently,
> >>>>>> at
> >>>>>> least the doc of its alredy speaks of OData V4 ready.
> >>>>>> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
> >>>>>> 
> >>>>>> Best,
> >>>>>> 
> >>>>>> Korbinian
> >>>>>> 
> >>>>>> 
> >>>>>> 
> >>>>>> ----- Ursprüngliche Mail -----
> >>>>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>>>> An: user@olingo.apache.org
> >>>>>>> Gesendet: Dienstag, 17. Februar 2015 07:11:28
> >>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>>>> 
> >>>>>>> Hello Korbinian,
> >>>>>>> You can extend the
> >>>>>>> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and
> >>>>>>> implement
> >>>>>>> the processor methods as it is done in
> >>>>>>> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.
> >>>>>>> In
> >>>>>>> your implementation for Create, Update and Delete you could begin the
> >>>>>>> JTA
> >>>>>>> transaction and close the transaction by either commit or rollback.
> >>>>>>> 
> >>>>>>> I have not tried the scenario with JTA based transactions but only
> >>>>>>> Resource
> >>>>>>> Local based transactions. Please check and tell if the above solution
> >>>>>>> works
> >>>>>>> for your case. Else raise a JIRA feature request to support JTA based
> >>>>>>> transactions.
> >>>>>>> 
> >>>>>>> Regards
> >>>>>>> Chandan
> >>>>>>> 
> >>>>>>> -----Original Message-----
> >>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>>>> Sent: Monday, February 16, 2015 2:16 PM
> >>>>>>> To: user@olingo.apache.org
> >>>>>>> Subject: olingo JPA / JTA - wrong transactions used
> >>>>>>> 
> >>>>>>> Hi,
> >>>>>>> 
> >>>>>>> I'm using Olingo 2.0.2 and I can query all items so far. When I want
> >>>>>>> to
> >>>>>>> update content, I get error:
> >>>>>>> 
> >>>>>>> ...
> >>>>>>> <message xml:lang="en">"OData - JPA Runtime: JPA update request is
> >>>>>>> not
> >>>>>>> correct"message>
> >>>>>>>   <innererror>class java.lang.IllegalStateException :
> >>>>>>> Exception Description: Cannot use an EntityTransaction while using
> >>>>>>> JTA.innererror>
> >>>>>>> ....
> >>>>>>> 
> >>>>>>> Digging deeper into the code, I ended up in file ODataJPAContextImpl
> >>>>>>> 
> >>>>>>> and there in the function
> >>>>>>> 
> >>>>>>> private  Object processUpdate(PutMergePatchUriInfo updateView,
> >>>>>>>     final InputStream content, final Map<String, Object> properties,
> >>>>>>>     final
> >>>>>>>     String requestContentType)
> >>>>>>>     throws ODataJPAModelException, ODataJPARuntimeException {
> >>>>>>> ...
> >>>>>>> boolean isLocalTransaction = setTransaction();
> >>>>>>> 
> >>>>>>> ...
> >>>>>>> }
> >>>>>>> 
> >>>>>>> with
> >>>>>>> 
> >>>>>>> private boolean setTransaction() {
> >>>>>>>   final EntityTransaction transaction = em.getTransaction();
> >>>>>>>   if (!transaction.isActive()) {
> >>>>>>>     em.getTransaction().begin();
> >>>>>>>     return true;
> >>>>>>>   }
> >>>>>>> 
> >>>>>>>   return false;
> >>>>>>> }
> >>>>>>> 
> >>>>>>> 
> >>>>>>> So far I understood this one is the function that collides with my
> >>>>>>> JTA
> >>>>>>> setup.
> >>>>>>> I now wonder how I can suppress to initialize this method?
> >>>>>>> 
> >>>>>>> I've sending in the right EntityManagerFactory into Olingo, e.g.:
> >>>>>>> 
> >>>>>>> public class ConnectorODataJPAServiceFactory extends
> >>>>>>> ODataJPAServiceFactory
> >>>>>>> {
> >>>>>>> 
> >>>>>>>   private static final String PERSISTENCE_UNIT_NAME = "myPU";
> >>>>>>> 
> >>>>>>>   @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
> >>>>>>>   EntityManagerFactory emf;
> >>>>>>> 
> >>>>>>> 
> >>>>>>>   @Override
> >>>>>>>   public ODataJPAContext initializeODataJPAContext() throws
> >>>>>>>   ODataJPARuntimeException {
> >>>>>>>       ODataJPAContext oDatJPAContext = this.getODataJPAContext();
> >>>>>>> 
> >>>>>>>       try {
> >>>>>>>           CdiContainer.get().getNonContextualManager().postConstruct(this);
> >>>>>>>           oDatJPAContext.setEntityManagerFactory(emf);
> >>>>>>>           oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
> >>>>>>>           oDatJPAContext.setPageSize(100);
> >>>>>>>           setDetailErrors(true);
> >>>>>>>           return oDatJPAContext;
> >>>>>>>       } catch (Exception e) {
> >>>>>>>           System.out.print(e);
> >>>>>>>           throw new RuntimeException(e);
> >>>>>>>       }
> >>>>>>>   }
> >>>>>>> 
> >>>>>>> ...
> >>>>>>> 
> >>>>>>> So where is the catch here?
> >>>>>>> 
> >>>>>>> 
> >>>>>>> Best,
> >>>>>>> 
> >>>>>>> Korbinian
> >>>>>>> 
> >>>>>> 
> >>>>> 
> >>>> 
> >> 
> >> 
> 
> 

Re: olingo JPA / JTA - wrong transactions used

Posted by "Bolz, Michael" <mi...@sap.com>.
Hello Korbinian,

I would prefer to add this just at “ODataJPAServiceFactory”.
First this way it is consistent with the “setODataTransactionContext” and second the callback is only related to database (JTA) dependent (using) OData services.
@Korbinian and Chandan: I think (hope) you both agree with my opinion  ;o)

When you send me the pull request I will check it and afterwards merge into Olingo master.

Kind regards,
Michael

> On 25 Feb 2015, at 12:17, Korbinian Bachl <ko...@whiskyworld.de> wrote:
> 
> Hello Michael,
> 
> I've looked at the suggested OnJPAWriteContent-approach and this would work. Question is just if the callback should be implemented within 
> ODataServiceFactory or just within ODataJPAServiceFactory; 
> 
> Either way we would need one (1) interface 
> 
> public interface ODataTransactionContext extends ODataCallback {
> 
> public void startTransaction();
> 
> public void commitTransaction();
> 
> public void rollbackTransaction();
> 
> public boolean transactionIsActive();
> 
> }
> 
> as well as 1 class that implements the current default;
> 
> it would be put into the Factory class like 
> 
> protected void setODataTransactionContext(final ODataTransactionContext oDataTransactionContext) {
>    this.oDataTransactionContext = oDataTransactionContext;
> }
> 
> and any access to transactions would then need to run via getTransactionContext() e.g.:
> 
> FactoryClassInstace.getTransactionContext().startTransaction(); 
> 
> (or if you want the more noisy version: FactoryClassInstace.getCallback(ODataTransactionContext.class).startTransaction(); - something I really dont like as this calling stack of if(callbackInterface.isAssignableFrom... ) is something I see waste of CPU cycles in regular and often called code areas, bad habbit IMHO)
> 
> 
> Any other usages like JTA can then override the setODataTransactionContext(...) and supply a class that "does" exactly what needed.
> 
> 
> If this is the way to go, then just let me know which "way" you want it and I can send you a pull request for it (on github);
> 
> 
> 
> Best,
> 
> Korbinian 
> 
> ----- Ursprüngliche Mail -----
>> Von: "Michael Bolz" <mi...@sap.com>
>> An: user@olingo.apache.org
>> Gesendet: Montag, 23. Februar 2015 11:03:40
>> Betreff: Re: olingo JPA / JTA - wrong transactions used
>> 
>> Hi,
>> 
>> could a solution with the “Callback” approach (like the “OnJPAWriteContent”)
>> work for this?
>> So that the “ODataTransactionContext” is implemented as
>> “ODataTransactionCallback”?
>> 
>> This way in the “ODataJPAServiceFactory” a method like: "protected void
>> setTransactionCallback(final ODataTransactionCallback callback)” can be
>> provided and
>> if someone want to implement (inherit) his own “ODataServiceFactory” he can
>> support the callback (interface) directly via the “getCallback(…)” method.
>> 
>> Kind regards,
>> Michael
>> 
>> 
>>> On 23 Feb 2015, at 10:17, Korbinian Bachl <ko...@whiskyworld.de>
>>> wrote:
>>> 
>>> Hello Chandan,
>>> 
>>> I've looked into the ODataServiceFactory and its usages and I really dont
>>> think this is good. Problems are
>>> 
>>> a, ODataServiceFactory is in lib module - so no external dependency should
>>> be pulled into
>>> b, just extending the class like I suggested wont work as we would have to
>>> fix over 13 implementations of this Factory as well - not speaking about
>>> any custom implementations so far;
>>> c, I currently dont see the "need" to have JTA outside of JPA context -
>>> since no one ever asked for it;
>>> 
>>> What I can think of is a CustomTransaction class object that gets its
>>> "hold" within ODataServiceFactory and needs to be setup by the
>>> implementation of the ODataServiceFactory only if it needs to use it.
>>> Something like e.g.:
>>> 
>>> in ODataServiceFactory:
>>> ----------
>>> private ODataTransactionContext = null;
>>> 
>>> //stub - needs to be implemented if want to be used
>>> public void setUpTransactionContext() {};
>>> 
>>> public getODataTransactionContext() {
>>>      return ODataTransactionContext;
>>> }
>>> 
>>> public setODataTransactionContext(ODataTransactionContext ctx) {...}
>>> 
>>> ---------
>>> 
>>> 
>>> and ODataTransactionContext could be some kind of abstract class that has
>>> the methods
>>> 
>>> public abstract class ODataTransactionContext {
>>> 
>>> public abstract void commitTransaction();
>>> 
>>> public abstract void startTransaction();
>>> 
>>> public abstract void rollbackTransaction();
>>> 
>>> public abstract boolean transactionIsActive();
>>> 
>>> }
>>> 
>>> -------
>>> 
>>> IMHO looks ugly; But using an interface for this would be even more
>>> ugly....
>>> 
>>> 
>>> Best,
>>> 
>>> Korbinian
>>> 
>>> 
>>> ----- Ursprüngliche Mail -----
>>>> Von: "Chandan V.A" <ch...@sap.com>
>>>> An: user@olingo.apache.org
>>>> Gesendet: Donnerstag, 19. Februar 2015 08:07:59
>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>>>> 
>>>> Hello Korbinian,
>>>> I could have kept the methods as part of ODataJPAServiceFactory but the
>>>> problem is, extending the ODataJPAServiceFactory class for an application
>>>> is
>>>> optional. Applications can create their own factory classes by directly
>>>> inheriting ODataServiceFactory. We need to support such applications as
>>>> well. I have created the JIRA issue
>>>> https://issues.apache.org/jira/browse/OLINGO-580 to implement support for
>>>> JTA based transactions.
>>>> 
>>>> Thanks
>>>> Kind Regards
>>>> Chandan
>>>> 
>>>> -----Original Message-----
>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>>>> Sent: Wednesday, February 18, 2015 7:30 PM
>>>> To: user@olingo.apache.org
>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
>>>> 
>>>> Hello Chandan,
>>>> 
>>>> sounds good. What I would do - based upon your idea - is to extend the
>>>> ODataJPAServiceFactory with 4 methods (as this one has to be used in any
>>>> case):
>>>> 
>>>> public static void startTransaction(EntityManager em, Object transaction)
>>>> {
>>>>   em.getTransaction().begin();
>>>>   transaction = em.getTransaction();
>>>> }
>>>> 
>>>> public static void commitTransaction(Object transaction) {
>>>>   ((EntitiyTransaction) transaction).commit();
>>>> }
>>>> 
>>>> public static void rollbackTransaction(Object transaction) {
>>>>   ((EntitiyTransaction) transaction).rollback();
>>>> }
>>>> 
>>>> public static boolean transactionIsActive(Object transaction) {
>>>>  return ((EntitiyTransaction) transaction).isActive();
>>>> }
>>>> 
>>>> These then would be called from wherever olingo JPA needs them.
>>>> 
>>>> That way any one needing JTA can override these methods while the rest
>>>> won't
>>>> even notice them...
>>>> 
>>>> 
>>>> What do you think?
>>>> 
>>>> Best,
>>>> 
>>>> Korbinian
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> ----- Ursprüngliche Mail -----
>>>>> Von: "Chandan V.A" <ch...@sap.com>
>>>>> An: user@olingo.apache.org
>>>>> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>>>>> 
>>>>> Hello Korbinian,
>>>>> I would at least keep the application managed transactions (like JTA)
>>>>> outside
>>>>> the context of JPA Processor for following reasons
>>>>> 1) Wiring the JTA transactions into JPA processor could make the
>>>>> processor
>>>>> to
>>>>> behave more like a framework than as a library (which is the current
>>>>> state).
>>>>> 2) JPA processor also need to take JNDI lookup as parameter from
>>>>> applications
>>>>> for looking up the datasource.
>>>>> 3) Olingo JPA processor should take care of just data transformations and
>>>>> need not worry about the scope of transactions
>>>>> 4) Olingo JPA processor should not take dependency to J2EE api because I
>>>>> am
>>>>> not sure will this artifact work in OSGI environments
>>>>> 
>>>>> One proposal from my side would be to provide a callback mechanism for
>>>>> transaction handling, where the library just calls a method in the
>>>>> interface
>>>>> to begin the transaction and end the transaction. If no one implements
>>>>> the
>>>>> callback mechanism the library would resort to "RESOURCE_LOCAL" based
>>>>> transaction handling. With this approach applications will have a greater
>>>>> control over transaction handling and also need not rewrite
>>>>> JPAProcessorImpl
>>>>> or extend ODataJPAProcessor.
>>>>> 
>>>>> What do you think? Do you foresee any shortcomings with this approach?
>>>>> 
>>>>> Thanks
>>>>> Kind Regards
>>>>> Chandan
>>>>> 
>>>>> 
>>>>> 
>>>>> -----Original Message-----
>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>>>>> Sent: Wednesday, February 18, 2015 6:22 PM
>>>>> To: user@olingo.apache.org
>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
>>>>> 
>>>>> Hello Chandan,
>>>>> 
>>>>> I finally had some success in using JTA based transactions. However, this
>>>>> only worked when I cloned the current git and changed it in the
>>>>> JPAProcessorImpl directly; If I try to do this from within my project
>>>>> onto
>>>>> the intialization with
>>>>> 
>>>>> oDatJPAContext.setODataProcessor(new
>>>>> ODataJPAProcessorJTA(oDatJPAContext));
>>>>> 
>>>>> I then have to do a ODataJPAProcessorJTA which is 99% copy n paste from
>>>>> ODataJPAProcessor and then also need a 95% copy n paste
>>>>> JPAProcessorImplJTA
>>>>> from JPAProcessorImpl;
>>>>> 
>>>>> As if this isn't ugly enough, it gets real dirty when trying to use it as
>>>>> you
>>>>> simply cant force olingo to use it! Problem is that it comes from the
>>>>> JPAAccessFactoryImpl class static; is a static one and sits in
>>>>> ODataJPAFactoryImpl and finally this one gets called in public abstract
>>>>> class ODataJPAFactory
>>>>> 
>>>>> using
>>>>> 
>>>>> public static ODataJPAFactory createFactory() {
>>>>> 
>>>>>   if (factoryImpl != null) {
>>>>>     return factoryImpl;
>>>>>   } else {
>>>>>     try {
>>>>>       Class<?> clazz = Class.forName(ODataJPAFactory.IMPLEMENTATION);
>>>>> 
>>>>>       Object object = clazz.newInstance();
>>>>>       factoryImpl = (ODataJPAFactory) object;
>>>>> 
>>>>>     } catch (Exception e) {
>>>>>       throw new RuntimeException(e);
>>>>>     }
>>>>> 
>>>>>     return factoryImpl;
>>>>>   }
>>>>> }
>>>>> 
>>>>> where private static final String IMPLEMENTATION =
>>>>>     "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
>>>>> 
>>>>> 
>>>>> Simple said - overriding this logic in the olingo project is next to
>>>>> impossible as you would end up with nearly the whole project
>>>>> copy'n'pasted
>>>>> over; Simple changing the e.g.  resolver etc. wont works as there are
>>>>> many
>>>>> usages of the ODataJPAFactory createFactory() method;
>>>>> 
>>>>> 
>>>>> Implementing JTA to work in olingo on the other hand is quite easy. You
>>>>> can
>>>>> check on the fly if your JTA or not via e.g.:
>>>>> 
>>>>> public static boolean isResourceLocal(EntityManager em) {
>>>>>       try {
>>>>>           EntityTransaction tx = em.getTransaction();
>>>>>           return true;
>>>>>       } catch (IllegalStateException ex) {
>>>>>           return false;
>>>>>       }
>>>>>   }
>>>>> 
>>>>> and this one can then set into a boolean var classwide in the
>>>>> JPAProcessorImpl; so the setTransaction would become:
>>>>> 
>>>>> private boolean setTransaction() {
>>>>>     if(isLocalTX) {
>>>>>         final EntityTransaction transaction = em.getTransaction();
>>>>>         if (!transaction.isActive()) {
>>>>>             em.getTransaction().begin();
>>>>>             return true;
>>>>>         }
>>>>>     } else {
>>>>>         try {
>>>>>             transaction = (UserTransaction) new
>>>>>             InitialContext().lookup("java:comp/UserTransaction");
>>>>>             transaction.begin();
>>>>>         } catch (NamingException e) {
>>>>>             e.printStackTrace();
>>>>>         } catch (NotSupportedException e) {
>>>>>             e.printStackTrace();
>>>>>         } catch (SystemException e) {
>>>>>             e.printStackTrace();
>>>>>         }
>>>>>     }
>>>>> 
>>>>> 
>>>>>   return false;
>>>>> }
>>>>> 
>>>>> 
>>>>> and this would work on all JTA bases Servers. The rest of the transaction
>>>>> logic would simply look like e.g.:
>>>>> 
>>>>> if (isLocalTransaction) {
>>>>>       em.getTransaction().commit();
>>>>>     }
>>>>> if(transaction != null) {
>>>>>           transaction.commit();
>>>>>     }
>>>>> Or even
>>>>> if (isLocalTransaction) {
>>>>>       em.getTransaction().commit();
>>>>>     }
>>>>> else {
>>>>>           transaction.commit();
>>>>>     }
>>>>> in case we expect a 100% availbilty of transactional context;
>>>>> 
>>>>> 
>>>>> 
>>>>> Problem is now that this needs at least the dependency of
>>>>>       <dependency>
>>>>>           <groupId>javax</groupId>
>>>>>           <artifactId>javaee-api</artifactId>
>>>>>           <version>6.0</version>
>>>>>       </dependency>
>>>>> as else there is no UserTransaction class available; Would this
>>>>> dependency
>>>>> be
>>>>> ok for the JPA part of the olingo project?
>>>>> 
>>>>> What do you think?
>>>>> 
>>>>> Best,
>>>>> 
>>>>> Korbinian
>>>>> 
>>>>> 
>>>>> 
>>>>> ----- Ursprüngliche Mail -----
>>>>>> Von: "Chandan V.A" <ch...@sap.com>
>>>>>> An: user@olingo.apache.org
>>>>>> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>>>>>> 
>>>>>> Hello Korbinian,
>>>>>> Please check the JIRA item -
>>>>>> https://issues.apache.org/jira/browse/OLINGO-549
>>>>>> for updates on Olingo V4 JPA processor. Current status is there is no
>>>>>> support for V4 JPA processor and the development is in progress.
>>>>>> 
>>>>>> Thanks
>>>>>> Kind Regards
>>>>>> Chandan
>>>>>> 
>>>>>> -----Original Message-----
>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>>>>>> Sent: Wednesday, February 18, 2015 2:48 PM
>>>>>> To: user@olingo.apache.org
>>>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
>>>>>> 
>>>>>> Hello Chandan,
>>>>>> 
>>>>>> thank you for the info. Will try this. I've seen that Olingo also has a
>>>>>> OData
>>>>>> V4 in Beta2 - but I couldn't really find information about its
>>>>>> "readyness".
>>>>>> Would it work in a simple CRUD scenario with JPA? Reason is as it seems
>>>>>> as
>>>>>> my other system I talk to via OData is moving from V3 to V4 currently,
>>>>>> at
>>>>>> least the doc of its alredy speaks of OData V4 ready.
>>>>>> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
>>>>>> 
>>>>>> Best,
>>>>>> 
>>>>>> Korbinian
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> ----- Ursprüngliche Mail -----
>>>>>>> Von: "Chandan V.A" <ch...@sap.com>
>>>>>>> An: user@olingo.apache.org
>>>>>>> Gesendet: Dienstag, 17. Februar 2015 07:11:28
>>>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>>>>>>> 
>>>>>>> Hello Korbinian,
>>>>>>> You can extend the
>>>>>>> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and
>>>>>>> implement
>>>>>>> the processor methods as it is done in
>>>>>>> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.
>>>>>>> In
>>>>>>> your implementation for Create, Update and Delete you could begin the
>>>>>>> JTA
>>>>>>> transaction and close the transaction by either commit or rollback.
>>>>>>> 
>>>>>>> I have not tried the scenario with JTA based transactions but only
>>>>>>> Resource
>>>>>>> Local based transactions. Please check and tell if the above solution
>>>>>>> works
>>>>>>> for your case. Else raise a JIRA feature request to support JTA based
>>>>>>> transactions.
>>>>>>> 
>>>>>>> Regards
>>>>>>> Chandan
>>>>>>> 
>>>>>>> -----Original Message-----
>>>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>>>>>>> Sent: Monday, February 16, 2015 2:16 PM
>>>>>>> To: user@olingo.apache.org
>>>>>>> Subject: olingo JPA / JTA - wrong transactions used
>>>>>>> 
>>>>>>> Hi,
>>>>>>> 
>>>>>>> I'm using Olingo 2.0.2 and I can query all items so far. When I want to
>>>>>>> update content, I get error:
>>>>>>> 
>>>>>>> ...
>>>>>>> <message xml:lang="en">"OData - JPA Runtime: JPA update request is not
>>>>>>> correct"message>
>>>>>>>   <innererror>class java.lang.IllegalStateException :
>>>>>>> Exception Description: Cannot use an EntityTransaction while using
>>>>>>> JTA.innererror>
>>>>>>> ....
>>>>>>> 
>>>>>>> Digging deeper into the code, I ended up in file ODataJPAContextImpl
>>>>>>> 
>>>>>>> and there in the function
>>>>>>> 
>>>>>>> private  Object processUpdate(PutMergePatchUriInfo updateView,
>>>>>>>     final InputStream content, final Map<String, Object> properties,
>>>>>>>     final
>>>>>>>     String requestContentType)
>>>>>>>     throws ODataJPAModelException, ODataJPARuntimeException {
>>>>>>> ...
>>>>>>> boolean isLocalTransaction = setTransaction();
>>>>>>> 
>>>>>>> ...
>>>>>>> }
>>>>>>> 
>>>>>>> with
>>>>>>> 
>>>>>>> private boolean setTransaction() {
>>>>>>>   final EntityTransaction transaction = em.getTransaction();
>>>>>>>   if (!transaction.isActive()) {
>>>>>>>     em.getTransaction().begin();
>>>>>>>     return true;
>>>>>>>   }
>>>>>>> 
>>>>>>>   return false;
>>>>>>> }
>>>>>>> 
>>>>>>> 
>>>>>>> So far I understood this one is the function that collides with my JTA
>>>>>>> setup.
>>>>>>> I now wonder how I can suppress to initialize this method?
>>>>>>> 
>>>>>>> I've sending in the right EntityManagerFactory into Olingo, e.g.:
>>>>>>> 
>>>>>>> public class ConnectorODataJPAServiceFactory extends
>>>>>>> ODataJPAServiceFactory
>>>>>>> {
>>>>>>> 
>>>>>>>   private static final String PERSISTENCE_UNIT_NAME = "myPU";
>>>>>>> 
>>>>>>>   @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
>>>>>>>   EntityManagerFactory emf;
>>>>>>> 
>>>>>>> 
>>>>>>>   @Override
>>>>>>>   public ODataJPAContext initializeODataJPAContext() throws
>>>>>>>   ODataJPARuntimeException {
>>>>>>>       ODataJPAContext oDatJPAContext = this.getODataJPAContext();
>>>>>>> 
>>>>>>>       try {
>>>>>>>           CdiContainer.get().getNonContextualManager().postConstruct(this);
>>>>>>>           oDatJPAContext.setEntityManagerFactory(emf);
>>>>>>>           oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
>>>>>>>           oDatJPAContext.setPageSize(100);
>>>>>>>           setDetailErrors(true);
>>>>>>>           return oDatJPAContext;
>>>>>>>       } catch (Exception e) {
>>>>>>>           System.out.print(e);
>>>>>>>           throw new RuntimeException(e);
>>>>>>>       }
>>>>>>>   }
>>>>>>> 
>>>>>>> ...
>>>>>>> 
>>>>>>> So where is the catch here?
>>>>>>> 
>>>>>>> 
>>>>>>> Best,
>>>>>>> 
>>>>>>> Korbinian
>>>>>>> 
>>>>>> 
>>>>> 
>>>> 
>> 
>> 


Re: olingo JPA / JTA - wrong transactions used

Posted by Korbinian Bachl <ko...@whiskyworld.de>.
Hello Michael,

I've looked at the suggested OnJPAWriteContent-approach and this would work. Question is just if the callback should be implemented within 
ODataServiceFactory or just within ODataJPAServiceFactory; 

Either way we would need one (1) interface 

public interface ODataTransactionContext extends ODataCallback {

public void startTransaction();

public void commitTransaction();
 
public void rollbackTransaction();
 
public boolean transactionIsActive();

}

as well as 1 class that implements the current default;

it would be put into the Factory class like 

protected void setODataTransactionContext(final ODataTransactionContext oDataTransactionContext) {
    this.oDataTransactionContext = oDataTransactionContext;
}

and any access to transactions would then need to run via getTransactionContext() e.g.:

FactoryClassInstace.getTransactionContext().startTransaction(); 

(or if you want the more noisy version: FactoryClassInstace.getCallback(ODataTransactionContext.class).startTransaction(); - something I really dont like as this calling stack of if(callbackInterface.isAssignableFrom... ) is something I see waste of CPU cycles in regular and often called code areas, bad habbit IMHO)


Any other usages like JTA can then override the setODataTransactionContext(...) and supply a class that "does" exactly what needed.


If this is the way to go, then just let me know which "way" you want it and I can send you a pull request for it (on github);



Best,

Korbinian 

----- Ursprüngliche Mail -----
> Von: "Michael Bolz" <mi...@sap.com>
> An: user@olingo.apache.org
> Gesendet: Montag, 23. Februar 2015 11:03:40
> Betreff: Re: olingo JPA / JTA - wrong transactions used
> 
> Hi,
> 
> could a solution with the “Callback” approach (like the “OnJPAWriteContent”)
> work for this?
> So that the “ODataTransactionContext” is implemented as
> “ODataTransactionCallback”?
> 
> This way in the “ODataJPAServiceFactory” a method like: "protected void
> setTransactionCallback(final ODataTransactionCallback callback)” can be
> provided and
> if someone want to implement (inherit) his own “ODataServiceFactory” he can
> support the callback (interface) directly via the “getCallback(…)” method.
> 
> Kind regards,
> Michael
> 
> 
> > On 23 Feb 2015, at 10:17, Korbinian Bachl <ko...@whiskyworld.de>
> > wrote:
> > 
> > Hello Chandan,
> > 
> > I've looked into the ODataServiceFactory and its usages and I really dont
> > think this is good. Problems are
> > 
> > a, ODataServiceFactory is in lib module - so no external dependency should
> > be pulled into
> > b, just extending the class like I suggested wont work as we would have to
> > fix over 13 implementations of this Factory as well - not speaking about
> > any custom implementations so far;
> > c, I currently dont see the "need" to have JTA outside of JPA context -
> > since no one ever asked for it;
> > 
> > What I can think of is a CustomTransaction class object that gets its
> > "hold" within ODataServiceFactory and needs to be setup by the
> > implementation of the ODataServiceFactory only if it needs to use it.
> > Something like e.g.:
> > 
> > in ODataServiceFactory:
> > ----------
> > private ODataTransactionContext = null;
> > 
> > //stub - needs to be implemented if want to be used
> > public void setUpTransactionContext() {};
> > 
> > public getODataTransactionContext() {
> >       return ODataTransactionContext;
> > }
> > 
> > public setODataTransactionContext(ODataTransactionContext ctx) {...}
> > 
> > ---------
> > 
> > 
> > and ODataTransactionContext could be some kind of abstract class that has
> > the methods
> > 
> > public abstract class ODataTransactionContext {
> > 
> > public abstract void commitTransaction();
> > 
> > public abstract void startTransaction();
> > 
> > public abstract void rollbackTransaction();
> > 
> > public abstract boolean transactionIsActive();
> > 
> > }
> > 
> > -------
> > 
> > IMHO looks ugly; But using an interface for this would be even more
> > ugly....
> > 
> > 
> > Best,
> > 
> > Korbinian
> > 
> > 
> > ----- Ursprüngliche Mail -----
> >> Von: "Chandan V.A" <ch...@sap.com>
> >> An: user@olingo.apache.org
> >> Gesendet: Donnerstag, 19. Februar 2015 08:07:59
> >> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >> 
> >> Hello Korbinian,
> >> I could have kept the methods as part of ODataJPAServiceFactory but the
> >> problem is, extending the ODataJPAServiceFactory class for an application
> >> is
> >> optional. Applications can create their own factory classes by directly
> >> inheriting ODataServiceFactory. We need to support such applications as
> >> well. I have created the JIRA issue
> >> https://issues.apache.org/jira/browse/OLINGO-580 to implement support for
> >> JTA based transactions.
> >> 
> >> Thanks
> >> Kind Regards
> >> Chandan
> >> 
> >> -----Original Message-----
> >> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >> Sent: Wednesday, February 18, 2015 7:30 PM
> >> To: user@olingo.apache.org
> >> Subject: Re: olingo JPA / JTA - wrong transactions used
> >> 
> >> Hello Chandan,
> >> 
> >> sounds good. What I would do - based upon your idea - is to extend the
> >> ODataJPAServiceFactory with 4 methods (as this one has to be used in any
> >> case):
> >> 
> >> public static void startTransaction(EntityManager em, Object transaction)
> >> {
> >>    em.getTransaction().begin();
> >>    transaction = em.getTransaction();
> >> }
> >> 
> >> public static void commitTransaction(Object transaction) {
> >>    ((EntitiyTransaction) transaction).commit();
> >> }
> >> 
> >> public static void rollbackTransaction(Object transaction) {
> >>    ((EntitiyTransaction) transaction).rollback();
> >> }
> >> 
> >> public static boolean transactionIsActive(Object transaction) {
> >>   return ((EntitiyTransaction) transaction).isActive();
> >> }
> >> 
> >> These then would be called from wherever olingo JPA needs them.
> >> 
> >> That way any one needing JTA can override these methods while the rest
> >> won't
> >> even notice them...
> >> 
> >> 
> >> What do you think?
> >> 
> >> Best,
> >> 
> >> Korbinian
> >> 
> >> 
> >> 
> >> 
> >> 
> >> ----- Ursprüngliche Mail -----
> >>> Von: "Chandan V.A" <ch...@sap.com>
> >>> An: user@olingo.apache.org
> >>> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
> >>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>> 
> >>> Hello Korbinian,
> >>> I would at least keep the application managed transactions (like JTA)
> >>> outside
> >>> the context of JPA Processor for following reasons
> >>> 1) Wiring the JTA transactions into JPA processor could make the
> >>> processor
> >>> to
> >>> behave more like a framework than as a library (which is the current
> >>> state).
> >>> 2) JPA processor also need to take JNDI lookup as parameter from
> >>> applications
> >>> for looking up the datasource.
> >>> 3) Olingo JPA processor should take care of just data transformations and
> >>> need not worry about the scope of transactions
> >>> 4) Olingo JPA processor should not take dependency to J2EE api because I
> >>> am
> >>> not sure will this artifact work in OSGI environments
> >>> 
> >>> One proposal from my side would be to provide a callback mechanism for
> >>> transaction handling, where the library just calls a method in the
> >>> interface
> >>> to begin the transaction and end the transaction. If no one implements
> >>> the
> >>> callback mechanism the library would resort to "RESOURCE_LOCAL" based
> >>> transaction handling. With this approach applications will have a greater
> >>> control over transaction handling and also need not rewrite
> >>> JPAProcessorImpl
> >>> or extend ODataJPAProcessor.
> >>> 
> >>> What do you think? Do you foresee any shortcomings with this approach?
> >>> 
> >>> Thanks
> >>> Kind Regards
> >>> Chandan
> >>> 
> >>> 
> >>> 
> >>> -----Original Message-----
> >>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>> Sent: Wednesday, February 18, 2015 6:22 PM
> >>> To: user@olingo.apache.org
> >>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>> 
> >>> Hello Chandan,
> >>> 
> >>> I finally had some success in using JTA based transactions. However, this
> >>> only worked when I cloned the current git and changed it in the
> >>> JPAProcessorImpl directly; If I try to do this from within my project
> >>> onto
> >>> the intialization with
> >>> 
> >>> oDatJPAContext.setODataProcessor(new
> >>> ODataJPAProcessorJTA(oDatJPAContext));
> >>> 
> >>> I then have to do a ODataJPAProcessorJTA which is 99% copy n paste from
> >>> ODataJPAProcessor and then also need a 95% copy n paste
> >>> JPAProcessorImplJTA
> >>> from JPAProcessorImpl;
> >>> 
> >>> As if this isn't ugly enough, it gets real dirty when trying to use it as
> >>> you
> >>> simply cant force olingo to use it! Problem is that it comes from the
> >>> JPAAccessFactoryImpl class static; is a static one and sits in
> >>> ODataJPAFactoryImpl and finally this one gets called in public abstract
> >>> class ODataJPAFactory
> >>> 
> >>> using
> >>> 
> >>> public static ODataJPAFactory createFactory() {
> >>> 
> >>>    if (factoryImpl != null) {
> >>>      return factoryImpl;
> >>>    } else {
> >>>      try {
> >>>        Class<?> clazz = Class.forName(ODataJPAFactory.IMPLEMENTATION);
> >>> 
> >>>        Object object = clazz.newInstance();
> >>>        factoryImpl = (ODataJPAFactory) object;
> >>> 
> >>>      } catch (Exception e) {
> >>>        throw new RuntimeException(e);
> >>>      }
> >>> 
> >>>      return factoryImpl;
> >>>    }
> >>>  }
> >>> 
> >>> where private static final String IMPLEMENTATION =
> >>>      "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
> >>> 
> >>> 
> >>> Simple said - overriding this logic in the olingo project is next to
> >>> impossible as you would end up with nearly the whole project
> >>> copy'n'pasted
> >>> over; Simple changing the e.g.  resolver etc. wont works as there are
> >>> many
> >>> usages of the ODataJPAFactory createFactory() method;
> >>> 
> >>> 
> >>> Implementing JTA to work in olingo on the other hand is quite easy. You
> >>> can
> >>> check on the fly if your JTA or not via e.g.:
> >>> 
> >>> public static boolean isResourceLocal(EntityManager em) {
> >>>        try {
> >>>            EntityTransaction tx = em.getTransaction();
> >>>            return true;
> >>>        } catch (IllegalStateException ex) {
> >>>            return false;
> >>>        }
> >>>    }
> >>> 
> >>> and this one can then set into a boolean var classwide in the
> >>> JPAProcessorImpl; so the setTransaction would become:
> >>> 
> >>> private boolean setTransaction() {
> >>>      if(isLocalTX) {
> >>>          final EntityTransaction transaction = em.getTransaction();
> >>>          if (!transaction.isActive()) {
> >>>              em.getTransaction().begin();
> >>>              return true;
> >>>          }
> >>>      } else {
> >>>          try {
> >>>              transaction = (UserTransaction) new
> >>>              InitialContext().lookup("java:comp/UserTransaction");
> >>>              transaction.begin();
> >>>          } catch (NamingException e) {
> >>>              e.printStackTrace();
> >>>          } catch (NotSupportedException e) {
> >>>              e.printStackTrace();
> >>>          } catch (SystemException e) {
> >>>              e.printStackTrace();
> >>>          }
> >>>      }
> >>> 
> >>> 
> >>>    return false;
> >>>  }
> >>> 
> >>> 
> >>> and this would work on all JTA bases Servers. The rest of the transaction
> >>> logic would simply look like e.g.:
> >>> 
> >>> if (isLocalTransaction) {
> >>>        em.getTransaction().commit();
> >>>      }
> >>> if(transaction != null) {
> >>>            transaction.commit();
> >>>      }
> >>> Or even
> >>> if (isLocalTransaction) {
> >>>        em.getTransaction().commit();
> >>>      }
> >>> else {
> >>>            transaction.commit();
> >>>      }
> >>> in case we expect a 100% availbilty of transactional context;
> >>> 
> >>> 
> >>> 
> >>> Problem is now that this needs at least the dependency of
> >>>        <dependency>
> >>>            <groupId>javax</groupId>
> >>>            <artifactId>javaee-api</artifactId>
> >>>            <version>6.0</version>
> >>>        </dependency>
> >>> as else there is no UserTransaction class available; Would this
> >>> dependency
> >>> be
> >>> ok for the JPA part of the olingo project?
> >>> 
> >>> What do you think?
> >>> 
> >>> Best,
> >>> 
> >>> Korbinian
> >>> 
> >>> 
> >>> 
> >>> ----- Ursprüngliche Mail -----
> >>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>> An: user@olingo.apache.org
> >>>> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
> >>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>> 
> >>>> Hello Korbinian,
> >>>> Please check the JIRA item -
> >>>> https://issues.apache.org/jira/browse/OLINGO-549
> >>>> for updates on Olingo V4 JPA processor. Current status is there is no
> >>>> support for V4 JPA processor and the development is in progress.
> >>>> 
> >>>> Thanks
> >>>> Kind Regards
> >>>> Chandan
> >>>> 
> >>>> -----Original Message-----
> >>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>> Sent: Wednesday, February 18, 2015 2:48 PM
> >>>> To: user@olingo.apache.org
> >>>> Subject: Re: olingo JPA / JTA - wrong transactions used
> >>>> 
> >>>> Hello Chandan,
> >>>> 
> >>>> thank you for the info. Will try this. I've seen that Olingo also has a
> >>>> OData
> >>>> V4 in Beta2 - but I couldn't really find information about its
> >>>> "readyness".
> >>>> Would it work in a simple CRUD scenario with JPA? Reason is as it seems
> >>>> as
> >>>> my other system I talk to via OData is moving from V3 to V4 currently,
> >>>> at
> >>>> least the doc of its alredy speaks of OData V4 ready.
> >>>> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
> >>>> 
> >>>> Best,
> >>>> 
> >>>> Korbinian
> >>>> 
> >>>> 
> >>>> 
> >>>> ----- Ursprüngliche Mail -----
> >>>>> Von: "Chandan V.A" <ch...@sap.com>
> >>>>> An: user@olingo.apache.org
> >>>>> Gesendet: Dienstag, 17. Februar 2015 07:11:28
> >>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
> >>>>> 
> >>>>> Hello Korbinian,
> >>>>> You can extend the
> >>>>> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and
> >>>>> implement
> >>>>> the processor methods as it is done in
> >>>>> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.
> >>>>> In
> >>>>> your implementation for Create, Update and Delete you could begin the
> >>>>> JTA
> >>>>> transaction and close the transaction by either commit or rollback.
> >>>>> 
> >>>>> I have not tried the scenario with JTA based transactions but only
> >>>>> Resource
> >>>>> Local based transactions. Please check and tell if the above solution
> >>>>> works
> >>>>> for your case. Else raise a JIRA feature request to support JTA based
> >>>>> transactions.
> >>>>> 
> >>>>> Regards
> >>>>> Chandan
> >>>>> 
> >>>>> -----Original Message-----
> >>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> >>>>> Sent: Monday, February 16, 2015 2:16 PM
> >>>>> To: user@olingo.apache.org
> >>>>> Subject: olingo JPA / JTA - wrong transactions used
> >>>>> 
> >>>>> Hi,
> >>>>> 
> >>>>> I'm using Olingo 2.0.2 and I can query all items so far. When I want to
> >>>>> update content, I get error:
> >>>>> 
> >>>>> ...
> >>>>> <message xml:lang="en">"OData - JPA Runtime: JPA update request is not
> >>>>> correct"message>
> >>>>>    <innererror>class java.lang.IllegalStateException :
> >>>>> Exception Description: Cannot use an EntityTransaction while using
> >>>>> JTA.innererror>
> >>>>> ....
> >>>>> 
> >>>>> Digging deeper into the code, I ended up in file ODataJPAContextImpl
> >>>>> 
> >>>>> and there in the function
> >>>>> 
> >>>>> private  Object processUpdate(PutMergePatchUriInfo updateView,
> >>>>>      final InputStream content, final Map<String, Object> properties,
> >>>>>      final
> >>>>>      String requestContentType)
> >>>>>      throws ODataJPAModelException, ODataJPARuntimeException {
> >>>>> ...
> >>>>> boolean isLocalTransaction = setTransaction();
> >>>>> 
> >>>>> ...
> >>>>> }
> >>>>> 
> >>>>> with
> >>>>> 
> >>>>> private boolean setTransaction() {
> >>>>>    final EntityTransaction transaction = em.getTransaction();
> >>>>>    if (!transaction.isActive()) {
> >>>>>      em.getTransaction().begin();
> >>>>>      return true;
> >>>>>    }
> >>>>> 
> >>>>>    return false;
> >>>>>  }
> >>>>> 
> >>>>> 
> >>>>> So far I understood this one is the function that collides with my JTA
> >>>>> setup.
> >>>>> I now wonder how I can suppress to initialize this method?
> >>>>> 
> >>>>> I've sending in the right EntityManagerFactory into Olingo, e.g.:
> >>>>> 
> >>>>> public class ConnectorODataJPAServiceFactory extends
> >>>>> ODataJPAServiceFactory
> >>>>> {
> >>>>> 
> >>>>>    private static final String PERSISTENCE_UNIT_NAME = "myPU";
> >>>>> 
> >>>>>    @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
> >>>>>    EntityManagerFactory emf;
> >>>>> 
> >>>>> 
> >>>>>    @Override
> >>>>>    public ODataJPAContext initializeODataJPAContext() throws
> >>>>>    ODataJPARuntimeException {
> >>>>>        ODataJPAContext oDatJPAContext = this.getODataJPAContext();
> >>>>> 
> >>>>>        try {
> >>>>>            CdiContainer.get().getNonContextualManager().postConstruct(this);
> >>>>>            oDatJPAContext.setEntityManagerFactory(emf);
> >>>>>            oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
> >>>>>            oDatJPAContext.setPageSize(100);
> >>>>>            setDetailErrors(true);
> >>>>>            return oDatJPAContext;
> >>>>>        } catch (Exception e) {
> >>>>>            System.out.print(e);
> >>>>>            throw new RuntimeException(e);
> >>>>>        }
> >>>>>    }
> >>>>> 
> >>>>> ...
> >>>>> 
> >>>>> So where is the catch here?
> >>>>> 
> >>>>> 
> >>>>> Best,
> >>>>> 
> >>>>> Korbinian
> >>>>> 
> >>>> 
> >>> 
> >> 
> 
> 

RE: olingo JPA / JTA - wrong transactions used

Posted by "V.A, Chandan" <ch...@sap.com>.
Hello Michael,
I am also thinking of a callback interface. 

Regards
Chandan

-----Original Message-----
From: Bolz, Michael [mailto:michael.bolz@sap.com] 
Sent: Monday, February 23, 2015 3:34 PM
To: user@olingo.apache.org
Subject: Re: olingo JPA / JTA - wrong transactions used

* PGP - S/MIME Signed by an unverified key: 2/23/2015 at 3:33:39 PM

Hi,

could a solution with the “Callback” approach (like the “OnJPAWriteContent”) work for this?
So that the “ODataTransactionContext” is implemented as “ODataTransactionCallback”?

This way in the “ODataJPAServiceFactory” a method like: "protected void setTransactionCallback(final ODataTransactionCallback callback)” can be provided and
if someone want to implement (inherit) his own “ODataServiceFactory” he can support the callback (interface) directly via the “getCallback(…)” method.

Kind regards,
Michael


> On 23 Feb 2015, at 10:17, Korbinian Bachl <ko...@whiskyworld.de> wrote:
> 
> Hello Chandan,
> 
> I've looked into the ODataServiceFactory and its usages and I really dont think this is good. Problems are
> 
> a, ODataServiceFactory is in lib module - so no external dependency should be pulled into 
> b, just extending the class like I suggested wont work as we would have to fix over 13 implementations of this Factory as well - not speaking about any custom implementations so far;
> c, I currently dont see the "need" to have JTA outside of JPA context - since no one ever asked for it;
> 
> What I can think of is a CustomTransaction class object that gets its "hold" within ODataServiceFactory and needs to be setup by the implementation of the ODataServiceFactory only if it needs to use it. Something like e.g.:
> 
> in ODataServiceFactory:
> ----------
> private ODataTransactionContext = null;
> 
> //stub - needs to be implemented if want to be used
> public void setUpTransactionContext() {};
> 
> public getODataTransactionContext() {
>       return ODataTransactionContext;
> }
> 
> public setODataTransactionContext(ODataTransactionContext ctx) {...}
> 
> ---------
> 
> 
> and ODataTransactionContext could be some kind of abstract class that has the methods 
> 
> public abstract class ODataTransactionContext {
> 
> public abstract void commitTransaction();
> 
> public abstract void startTransaction();
> 
> public abstract void rollbackTransaction();
> 
> public abstract boolean transactionIsActive();
> 
> }
> 
> -------
> 
> IMHO looks ugly; But using an interface for this would be even more ugly....
> 
> 
> Best,
> 
> Korbinian
> 
> 
> ----- Ursprüngliche Mail -----
>> Von: "Chandan V.A" <ch...@sap.com>
>> An: user@olingo.apache.org
>> Gesendet: Donnerstag, 19. Februar 2015 08:07:59
>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>> 
>> Hello Korbinian,
>> I could have kept the methods as part of ODataJPAServiceFactory but the
>> problem is, extending the ODataJPAServiceFactory class for an application is
>> optional. Applications can create their own factory classes by directly
>> inheriting ODataServiceFactory. We need to support such applications as
>> well. I have created the JIRA issue
>> https://issues.apache.org/jira/browse/OLINGO-580 to implement support for
>> JTA based transactions.
>> 
>> Thanks
>> Kind Regards
>> Chandan
>> 
>> -----Original Message-----
>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>> Sent: Wednesday, February 18, 2015 7:30 PM
>> To: user@olingo.apache.org
>> Subject: Re: olingo JPA / JTA - wrong transactions used
>> 
>> Hello Chandan,
>> 
>> sounds good. What I would do - based upon your idea - is to extend the
>> ODataJPAServiceFactory with 4 methods (as this one has to be used in any
>> case):
>> 
>> public static void startTransaction(EntityManager em, Object transaction) {
>>    em.getTransaction().begin();
>>    transaction = em.getTransaction();
>> }
>> 
>> public static void commitTransaction(Object transaction) {
>>    ((EntitiyTransaction) transaction).commit();
>> }
>> 
>> public static void rollbackTransaction(Object transaction) {
>>    ((EntitiyTransaction) transaction).rollback();
>> }
>> 
>> public static boolean transactionIsActive(Object transaction) {
>>   return ((EntitiyTransaction) transaction).isActive();
>> }
>> 
>> These then would be called from wherever olingo JPA needs them.
>> 
>> That way any one needing JTA can override these methods while the rest won't
>> even notice them...
>> 
>> 
>> What do you think?
>> 
>> Best,
>> 
>> Korbinian
>> 
>> 
>> 
>> 
>> 
>> ----- Ursprüngliche Mail -----
>>> Von: "Chandan V.A" <ch...@sap.com>
>>> An: user@olingo.apache.org
>>> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>>> 
>>> Hello Korbinian,
>>> I would at least keep the application managed transactions (like JTA)
>>> outside
>>> the context of JPA Processor for following reasons
>>> 1) Wiring the JTA transactions into JPA processor could make the processor
>>> to
>>> behave more like a framework than as a library (which is the current
>>> state).
>>> 2) JPA processor also need to take JNDI lookup as parameter from
>>> applications
>>> for looking up the datasource.
>>> 3) Olingo JPA processor should take care of just data transformations and
>>> need not worry about the scope of transactions
>>> 4) Olingo JPA processor should not take dependency to J2EE api because I am
>>> not sure will this artifact work in OSGI environments
>>> 
>>> One proposal from my side would be to provide a callback mechanism for
>>> transaction handling, where the library just calls a method in the
>>> interface
>>> to begin the transaction and end the transaction. If no one implements the
>>> callback mechanism the library would resort to "RESOURCE_LOCAL" based
>>> transaction handling. With this approach applications will have a greater
>>> control over transaction handling and also need not rewrite
>>> JPAProcessorImpl
>>> or extend ODataJPAProcessor.
>>> 
>>> What do you think? Do you foresee any shortcomings with this approach?
>>> 
>>> Thanks
>>> Kind Regards
>>> Chandan
>>> 
>>> 
>>> 
>>> -----Original Message-----
>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>>> Sent: Wednesday, February 18, 2015 6:22 PM
>>> To: user@olingo.apache.org
>>> Subject: Re: olingo JPA / JTA - wrong transactions used
>>> 
>>> Hello Chandan,
>>> 
>>> I finally had some success in using JTA based transactions. However, this
>>> only worked when I cloned the current git and changed it in the
>>> JPAProcessorImpl directly; If I try to do this from within my project onto
>>> the intialization with
>>> 
>>> oDatJPAContext.setODataProcessor(new ODataJPAProcessorJTA(oDatJPAContext));
>>> 
>>> I then have to do a ODataJPAProcessorJTA which is 99% copy n paste from
>>> ODataJPAProcessor and then also need a 95% copy n paste JPAProcessorImplJTA
>>> from JPAProcessorImpl;
>>> 
>>> As if this isn't ugly enough, it gets real dirty when trying to use it as
>>> you
>>> simply cant force olingo to use it! Problem is that it comes from the
>>> JPAAccessFactoryImpl class static; is a static one and sits in
>>> ODataJPAFactoryImpl and finally this one gets called in public abstract
>>> class ODataJPAFactory
>>> 
>>> using
>>> 
>>> public static ODataJPAFactory createFactory() {
>>> 
>>>    if (factoryImpl != null) {
>>>      return factoryImpl;
>>>    } else {
>>>      try {
>>>        Class<?> clazz = Class.forName(ODataJPAFactory.IMPLEMENTATION);
>>> 
>>>        Object object = clazz.newInstance();
>>>        factoryImpl = (ODataJPAFactory) object;
>>> 
>>>      } catch (Exception e) {
>>>        throw new RuntimeException(e);
>>>      }
>>> 
>>>      return factoryImpl;
>>>    }
>>>  }
>>> 
>>> where private static final String IMPLEMENTATION =
>>>      "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
>>> 
>>> 
>>> Simple said - overriding this logic in the olingo project is next to
>>> impossible as you would end up with nearly the whole project copy'n'pasted
>>> over; Simple changing the e.g.  resolver etc. wont works as there are many
>>> usages of the ODataJPAFactory createFactory() method;
>>> 
>>> 
>>> Implementing JTA to work in olingo on the other hand is quite easy. You can
>>> check on the fly if your JTA or not via e.g.:
>>> 
>>> public static boolean isResourceLocal(EntityManager em) {
>>>        try {
>>>            EntityTransaction tx = em.getTransaction();
>>>            return true;
>>>        } catch (IllegalStateException ex) {
>>>            return false;
>>>        }
>>>    }
>>> 
>>> and this one can then set into a boolean var classwide in the
>>> JPAProcessorImpl; so the setTransaction would become:
>>> 
>>> private boolean setTransaction() {
>>>      if(isLocalTX) {
>>>          final EntityTransaction transaction = em.getTransaction();
>>>          if (!transaction.isActive()) {
>>>              em.getTransaction().begin();
>>>              return true;
>>>          }
>>>      } else {
>>>          try {
>>>              transaction = (UserTransaction) new
>>>              InitialContext().lookup("java:comp/UserTransaction");
>>>              transaction.begin();
>>>          } catch (NamingException e) {
>>>              e.printStackTrace();
>>>          } catch (NotSupportedException e) {
>>>              e.printStackTrace();
>>>          } catch (SystemException e) {
>>>              e.printStackTrace();
>>>          }
>>>      }
>>> 
>>> 
>>>    return false;
>>>  }
>>> 
>>> 
>>> and this would work on all JTA bases Servers. The rest of the transaction
>>> logic would simply look like e.g.:
>>> 
>>> if (isLocalTransaction) {
>>>        em.getTransaction().commit();
>>>      }
>>> if(transaction != null) {
>>>            transaction.commit();
>>>      }
>>> Or even
>>> if (isLocalTransaction) {
>>>        em.getTransaction().commit();
>>>      }
>>> else {
>>>            transaction.commit();
>>>      }
>>> in case we expect a 100% availbilty of transactional context;
>>> 
>>> 
>>> 
>>> Problem is now that this needs at least the dependency of
>>>        <dependency>
>>>            <groupId>javax</groupId>
>>>            <artifactId>javaee-api</artifactId>
>>>            <version>6.0</version>
>>>        </dependency>
>>> as else there is no UserTransaction class available; Would this dependency
>>> be
>>> ok for the JPA part of the olingo project?
>>> 
>>> What do you think?
>>> 
>>> Best,
>>> 
>>> Korbinian
>>> 
>>> 
>>> 
>>> ----- Ursprüngliche Mail -----
>>>> Von: "Chandan V.A" <ch...@sap.com>
>>>> An: user@olingo.apache.org
>>>> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>>>> 
>>>> Hello Korbinian,
>>>> Please check the JIRA item -
>>>> https://issues.apache.org/jira/browse/OLINGO-549
>>>> for updates on Olingo V4 JPA processor. Current status is there is no
>>>> support for V4 JPA processor and the development is in progress.
>>>> 
>>>> Thanks
>>>> Kind Regards
>>>> Chandan
>>>> 
>>>> -----Original Message-----
>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>>>> Sent: Wednesday, February 18, 2015 2:48 PM
>>>> To: user@olingo.apache.org
>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
>>>> 
>>>> Hello Chandan,
>>>> 
>>>> thank you for the info. Will try this. I've seen that Olingo also has a
>>>> OData
>>>> V4 in Beta2 - but I couldn't really find information about its
>>>> "readyness".
>>>> Would it work in a simple CRUD scenario with JPA? Reason is as it seems
>>>> as
>>>> my other system I talk to via OData is moving from V3 to V4 currently, at
>>>> least the doc of its alredy speaks of OData V4 ready.
>>>> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
>>>> 
>>>> Best,
>>>> 
>>>> Korbinian
>>>> 
>>>> 
>>>> 
>>>> ----- Ursprüngliche Mail -----
>>>>> Von: "Chandan V.A" <ch...@sap.com>
>>>>> An: user@olingo.apache.org
>>>>> Gesendet: Dienstag, 17. Februar 2015 07:11:28
>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>>>>> 
>>>>> Hello Korbinian,
>>>>> You can extend the
>>>>> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and
>>>>> implement
>>>>> the processor methods as it is done in
>>>>> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.
>>>>> In
>>>>> your implementation for Create, Update and Delete you could begin the
>>>>> JTA
>>>>> transaction and close the transaction by either commit or rollback.
>>>>> 
>>>>> I have not tried the scenario with JTA based transactions but only
>>>>> Resource
>>>>> Local based transactions. Please check and tell if the above solution
>>>>> works
>>>>> for your case. Else raise a JIRA feature request to support JTA based
>>>>> transactions.
>>>>> 
>>>>> Regards
>>>>> Chandan
>>>>> 
>>>>> -----Original Message-----
>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>>>>> Sent: Monday, February 16, 2015 2:16 PM
>>>>> To: user@olingo.apache.org
>>>>> Subject: olingo JPA / JTA - wrong transactions used
>>>>> 
>>>>> Hi,
>>>>> 
>>>>> I'm using Olingo 2.0.2 and I can query all items so far. When I want to
>>>>> update content, I get error:
>>>>> 
>>>>> ...
>>>>> <message xml:lang="en">"OData - JPA Runtime: JPA update request is not
>>>>> correct"message>
>>>>>    <innererror>class java.lang.IllegalStateException :
>>>>> Exception Description: Cannot use an EntityTransaction while using
>>>>> JTA.innererror>
>>>>> ....
>>>>> 
>>>>> Digging deeper into the code, I ended up in file ODataJPAContextImpl
>>>>> 
>>>>> and there in the function
>>>>> 
>>>>> private  Object processUpdate(PutMergePatchUriInfo updateView,
>>>>>      final InputStream content, final Map<String, Object> properties,
>>>>>      final
>>>>>      String requestContentType)
>>>>>      throws ODataJPAModelException, ODataJPARuntimeException {
>>>>> ...
>>>>> boolean isLocalTransaction = setTransaction();
>>>>> 
>>>>> ...
>>>>> }
>>>>> 
>>>>> with
>>>>> 
>>>>> private boolean setTransaction() {
>>>>>    final EntityTransaction transaction = em.getTransaction();
>>>>>    if (!transaction.isActive()) {
>>>>>      em.getTransaction().begin();
>>>>>      return true;
>>>>>    }
>>>>> 
>>>>>    return false;
>>>>>  }
>>>>> 
>>>>> 
>>>>> So far I understood this one is the function that collides with my JTA
>>>>> setup.
>>>>> I now wonder how I can suppress to initialize this method?
>>>>> 
>>>>> I've sending in the right EntityManagerFactory into Olingo, e.g.:
>>>>> 
>>>>> public class ConnectorODataJPAServiceFactory extends
>>>>> ODataJPAServiceFactory
>>>>> {
>>>>> 
>>>>>    private static final String PERSISTENCE_UNIT_NAME = "myPU";
>>>>> 
>>>>>    @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
>>>>>    EntityManagerFactory emf;
>>>>> 
>>>>> 
>>>>>    @Override
>>>>>    public ODataJPAContext initializeODataJPAContext() throws
>>>>>    ODataJPARuntimeException {
>>>>>        ODataJPAContext oDatJPAContext = this.getODataJPAContext();
>>>>> 
>>>>>        try {
>>>>>            CdiContainer.get().getNonContextualManager().postConstruct(this);
>>>>>            oDatJPAContext.setEntityManagerFactory(emf);
>>>>>            oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
>>>>>            oDatJPAContext.setPageSize(100);
>>>>>            setDetailErrors(true);
>>>>>            return oDatJPAContext;
>>>>>        } catch (Exception e) {
>>>>>            System.out.print(e);
>>>>>            throw new RuntimeException(e);
>>>>>        }
>>>>>    }
>>>>> 
>>>>> ...
>>>>> 
>>>>> So where is the catch here?
>>>>> 
>>>>> 
>>>>> Best,
>>>>> 
>>>>> Korbinian
>>>>> 
>>>> 
>>> 
>> 


* D046871 <mi...@sap.com>
* Issuer: SAP-AG - Unverified

Re: olingo JPA / JTA - wrong transactions used

Posted by "Bolz, Michael" <mi...@sap.com>.
Hi,

could a solution with the “Callback” approach (like the “OnJPAWriteContent”) work for this?
So that the “ODataTransactionContext” is implemented as “ODataTransactionCallback”?

This way in the “ODataJPAServiceFactory” a method like: "protected void setTransactionCallback(final ODataTransactionCallback callback)” can be provided and
if someone want to implement (inherit) his own “ODataServiceFactory” he can support the callback (interface) directly via the “getCallback(…)” method.

Kind regards,
Michael


> On 23 Feb 2015, at 10:17, Korbinian Bachl <ko...@whiskyworld.de> wrote:
> 
> Hello Chandan,
> 
> I've looked into the ODataServiceFactory and its usages and I really dont think this is good. Problems are
> 
> a, ODataServiceFactory is in lib module - so no external dependency should be pulled into 
> b, just extending the class like I suggested wont work as we would have to fix over 13 implementations of this Factory as well - not speaking about any custom implementations so far;
> c, I currently dont see the "need" to have JTA outside of JPA context - since no one ever asked for it;
> 
> What I can think of is a CustomTransaction class object that gets its "hold" within ODataServiceFactory and needs to be setup by the implementation of the ODataServiceFactory only if it needs to use it. Something like e.g.:
> 
> in ODataServiceFactory:
> ----------
> private ODataTransactionContext = null;
> 
> //stub - needs to be implemented if want to be used
> public void setUpTransactionContext() {};
> 
> public getODataTransactionContext() {
>       return ODataTransactionContext;
> }
> 
> public setODataTransactionContext(ODataTransactionContext ctx) {...}
> 
> ---------
> 
> 
> and ODataTransactionContext could be some kind of abstract class that has the methods 
> 
> public abstract class ODataTransactionContext {
> 
> public abstract void commitTransaction();
> 
> public abstract void startTransaction();
> 
> public abstract void rollbackTransaction();
> 
> public abstract boolean transactionIsActive();
> 
> }
> 
> -------
> 
> IMHO looks ugly; But using an interface for this would be even more ugly....
> 
> 
> Best,
> 
> Korbinian
> 
> 
> ----- Ursprüngliche Mail -----
>> Von: "Chandan V.A" <ch...@sap.com>
>> An: user@olingo.apache.org
>> Gesendet: Donnerstag, 19. Februar 2015 08:07:59
>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>> 
>> Hello Korbinian,
>> I could have kept the methods as part of ODataJPAServiceFactory but the
>> problem is, extending the ODataJPAServiceFactory class for an application is
>> optional. Applications can create their own factory classes by directly
>> inheriting ODataServiceFactory. We need to support such applications as
>> well. I have created the JIRA issue
>> https://issues.apache.org/jira/browse/OLINGO-580 to implement support for
>> JTA based transactions.
>> 
>> Thanks
>> Kind Regards
>> Chandan
>> 
>> -----Original Message-----
>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>> Sent: Wednesday, February 18, 2015 7:30 PM
>> To: user@olingo.apache.org
>> Subject: Re: olingo JPA / JTA - wrong transactions used
>> 
>> Hello Chandan,
>> 
>> sounds good. What I would do - based upon your idea - is to extend the
>> ODataJPAServiceFactory with 4 methods (as this one has to be used in any
>> case):
>> 
>> public static void startTransaction(EntityManager em, Object transaction) {
>>    em.getTransaction().begin();
>>    transaction = em.getTransaction();
>> }
>> 
>> public static void commitTransaction(Object transaction) {
>>    ((EntitiyTransaction) transaction).commit();
>> }
>> 
>> public static void rollbackTransaction(Object transaction) {
>>    ((EntitiyTransaction) transaction).rollback();
>> }
>> 
>> public static boolean transactionIsActive(Object transaction) {
>>   return ((EntitiyTransaction) transaction).isActive();
>> }
>> 
>> These then would be called from wherever olingo JPA needs them.
>> 
>> That way any one needing JTA can override these methods while the rest won't
>> even notice them...
>> 
>> 
>> What do you think?
>> 
>> Best,
>> 
>> Korbinian
>> 
>> 
>> 
>> 
>> 
>> ----- Ursprüngliche Mail -----
>>> Von: "Chandan V.A" <ch...@sap.com>
>>> An: user@olingo.apache.org
>>> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>>> 
>>> Hello Korbinian,
>>> I would at least keep the application managed transactions (like JTA)
>>> outside
>>> the context of JPA Processor for following reasons
>>> 1) Wiring the JTA transactions into JPA processor could make the processor
>>> to
>>> behave more like a framework than as a library (which is the current
>>> state).
>>> 2) JPA processor also need to take JNDI lookup as parameter from
>>> applications
>>> for looking up the datasource.
>>> 3) Olingo JPA processor should take care of just data transformations and
>>> need not worry about the scope of transactions
>>> 4) Olingo JPA processor should not take dependency to J2EE api because I am
>>> not sure will this artifact work in OSGI environments
>>> 
>>> One proposal from my side would be to provide a callback mechanism for
>>> transaction handling, where the library just calls a method in the
>>> interface
>>> to begin the transaction and end the transaction. If no one implements the
>>> callback mechanism the library would resort to "RESOURCE_LOCAL" based
>>> transaction handling. With this approach applications will have a greater
>>> control over transaction handling and also need not rewrite
>>> JPAProcessorImpl
>>> or extend ODataJPAProcessor.
>>> 
>>> What do you think? Do you foresee any shortcomings with this approach?
>>> 
>>> Thanks
>>> Kind Regards
>>> Chandan
>>> 
>>> 
>>> 
>>> -----Original Message-----
>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>>> Sent: Wednesday, February 18, 2015 6:22 PM
>>> To: user@olingo.apache.org
>>> Subject: Re: olingo JPA / JTA - wrong transactions used
>>> 
>>> Hello Chandan,
>>> 
>>> I finally had some success in using JTA based transactions. However, this
>>> only worked when I cloned the current git and changed it in the
>>> JPAProcessorImpl directly; If I try to do this from within my project onto
>>> the intialization with
>>> 
>>> oDatJPAContext.setODataProcessor(new ODataJPAProcessorJTA(oDatJPAContext));
>>> 
>>> I then have to do a ODataJPAProcessorJTA which is 99% copy n paste from
>>> ODataJPAProcessor and then also need a 95% copy n paste JPAProcessorImplJTA
>>> from JPAProcessorImpl;
>>> 
>>> As if this isn't ugly enough, it gets real dirty when trying to use it as
>>> you
>>> simply cant force olingo to use it! Problem is that it comes from the
>>> JPAAccessFactoryImpl class static; is a static one and sits in
>>> ODataJPAFactoryImpl and finally this one gets called in public abstract
>>> class ODataJPAFactory
>>> 
>>> using
>>> 
>>> public static ODataJPAFactory createFactory() {
>>> 
>>>    if (factoryImpl != null) {
>>>      return factoryImpl;
>>>    } else {
>>>      try {
>>>        Class<?> clazz = Class.forName(ODataJPAFactory.IMPLEMENTATION);
>>> 
>>>        Object object = clazz.newInstance();
>>>        factoryImpl = (ODataJPAFactory) object;
>>> 
>>>      } catch (Exception e) {
>>>        throw new RuntimeException(e);
>>>      }
>>> 
>>>      return factoryImpl;
>>>    }
>>>  }
>>> 
>>> where private static final String IMPLEMENTATION =
>>>      "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
>>> 
>>> 
>>> Simple said - overriding this logic in the olingo project is next to
>>> impossible as you would end up with nearly the whole project copy'n'pasted
>>> over; Simple changing the e.g.  resolver etc. wont works as there are many
>>> usages of the ODataJPAFactory createFactory() method;
>>> 
>>> 
>>> Implementing JTA to work in olingo on the other hand is quite easy. You can
>>> check on the fly if your JTA or not via e.g.:
>>> 
>>> public static boolean isResourceLocal(EntityManager em) {
>>>        try {
>>>            EntityTransaction tx = em.getTransaction();
>>>            return true;
>>>        } catch (IllegalStateException ex) {
>>>            return false;
>>>        }
>>>    }
>>> 
>>> and this one can then set into a boolean var classwide in the
>>> JPAProcessorImpl; so the setTransaction would become:
>>> 
>>> private boolean setTransaction() {
>>>      if(isLocalTX) {
>>>          final EntityTransaction transaction = em.getTransaction();
>>>          if (!transaction.isActive()) {
>>>              em.getTransaction().begin();
>>>              return true;
>>>          }
>>>      } else {
>>>          try {
>>>              transaction = (UserTransaction) new
>>>              InitialContext().lookup("java:comp/UserTransaction");
>>>              transaction.begin();
>>>          } catch (NamingException e) {
>>>              e.printStackTrace();
>>>          } catch (NotSupportedException e) {
>>>              e.printStackTrace();
>>>          } catch (SystemException e) {
>>>              e.printStackTrace();
>>>          }
>>>      }
>>> 
>>> 
>>>    return false;
>>>  }
>>> 
>>> 
>>> and this would work on all JTA bases Servers. The rest of the transaction
>>> logic would simply look like e.g.:
>>> 
>>> if (isLocalTransaction) {
>>>        em.getTransaction().commit();
>>>      }
>>> if(transaction != null) {
>>>            transaction.commit();
>>>      }
>>> Or even
>>> if (isLocalTransaction) {
>>>        em.getTransaction().commit();
>>>      }
>>> else {
>>>            transaction.commit();
>>>      }
>>> in case we expect a 100% availbilty of transactional context;
>>> 
>>> 
>>> 
>>> Problem is now that this needs at least the dependency of
>>>        <dependency>
>>>            <groupId>javax</groupId>
>>>            <artifactId>javaee-api</artifactId>
>>>            <version>6.0</version>
>>>        </dependency>
>>> as else there is no UserTransaction class available; Would this dependency
>>> be
>>> ok for the JPA part of the olingo project?
>>> 
>>> What do you think?
>>> 
>>> Best,
>>> 
>>> Korbinian
>>> 
>>> 
>>> 
>>> ----- Ursprüngliche Mail -----
>>>> Von: "Chandan V.A" <ch...@sap.com>
>>>> An: user@olingo.apache.org
>>>> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>>>> 
>>>> Hello Korbinian,
>>>> Please check the JIRA item -
>>>> https://issues.apache.org/jira/browse/OLINGO-549
>>>> for updates on Olingo V4 JPA processor. Current status is there is no
>>>> support for V4 JPA processor and the development is in progress.
>>>> 
>>>> Thanks
>>>> Kind Regards
>>>> Chandan
>>>> 
>>>> -----Original Message-----
>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>>>> Sent: Wednesday, February 18, 2015 2:48 PM
>>>> To: user@olingo.apache.org
>>>> Subject: Re: olingo JPA / JTA - wrong transactions used
>>>> 
>>>> Hello Chandan,
>>>> 
>>>> thank you for the info. Will try this. I've seen that Olingo also has a
>>>> OData
>>>> V4 in Beta2 - but I couldn't really find information about its
>>>> "readyness".
>>>> Would it work in a simple CRUD scenario with JPA? Reason is as it seems
>>>> as
>>>> my other system I talk to via OData is moving from V3 to V4 currently, at
>>>> least the doc of its alredy speaks of OData V4 ready.
>>>> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
>>>> 
>>>> Best,
>>>> 
>>>> Korbinian
>>>> 
>>>> 
>>>> 
>>>> ----- Ursprüngliche Mail -----
>>>>> Von: "Chandan V.A" <ch...@sap.com>
>>>>> An: user@olingo.apache.org
>>>>> Gesendet: Dienstag, 17. Februar 2015 07:11:28
>>>>> Betreff: RE: olingo JPA / JTA - wrong transactions used
>>>>> 
>>>>> Hello Korbinian,
>>>>> You can extend the
>>>>> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and
>>>>> implement
>>>>> the processor methods as it is done in
>>>>> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.
>>>>> In
>>>>> your implementation for Create, Update and Delete you could begin the
>>>>> JTA
>>>>> transaction and close the transaction by either commit or rollback.
>>>>> 
>>>>> I have not tried the scenario with JTA based transactions but only
>>>>> Resource
>>>>> Local based transactions. Please check and tell if the above solution
>>>>> works
>>>>> for your case. Else raise a JIRA feature request to support JTA based
>>>>> transactions.
>>>>> 
>>>>> Regards
>>>>> Chandan
>>>>> 
>>>>> -----Original Message-----
>>>>> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
>>>>> Sent: Monday, February 16, 2015 2:16 PM
>>>>> To: user@olingo.apache.org
>>>>> Subject: olingo JPA / JTA - wrong transactions used
>>>>> 
>>>>> Hi,
>>>>> 
>>>>> I'm using Olingo 2.0.2 and I can query all items so far. When I want to
>>>>> update content, I get error:
>>>>> 
>>>>> ...
>>>>> <message xml:lang="en">"OData - JPA Runtime: JPA update request is not
>>>>> correct"message>
>>>>>    <innererror>class java.lang.IllegalStateException :
>>>>> Exception Description: Cannot use an EntityTransaction while using
>>>>> JTA.innererror>
>>>>> ....
>>>>> 
>>>>> Digging deeper into the code, I ended up in file ODataJPAContextImpl
>>>>> 
>>>>> and there in the function
>>>>> 
>>>>> private  Object processUpdate(PutMergePatchUriInfo updateView,
>>>>>      final InputStream content, final Map<String, Object> properties,
>>>>>      final
>>>>>      String requestContentType)
>>>>>      throws ODataJPAModelException, ODataJPARuntimeException {
>>>>> ...
>>>>> boolean isLocalTransaction = setTransaction();
>>>>> 
>>>>> ...
>>>>> }
>>>>> 
>>>>> with
>>>>> 
>>>>> private boolean setTransaction() {
>>>>>    final EntityTransaction transaction = em.getTransaction();
>>>>>    if (!transaction.isActive()) {
>>>>>      em.getTransaction().begin();
>>>>>      return true;
>>>>>    }
>>>>> 
>>>>>    return false;
>>>>>  }
>>>>> 
>>>>> 
>>>>> So far I understood this one is the function that collides with my JTA
>>>>> setup.
>>>>> I now wonder how I can suppress to initialize this method?
>>>>> 
>>>>> I've sending in the right EntityManagerFactory into Olingo, e.g.:
>>>>> 
>>>>> public class ConnectorODataJPAServiceFactory extends
>>>>> ODataJPAServiceFactory
>>>>> {
>>>>> 
>>>>>    private static final String PERSISTENCE_UNIT_NAME = "myPU";
>>>>> 
>>>>>    @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
>>>>>    EntityManagerFactory emf;
>>>>> 
>>>>> 
>>>>>    @Override
>>>>>    public ODataJPAContext initializeODataJPAContext() throws
>>>>>    ODataJPARuntimeException {
>>>>>        ODataJPAContext oDatJPAContext = this.getODataJPAContext();
>>>>> 
>>>>>        try {
>>>>>            CdiContainer.get().getNonContextualManager().postConstruct(this);
>>>>>            oDatJPAContext.setEntityManagerFactory(emf);
>>>>>            oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
>>>>>            oDatJPAContext.setPageSize(100);
>>>>>            setDetailErrors(true);
>>>>>            return oDatJPAContext;
>>>>>        } catch (Exception e) {
>>>>>            System.out.print(e);
>>>>>            throw new RuntimeException(e);
>>>>>        }
>>>>>    }
>>>>> 
>>>>> ...
>>>>> 
>>>>> So where is the catch here?
>>>>> 
>>>>> 
>>>>> Best,
>>>>> 
>>>>> Korbinian
>>>>> 
>>>> 
>>> 
>> 


Re: olingo JPA / JTA - wrong transactions used

Posted by Korbinian Bachl <ko...@whiskyworld.de>.
Hello Chandan,

I've looked into the ODataServiceFactory and its usages and I really dont think this is good. Problems are

a, ODataServiceFactory is in lib module - so no external dependency should be pulled into 
b, just extending the class like I suggested wont work as we would have to fix over 13 implementations of this Factory as well - not speaking about any custom implementations so far;
c, I currently dont see the "need" to have JTA outside of JPA context - since no one ever asked for it;

What I can think of is a CustomTransaction class object that gets its "hold" within ODataServiceFactory and needs to be setup by the implementation of the ODataServiceFactory only if it needs to use it. Something like e.g.:

in ODataServiceFactory:
----------
private ODataTransactionContext = null;

//stub - needs to be implemented if want to be used
public void setUpTransactionContext() {};

public getODataTransactionContext() {
       return ODataTransactionContext;
}

public setODataTransactionContext(ODataTransactionContext ctx) {...}

---------


and ODataTransactionContext could be some kind of abstract class that has the methods 

public abstract class ODataTransactionContext {

public abstract void commitTransaction();

public abstract void startTransaction();

public abstract void rollbackTransaction();

public abstract boolean transactionIsActive();

}

-------

IMHO looks ugly; But using an interface for this would be even more ugly....


Best,

Korbinian


----- Ursprüngliche Mail -----
> Von: "Chandan V.A" <ch...@sap.com>
> An: user@olingo.apache.org
> Gesendet: Donnerstag, 19. Februar 2015 08:07:59
> Betreff: RE: olingo JPA / JTA - wrong transactions used
> 
> Hello Korbinian,
> I could have kept the methods as part of ODataJPAServiceFactory but the
> problem is, extending the ODataJPAServiceFactory class for an application is
> optional. Applications can create their own factory classes by directly
> inheriting ODataServiceFactory. We need to support such applications as
> well. I have created the JIRA issue
> https://issues.apache.org/jira/browse/OLINGO-580 to implement support for
> JTA based transactions.
> 
> Thanks
> Kind Regards
> Chandan
> 
> -----Original Message-----
> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> Sent: Wednesday, February 18, 2015 7:30 PM
> To: user@olingo.apache.org
> Subject: Re: olingo JPA / JTA - wrong transactions used
> 
> Hello Chandan,
> 
> sounds good. What I would do - based upon your idea - is to extend the
> ODataJPAServiceFactory with 4 methods (as this one has to be used in any
> case):
> 
> public static void startTransaction(EntityManager em, Object transaction) {
>     em.getTransaction().begin();
>     transaction = em.getTransaction();
> }
> 
> public static void commitTransaction(Object transaction) {
>     ((EntitiyTransaction) transaction).commit();
> }
> 
> public static void rollbackTransaction(Object transaction) {
>     ((EntitiyTransaction) transaction).rollback();
> }
> 
> public static boolean transactionIsActive(Object transaction) {
>    return ((EntitiyTransaction) transaction).isActive();
> }
> 
> These then would be called from wherever olingo JPA needs them.
> 
> That way any one needing JTA can override these methods while the rest won't
> even notice them...
> 
> 
> What do you think?
> 
> Best,
> 
> Korbinian
> 
> 
> 
> 
> 
> ----- Ursprüngliche Mail -----
> > Von: "Chandan V.A" <ch...@sap.com>
> > An: user@olingo.apache.org
> > Gesendet: Mittwoch, 18. Februar 2015 14:26:45
> > Betreff: RE: olingo JPA / JTA - wrong transactions used
> > 
> > Hello Korbinian,
> > I would at least keep the application managed transactions (like JTA)
> > outside
> > the context of JPA Processor for following reasons
> > 1) Wiring the JTA transactions into JPA processor could make the processor
> > to
> > behave more like a framework than as a library (which is the current
> > state).
> > 2) JPA processor also need to take JNDI lookup as parameter from
> > applications
> > for looking up the datasource.
> > 3) Olingo JPA processor should take care of just data transformations and
> > need not worry about the scope of transactions
> > 4) Olingo JPA processor should not take dependency to J2EE api because I am
> > not sure will this artifact work in OSGI environments
> > 
> > One proposal from my side would be to provide a callback mechanism for
> > transaction handling, where the library just calls a method in the
> > interface
> > to begin the transaction and end the transaction. If no one implements the
> > callback mechanism the library would resort to "RESOURCE_LOCAL" based
> > transaction handling. With this approach applications will have a greater
> > control over transaction handling and also need not rewrite
> > JPAProcessorImpl
> > or extend ODataJPAProcessor.
> > 
> > What do you think? Do you foresee any shortcomings with this approach?
> > 
> > Thanks
> > Kind Regards
> > Chandan
> > 
> > 
> > 
> > -----Original Message-----
> > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > Sent: Wednesday, February 18, 2015 6:22 PM
> > To: user@olingo.apache.org
> > Subject: Re: olingo JPA / JTA - wrong transactions used
> > 
> > Hello Chandan,
> > 
> > I finally had some success in using JTA based transactions. However, this
> > only worked when I cloned the current git and changed it in the
> > JPAProcessorImpl directly; If I try to do this from within my project onto
> > the intialization with
> > 
> > oDatJPAContext.setODataProcessor(new ODataJPAProcessorJTA(oDatJPAContext));
> > 
> > I then have to do a ODataJPAProcessorJTA which is 99% copy n paste from
> > ODataJPAProcessor and then also need a 95% copy n paste JPAProcessorImplJTA
> > from JPAProcessorImpl;
> > 
> > As if this isn't ugly enough, it gets real dirty when trying to use it as
> > you
> > simply cant force olingo to use it! Problem is that it comes from the
> > JPAAccessFactoryImpl class static; is a static one and sits in
> > ODataJPAFactoryImpl and finally this one gets called in public abstract
> > class ODataJPAFactory
> > 
> > using
> > 
> >  public static ODataJPAFactory createFactory() {
> > 
> >     if (factoryImpl != null) {
> >       return factoryImpl;
> >     } else {
> >       try {
> >         Class<?> clazz = Class.forName(ODataJPAFactory.IMPLEMENTATION);
> > 
> >         Object object = clazz.newInstance();
> >         factoryImpl = (ODataJPAFactory) object;
> > 
> >       } catch (Exception e) {
> >         throw new RuntimeException(e);
> >       }
> > 
> >       return factoryImpl;
> >     }
> >   }
> > 
> > where private static final String IMPLEMENTATION =
> >       "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
> > 
> > 
> > Simple said - overriding this logic in the olingo project is next to
> > impossible as you would end up with nearly the whole project copy'n'pasted
> > over; Simple changing the e.g.  resolver etc. wont works as there are many
> > usages of the ODataJPAFactory createFactory() method;
> > 
> > 
> > Implementing JTA to work in olingo on the other hand is quite easy. You can
> > check on the fly if your JTA or not via e.g.:
> > 
> >  public static boolean isResourceLocal(EntityManager em) {
> >         try {
> >             EntityTransaction tx = em.getTransaction();
> >             return true;
> >         } catch (IllegalStateException ex) {
> >             return false;
> >         }
> >     }
> > 
> > and this one can then set into a boolean var classwide in the
> > JPAProcessorImpl; so the setTransaction would become:
> > 
> > private boolean setTransaction() {
> >       if(isLocalTX) {
> >           final EntityTransaction transaction = em.getTransaction();
> >           if (!transaction.isActive()) {
> >               em.getTransaction().begin();
> >               return true;
> >           }
> >       } else {
> >           try {
> >               transaction = (UserTransaction) new
> >               InitialContext().lookup("java:comp/UserTransaction");
> >               transaction.begin();
> >           } catch (NamingException e) {
> >               e.printStackTrace();
> >           } catch (NotSupportedException e) {
> >               e.printStackTrace();
> >           } catch (SystemException e) {
> >               e.printStackTrace();
> >           }
> >       }
> > 
> > 
> >     return false;
> >   }
> > 
> > 
> > and this would work on all JTA bases Servers. The rest of the transaction
> > logic would simply look like e.g.:
> > 
> > if (isLocalTransaction) {
> >         em.getTransaction().commit();
> >       }
> > if(transaction != null) {
> >             transaction.commit();
> >       }
> > Or even
> > if (isLocalTransaction) {
> >         em.getTransaction().commit();
> >       }
> > else {
> >             transaction.commit();
> >       }
> > in case we expect a 100% availbilty of transactional context;
> > 
> > 
> > 
> > Problem is now that this needs at least the dependency of
> >         <dependency>
> >             <groupId>javax</groupId>
> >             <artifactId>javaee-api</artifactId>
> >             <version>6.0</version>
> >         </dependency>
> > as else there is no UserTransaction class available; Would this dependency
> > be
> > ok for the JPA part of the olingo project?
> > 
> > What do you think?
> > 
> > Best,
> > 
> > Korbinian
> > 
> > 
> > 
> > ----- Ursprüngliche Mail -----
> > > Von: "Chandan V.A" <ch...@sap.com>
> > > An: user@olingo.apache.org
> > > Gesendet: Mittwoch, 18. Februar 2015 10:26:11
> > > Betreff: RE: olingo JPA / JTA - wrong transactions used
> > > 
> > > Hello Korbinian,
> > > Please check the JIRA item -
> > > https://issues.apache.org/jira/browse/OLINGO-549
> > > for updates on Olingo V4 JPA processor. Current status is there is no
> > > support for V4 JPA processor and the development is in progress.
> > > 
> > > Thanks
> > > Kind Regards
> > > Chandan
> > > 
> > > -----Original Message-----
> > > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > Sent: Wednesday, February 18, 2015 2:48 PM
> > > To: user@olingo.apache.org
> > > Subject: Re: olingo JPA / JTA - wrong transactions used
> > > 
> > > Hello Chandan,
> > > 
> > > thank you for the info. Will try this. I've seen that Olingo also has a
> > > OData
> > > V4 in Beta2 - but I couldn't really find information about its
> > > "readyness".
> > > Would it work in a simple CRUD scenario with JPA? Reason is as it seems
> > > as
> > > my other system I talk to via OData is moving from V3 to V4 currently, at
> > > least the doc of its alredy speaks of OData V4 ready.
> > > (Beside: how to setup JPA? - the onlingo 2.x way wont work)
> > > 
> > > Best,
> > > 
> > > Korbinian
> > > 
> > > 
> > > 
> > > ----- Ursprüngliche Mail -----
> > > > Von: "Chandan V.A" <ch...@sap.com>
> > > > An: user@olingo.apache.org
> > > > Gesendet: Dienstag, 17. Februar 2015 07:11:28
> > > > Betreff: RE: olingo JPA / JTA - wrong transactions used
> > > > 
> > > > Hello Korbinian,
> > > > You can extend the
> > > > org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and
> > > > implement
> > > > the processor methods as it is done in
> > > > org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.
> > > > In
> > > > your implementation for Create, Update and Delete you could begin the
> > > > JTA
> > > > transaction and close the transaction by either commit or rollback.
> > > > 
> > > > I have not tried the scenario with JTA based transactions but only
> > > > Resource
> > > > Local based transactions. Please check and tell if the above solution
> > > > works
> > > > for your case. Else raise a JIRA feature request to support JTA based
> > > > transactions.
> > > > 
> > > > Regards
> > > > Chandan
> > > > 
> > > > -----Original Message-----
> > > > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > > Sent: Monday, February 16, 2015 2:16 PM
> > > > To: user@olingo.apache.org
> > > > Subject: olingo JPA / JTA - wrong transactions used
> > > > 
> > > > Hi,
> > > > 
> > > > I'm using Olingo 2.0.2 and I can query all items so far. When I want to
> > > > update content, I get error:
> > > > 
> > > > ...
> > > > <message xml:lang="en">"OData - JPA Runtime: JPA update request is not
> > > > correct"message>
> > > >     <innererror>class java.lang.IllegalStateException :
> > > > Exception Description: Cannot use an EntityTransaction while using
> > > > JTA.innererror>
> > > > ....
> > > > 
> > > > Digging deeper into the code, I ended up in file ODataJPAContextImpl
> > > > 
> > > > and there in the function
> > > > 
> > > > private  Object processUpdate(PutMergePatchUriInfo updateView,
> > > >       final InputStream content, final Map<String, Object> properties,
> > > >       final
> > > >       String requestContentType)
> > > >       throws ODataJPAModelException, ODataJPARuntimeException {
> > > > ...
> > > > boolean isLocalTransaction = setTransaction();
> > > > 
> > > > ...
> > > > }
> > > > 
> > > > with
> > > > 
> > > > private boolean setTransaction() {
> > > >     final EntityTransaction transaction = em.getTransaction();
> > > >     if (!transaction.isActive()) {
> > > >       em.getTransaction().begin();
> > > >       return true;
> > > >     }
> > > > 
> > > >     return false;
> > > >   }
> > > > 
> > > > 
> > > > So far I understood this one is the function that collides with my JTA
> > > > setup.
> > > > I now wonder how I can suppress to initialize this method?
> > > > 
> > > > I've sending in the right EntityManagerFactory into Olingo, e.g.:
> > > > 
> > > > public class ConnectorODataJPAServiceFactory extends
> > > > ODataJPAServiceFactory
> > > > {
> > > > 
> > > >     private static final String PERSISTENCE_UNIT_NAME = "myPU";
> > > > 
> > > >     @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
> > > >     EntityManagerFactory emf;
> > > > 
> > > > 
> > > >     @Override
> > > >     public ODataJPAContext initializeODataJPAContext() throws
> > > >     ODataJPARuntimeException {
> > > >         ODataJPAContext oDatJPAContext = this.getODataJPAContext();
> > > > 
> > > >         try {
> > > >             CdiContainer.get().getNonContextualManager().postConstruct(this);
> > > >             oDatJPAContext.setEntityManagerFactory(emf);
> > > >             oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
> > > >             oDatJPAContext.setPageSize(100);
> > > >             setDetailErrors(true);
> > > >             return oDatJPAContext;
> > > >         } catch (Exception e) {
> > > >             System.out.print(e);
> > > >             throw new RuntimeException(e);
> > > >         }
> > > >     }
> > > > 
> > > > ...
> > > > 
> > > > So where is the catch here?
> > > > 
> > > > 
> > > > Best,
> > > > 
> > > > Korbinian
> > > > 
> > > 
> > 
> 

RE: olingo JPA / JTA - wrong transactions used

Posted by "V.A, Chandan" <ch...@sap.com>.
Hello Korbinian,
I could have kept the methods as part of ODataJPAServiceFactory but the problem is, extending the ODataJPAServiceFactory class for an application is optional. Applications can create their own factory classes by directly inheriting ODataServiceFactory. We need to support such applications as well. I have created the JIRA issue https://issues.apache.org/jira/browse/OLINGO-580 to implement support for JTA based transactions.

Thanks
Kind Regards
Chandan

-----Original Message-----
From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de] 
Sent: Wednesday, February 18, 2015 7:30 PM
To: user@olingo.apache.org
Subject: Re: olingo JPA / JTA - wrong transactions used

Hello Chandan,

sounds good. What I would do - based upon your idea - is to extend the ODataJPAServiceFactory with 4 methods (as this one has to be used in any case):

public static void startTransaction(EntityManager em, Object transaction) {
    em.getTransaction().begin();
    transaction = em.getTransaction();
}

public static void commitTransaction(Object transaction) {
    ((EntitiyTransaction) transaction).commit();
}

public static void rollbackTransaction(Object transaction) {
    ((EntitiyTransaction) transaction).rollback();
}

public static boolean transactionIsActive(Object transaction) {
   return ((EntitiyTransaction) transaction).isActive();
}

These then would be called from wherever olingo JPA needs them.

That way any one needing JTA can override these methods while the rest won't even notice them... 


What do you think?

Best,

Korbinian





----- Ursprüngliche Mail -----
> Von: "Chandan V.A" <ch...@sap.com>
> An: user@olingo.apache.org
> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
> Betreff: RE: olingo JPA / JTA - wrong transactions used
> 
> Hello Korbinian,
> I would at least keep the application managed transactions (like JTA) outside
> the context of JPA Processor for following reasons
> 1) Wiring the JTA transactions into JPA processor could make the processor to
> behave more like a framework than as a library (which is the current state).
> 2) JPA processor also need to take JNDI lookup as parameter from applications
> for looking up the datasource.
> 3) Olingo JPA processor should take care of just data transformations and
> need not worry about the scope of transactions
> 4) Olingo JPA processor should not take dependency to J2EE api because I am
> not sure will this artifact work in OSGI environments
> 
> One proposal from my side would be to provide a callback mechanism for
> transaction handling, where the library just calls a method in the interface
> to begin the transaction and end the transaction. If no one implements the
> callback mechanism the library would resort to "RESOURCE_LOCAL" based
> transaction handling. With this approach applications will have a greater
> control over transaction handling and also need not rewrite JPAProcessorImpl
> or extend ODataJPAProcessor.
> 
> What do you think? Do you foresee any shortcomings with this approach?
> 
> Thanks
> Kind Regards
> Chandan
> 
> 
> 
> -----Original Message-----
> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> Sent: Wednesday, February 18, 2015 6:22 PM
> To: user@olingo.apache.org
> Subject: Re: olingo JPA / JTA - wrong transactions used
> 
> Hello Chandan,
> 
> I finally had some success in using JTA based transactions. However, this
> only worked when I cloned the current git and changed it in the
> JPAProcessorImpl directly; If I try to do this from within my project onto
> the intialization with
> 
> oDatJPAContext.setODataProcessor(new ODataJPAProcessorJTA(oDatJPAContext));
> 
> I then have to do a ODataJPAProcessorJTA which is 99% copy n paste from
> ODataJPAProcessor and then also need a 95% copy n paste JPAProcessorImplJTA
> from JPAProcessorImpl;
> 
> As if this isn't ugly enough, it gets real dirty when trying to use it as you
> simply cant force olingo to use it! Problem is that it comes from the
> JPAAccessFactoryImpl class static; is a static one and sits in
> ODataJPAFactoryImpl and finally this one gets called in public abstract
> class ODataJPAFactory
> 
> using
> 
>  public static ODataJPAFactory createFactory() {
> 
>     if (factoryImpl != null) {
>       return factoryImpl;
>     } else {
>       try {
>         Class<?> clazz = Class.forName(ODataJPAFactory.IMPLEMENTATION);
> 
>         Object object = clazz.newInstance();
>         factoryImpl = (ODataJPAFactory) object;
> 
>       } catch (Exception e) {
>         throw new RuntimeException(e);
>       }
> 
>       return factoryImpl;
>     }
>   }
> 
> where private static final String IMPLEMENTATION =
>       "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
> 
> 
> Simple said - overriding this logic in the olingo project is next to
> impossible as you would end up with nearly the whole project copy'n'pasted
> over; Simple changing the e.g.  resolver etc. wont works as there are many
> usages of the ODataJPAFactory createFactory() method;
> 
> 
> Implementing JTA to work in olingo on the other hand is quite easy. You can
> check on the fly if your JTA or not via e.g.:
> 
>  public static boolean isResourceLocal(EntityManager em) {
>         try {
>             EntityTransaction tx = em.getTransaction();
>             return true;
>         } catch (IllegalStateException ex) {
>             return false;
>         }
>     }
> 
> and this one can then set into a boolean var classwide in the
> JPAProcessorImpl; so the setTransaction would become:
> 
> private boolean setTransaction() {
>       if(isLocalTX) {
>           final EntityTransaction transaction = em.getTransaction();
>           if (!transaction.isActive()) {
>               em.getTransaction().begin();
>               return true;
>           }
>       } else {
>           try {
>               transaction = (UserTransaction) new
>               InitialContext().lookup("java:comp/UserTransaction");
>               transaction.begin();
>           } catch (NamingException e) {
>               e.printStackTrace();
>           } catch (NotSupportedException e) {
>               e.printStackTrace();
>           } catch (SystemException e) {
>               e.printStackTrace();
>           }
>       }
> 
> 
>     return false;
>   }
> 
> 
> and this would work on all JTA bases Servers. The rest of the transaction
> logic would simply look like e.g.:
> 
> if (isLocalTransaction) {
>         em.getTransaction().commit();
>       }
> if(transaction != null) {
>             transaction.commit();
>       }
> Or even
> if (isLocalTransaction) {
>         em.getTransaction().commit();
>       }
> else {
>             transaction.commit();
>       }
> in case we expect a 100% availbilty of transactional context;
> 
> 
> 
> Problem is now that this needs at least the dependency of
>         <dependency>
>             <groupId>javax</groupId>
>             <artifactId>javaee-api</artifactId>
>             <version>6.0</version>
>         </dependency>
> as else there is no UserTransaction class available; Would this dependency be
> ok for the JPA part of the olingo project?
> 
> What do you think?
> 
> Best,
> 
> Korbinian
> 
> 
> 
> ----- Ursprüngliche Mail -----
> > Von: "Chandan V.A" <ch...@sap.com>
> > An: user@olingo.apache.org
> > Gesendet: Mittwoch, 18. Februar 2015 10:26:11
> > Betreff: RE: olingo JPA / JTA - wrong transactions used
> > 
> > Hello Korbinian,
> > Please check the JIRA item -
> > https://issues.apache.org/jira/browse/OLINGO-549
> > for updates on Olingo V4 JPA processor. Current status is there is no
> > support for V4 JPA processor and the development is in progress.
> > 
> > Thanks
> > Kind Regards
> > Chandan
> > 
> > -----Original Message-----
> > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > Sent: Wednesday, February 18, 2015 2:48 PM
> > To: user@olingo.apache.org
> > Subject: Re: olingo JPA / JTA - wrong transactions used
> > 
> > Hello Chandan,
> > 
> > thank you for the info. Will try this. I've seen that Olingo also has a
> > OData
> > V4 in Beta2 - but I couldn't really find information about its "readyness".
> > Would it work in a simple CRUD scenario with JPA? Reason is as it seems as
> > my other system I talk to via OData is moving from V3 to V4 currently, at
> > least the doc of its alredy speaks of OData V4 ready.
> > (Beside: how to setup JPA? - the onlingo 2.x way wont work)
> > 
> > Best,
> > 
> > Korbinian
> > 
> > 
> > 
> > ----- Ursprüngliche Mail -----
> > > Von: "Chandan V.A" <ch...@sap.com>
> > > An: user@olingo.apache.org
> > > Gesendet: Dienstag, 17. Februar 2015 07:11:28
> > > Betreff: RE: olingo JPA / JTA - wrong transactions used
> > > 
> > > Hello Korbinian,
> > > You can extend the
> > > org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and
> > > implement
> > > the processor methods as it is done in
> > > org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault. In
> > > your implementation for Create, Update and Delete you could begin the JTA
> > > transaction and close the transaction by either commit or rollback.
> > > 
> > > I have not tried the scenario with JTA based transactions but only
> > > Resource
> > > Local based transactions. Please check and tell if the above solution
> > > works
> > > for your case. Else raise a JIRA feature request to support JTA based
> > > transactions.
> > > 
> > > Regards
> > > Chandan
> > > 
> > > -----Original Message-----
> > > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > Sent: Monday, February 16, 2015 2:16 PM
> > > To: user@olingo.apache.org
> > > Subject: olingo JPA / JTA - wrong transactions used
> > > 
> > > Hi,
> > > 
> > > I'm using Olingo 2.0.2 and I can query all items so far. When I want to
> > > update content, I get error:
> > > 
> > > ...
> > > <message xml:lang="en">"OData - JPA Runtime: JPA update request is not
> > > correct"message>
> > >     <innererror>class java.lang.IllegalStateException :
> > > Exception Description: Cannot use an EntityTransaction while using
> > > JTA.innererror>
> > > ....
> > > 
> > > Digging deeper into the code, I ended up in file ODataJPAContextImpl
> > > 
> > > and there in the function
> > > 
> > > private  Object processUpdate(PutMergePatchUriInfo updateView,
> > >       final InputStream content, final Map<String, Object> properties,
> > >       final
> > >       String requestContentType)
> > >       throws ODataJPAModelException, ODataJPARuntimeException {
> > > ...
> > > boolean isLocalTransaction = setTransaction();
> > > 
> > > ...
> > > }
> > > 
> > > with
> > > 
> > > private boolean setTransaction() {
> > >     final EntityTransaction transaction = em.getTransaction();
> > >     if (!transaction.isActive()) {
> > >       em.getTransaction().begin();
> > >       return true;
> > >     }
> > > 
> > >     return false;
> > >   }
> > > 
> > > 
> > > So far I understood this one is the function that collides with my JTA
> > > setup.
> > > I now wonder how I can suppress to initialize this method?
> > > 
> > > I've sending in the right EntityManagerFactory into Olingo, e.g.:
> > > 
> > > public class ConnectorODataJPAServiceFactory extends
> > > ODataJPAServiceFactory
> > > {
> > > 
> > >     private static final String PERSISTENCE_UNIT_NAME = "myPU";
> > > 
> > >     @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
> > >     EntityManagerFactory emf;
> > > 
> > > 
> > >     @Override
> > >     public ODataJPAContext initializeODataJPAContext() throws
> > >     ODataJPARuntimeException {
> > >         ODataJPAContext oDatJPAContext = this.getODataJPAContext();
> > > 
> > >         try {
> > >             CdiContainer.get().getNonContextualManager().postConstruct(this);
> > >             oDatJPAContext.setEntityManagerFactory(emf);
> > >             oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
> > >             oDatJPAContext.setPageSize(100);
> > >             setDetailErrors(true);
> > >             return oDatJPAContext;
> > >         } catch (Exception e) {
> > >             System.out.print(e);
> > >             throw new RuntimeException(e);
> > >         }
> > >     }
> > > 
> > > ...
> > > 
> > > So where is the catch here?
> > > 
> > > 
> > > Best,
> > > 
> > > Korbinian
> > > 
> > 
> 

Re: olingo JPA / JTA - wrong transactions used

Posted by Korbinian Bachl <ko...@whiskyworld.de>.
Hello Chandan,

sounds good. What I would do - based upon your idea - is to extend the ODataJPAServiceFactory with 4 methods (as this one has to be used in any case):

public static void startTransaction(EntityManager em, Object transaction) {
    em.getTransaction().begin();
    transaction = em.getTransaction();
}

public static void commitTransaction(Object transaction) {
    ((EntitiyTransaction) transaction).commit();
}

public static void rollbackTransaction(Object transaction) {
    ((EntitiyTransaction) transaction).rollback();
}

public static boolean transactionIsActive(Object transaction) {
   return ((EntitiyTransaction) transaction).isActive();
}

These then would be called from wherever olingo JPA needs them.

That way any one needing JTA can override these methods while the rest won't even notice them... 


What do you think?

Best,

Korbinian





----- Ursprüngliche Mail -----
> Von: "Chandan V.A" <ch...@sap.com>
> An: user@olingo.apache.org
> Gesendet: Mittwoch, 18. Februar 2015 14:26:45
> Betreff: RE: olingo JPA / JTA - wrong transactions used
> 
> Hello Korbinian,
> I would at least keep the application managed transactions (like JTA) outside
> the context of JPA Processor for following reasons
> 1) Wiring the JTA transactions into JPA processor could make the processor to
> behave more like a framework than as a library (which is the current state).
> 2) JPA processor also need to take JNDI lookup as parameter from applications
> for looking up the datasource.
> 3) Olingo JPA processor should take care of just data transformations and
> need not worry about the scope of transactions
> 4) Olingo JPA processor should not take dependency to J2EE api because I am
> not sure will this artifact work in OSGI environments
> 
> One proposal from my side would be to provide a callback mechanism for
> transaction handling, where the library just calls a method in the interface
> to begin the transaction and end the transaction. If no one implements the
> callback mechanism the library would resort to "RESOURCE_LOCAL" based
> transaction handling. With this approach applications will have a greater
> control over transaction handling and also need not rewrite JPAProcessorImpl
> or extend ODataJPAProcessor.
> 
> What do you think? Do you foresee any shortcomings with this approach?
> 
> Thanks
> Kind Regards
> Chandan
> 
> 
> 
> -----Original Message-----
> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> Sent: Wednesday, February 18, 2015 6:22 PM
> To: user@olingo.apache.org
> Subject: Re: olingo JPA / JTA - wrong transactions used
> 
> Hello Chandan,
> 
> I finally had some success in using JTA based transactions. However, this
> only worked when I cloned the current git and changed it in the
> JPAProcessorImpl directly; If I try to do this from within my project onto
> the intialization with
> 
> oDatJPAContext.setODataProcessor(new ODataJPAProcessorJTA(oDatJPAContext));
> 
> I then have to do a ODataJPAProcessorJTA which is 99% copy n paste from
> ODataJPAProcessor and then also need a 95% copy n paste JPAProcessorImplJTA
> from JPAProcessorImpl;
> 
> As if this isn't ugly enough, it gets real dirty when trying to use it as you
> simply cant force olingo to use it! Problem is that it comes from the
> JPAAccessFactoryImpl class static; is a static one and sits in
> ODataJPAFactoryImpl and finally this one gets called in public abstract
> class ODataJPAFactory
> 
> using
> 
>  public static ODataJPAFactory createFactory() {
> 
>     if (factoryImpl != null) {
>       return factoryImpl;
>     } else {
>       try {
>         Class<?> clazz = Class.forName(ODataJPAFactory.IMPLEMENTATION);
> 
>         Object object = clazz.newInstance();
>         factoryImpl = (ODataJPAFactory) object;
> 
>       } catch (Exception e) {
>         throw new RuntimeException(e);
>       }
> 
>       return factoryImpl;
>     }
>   }
> 
> where private static final String IMPLEMENTATION =
>       "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";
> 
> 
> Simple said - overriding this logic in the olingo project is next to
> impossible as you would end up with nearly the whole project copy'n'pasted
> over; Simple changing the e.g.  resolver etc. wont works as there are many
> usages of the ODataJPAFactory createFactory() method;
> 
> 
> Implementing JTA to work in olingo on the other hand is quite easy. You can
> check on the fly if your JTA or not via e.g.:
> 
>  public static boolean isResourceLocal(EntityManager em) {
>         try {
>             EntityTransaction tx = em.getTransaction();
>             return true;
>         } catch (IllegalStateException ex) {
>             return false;
>         }
>     }
> 
> and this one can then set into a boolean var classwide in the
> JPAProcessorImpl; so the setTransaction would become:
> 
> private boolean setTransaction() {
>       if(isLocalTX) {
>           final EntityTransaction transaction = em.getTransaction();
>           if (!transaction.isActive()) {
>               em.getTransaction().begin();
>               return true;
>           }
>       } else {
>           try {
>               transaction = (UserTransaction) new
>               InitialContext().lookup("java:comp/UserTransaction");
>               transaction.begin();
>           } catch (NamingException e) {
>               e.printStackTrace();
>           } catch (NotSupportedException e) {
>               e.printStackTrace();
>           } catch (SystemException e) {
>               e.printStackTrace();
>           }
>       }
> 
> 
>     return false;
>   }
> 
> 
> and this would work on all JTA bases Servers. The rest of the transaction
> logic would simply look like e.g.:
> 
> if (isLocalTransaction) {
>         em.getTransaction().commit();
>       }
> if(transaction != null) {
>             transaction.commit();
>       }
> Or even
> if (isLocalTransaction) {
>         em.getTransaction().commit();
>       }
> else {
>             transaction.commit();
>       }
> in case we expect a 100% availbilty of transactional context;
> 
> 
> 
> Problem is now that this needs at least the dependency of
>         <dependency>
>             <groupId>javax</groupId>
>             <artifactId>javaee-api</artifactId>
>             <version>6.0</version>
>         </dependency>
> as else there is no UserTransaction class available; Would this dependency be
> ok for the JPA part of the olingo project?
> 
> What do you think?
> 
> Best,
> 
> Korbinian
> 
> 
> 
> ----- Ursprüngliche Mail -----
> > Von: "Chandan V.A" <ch...@sap.com>
> > An: user@olingo.apache.org
> > Gesendet: Mittwoch, 18. Februar 2015 10:26:11
> > Betreff: RE: olingo JPA / JTA - wrong transactions used
> > 
> > Hello Korbinian,
> > Please check the JIRA item -
> > https://issues.apache.org/jira/browse/OLINGO-549
> > for updates on Olingo V4 JPA processor. Current status is there is no
> > support for V4 JPA processor and the development is in progress.
> > 
> > Thanks
> > Kind Regards
> > Chandan
> > 
> > -----Original Message-----
> > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > Sent: Wednesday, February 18, 2015 2:48 PM
> > To: user@olingo.apache.org
> > Subject: Re: olingo JPA / JTA - wrong transactions used
> > 
> > Hello Chandan,
> > 
> > thank you for the info. Will try this. I've seen that Olingo also has a
> > OData
> > V4 in Beta2 - but I couldn't really find information about its "readyness".
> > Would it work in a simple CRUD scenario with JPA? Reason is as it seems as
> > my other system I talk to via OData is moving from V3 to V4 currently, at
> > least the doc of its alredy speaks of OData V4 ready.
> > (Beside: how to setup JPA? - the onlingo 2.x way wont work)
> > 
> > Best,
> > 
> > Korbinian
> > 
> > 
> > 
> > ----- Ursprüngliche Mail -----
> > > Von: "Chandan V.A" <ch...@sap.com>
> > > An: user@olingo.apache.org
> > > Gesendet: Dienstag, 17. Februar 2015 07:11:28
> > > Betreff: RE: olingo JPA / JTA - wrong transactions used
> > > 
> > > Hello Korbinian,
> > > You can extend the
> > > org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and
> > > implement
> > > the processor methods as it is done in
> > > org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault. In
> > > your implementation for Create, Update and Delete you could begin the JTA
> > > transaction and close the transaction by either commit or rollback.
> > > 
> > > I have not tried the scenario with JTA based transactions but only
> > > Resource
> > > Local based transactions. Please check and tell if the above solution
> > > works
> > > for your case. Else raise a JIRA feature request to support JTA based
> > > transactions.
> > > 
> > > Regards
> > > Chandan
> > > 
> > > -----Original Message-----
> > > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > > Sent: Monday, February 16, 2015 2:16 PM
> > > To: user@olingo.apache.org
> > > Subject: olingo JPA / JTA - wrong transactions used
> > > 
> > > Hi,
> > > 
> > > I'm using Olingo 2.0.2 and I can query all items so far. When I want to
> > > update content, I get error:
> > > 
> > > ...
> > > <message xml:lang="en">"OData - JPA Runtime: JPA update request is not
> > > correct"message>
> > >     <innererror>class java.lang.IllegalStateException :
> > > Exception Description: Cannot use an EntityTransaction while using
> > > JTA.innererror>
> > > ....
> > > 
> > > Digging deeper into the code, I ended up in file ODataJPAContextImpl
> > > 
> > > and there in the function
> > > 
> > > private  Object processUpdate(PutMergePatchUriInfo updateView,
> > >       final InputStream content, final Map<String, Object> properties,
> > >       final
> > >       String requestContentType)
> > >       throws ODataJPAModelException, ODataJPARuntimeException {
> > > ...
> > > boolean isLocalTransaction = setTransaction();
> > > 
> > > ...
> > > }
> > > 
> > > with
> > > 
> > > private boolean setTransaction() {
> > >     final EntityTransaction transaction = em.getTransaction();
> > >     if (!transaction.isActive()) {
> > >       em.getTransaction().begin();
> > >       return true;
> > >     }
> > > 
> > >     return false;
> > >   }
> > > 
> > > 
> > > So far I understood this one is the function that collides with my JTA
> > > setup.
> > > I now wonder how I can suppress to initialize this method?
> > > 
> > > I've sending in the right EntityManagerFactory into Olingo, e.g.:
> > > 
> > > public class ConnectorODataJPAServiceFactory extends
> > > ODataJPAServiceFactory
> > > {
> > > 
> > >     private static final String PERSISTENCE_UNIT_NAME = "myPU";
> > > 
> > >     @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
> > >     EntityManagerFactory emf;
> > > 
> > > 
> > >     @Override
> > >     public ODataJPAContext initializeODataJPAContext() throws
> > >     ODataJPARuntimeException {
> > >         ODataJPAContext oDatJPAContext = this.getODataJPAContext();
> > > 
> > >         try {
> > >             CdiContainer.get().getNonContextualManager().postConstruct(this);
> > >             oDatJPAContext.setEntityManagerFactory(emf);
> > >             oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
> > >             oDatJPAContext.setPageSize(100);
> > >             setDetailErrors(true);
> > >             return oDatJPAContext;
> > >         } catch (Exception e) {
> > >             System.out.print(e);
> > >             throw new RuntimeException(e);
> > >         }
> > >     }
> > > 
> > > ...
> > > 
> > > So where is the catch here?
> > > 
> > > 
> > > Best,
> > > 
> > > Korbinian
> > > 
> > 
> 

RE: olingo JPA / JTA - wrong transactions used

Posted by "V.A, Chandan" <ch...@sap.com>.
Hello Korbinian,
I would at least keep the application managed transactions (like JTA) outside the context of JPA Processor for following reasons
1) Wiring the JTA transactions into JPA processor could make the processor to behave more like a framework than as a library (which is the current state).
2) JPA processor also need to take JNDI lookup as parameter from applications for looking up the datasource.
3) Olingo JPA processor should take care of just data transformations and need not worry about the scope of transactions
4) Olingo JPA processor should not take dependency to J2EE api because I am not sure will this artifact work in OSGI environments

One proposal from my side would be to provide a callback mechanism for transaction handling, where the library just calls a method in the interface to begin the transaction and end the transaction. If no one implements the callback mechanism the library would resort to "RESOURCE_LOCAL" based transaction handling. With this approach applications will have a greater control over transaction handling and also need not rewrite JPAProcessorImpl or extend ODataJPAProcessor.

What do you think? Do you foresee any shortcomings with this approach?

Thanks
Kind Regards
Chandan



-----Original Message-----
From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de] 
Sent: Wednesday, February 18, 2015 6:22 PM
To: user@olingo.apache.org
Subject: Re: olingo JPA / JTA - wrong transactions used

Hello Chandan,

I finally had some success in using JTA based transactions. However, this only worked when I cloned the current git and changed it in the JPAProcessorImpl directly; If I try to do this from within my project onto the intialization with 

oDatJPAContext.setODataProcessor(new ODataJPAProcessorJTA(oDatJPAContext));

I then have to do a ODataJPAProcessorJTA which is 99% copy n paste from ODataJPAProcessor and then also need a 95% copy n paste JPAProcessorImplJTA from JPAProcessorImpl;

As if this isn't ugly enough, it gets real dirty when trying to use it as you simply cant force olingo to use it! Problem is that it comes from the JPAAccessFactoryImpl class static; is a static one and sits in ODataJPAFactoryImpl and finally this one gets called in public abstract class ODataJPAFactory

using

 public static ODataJPAFactory createFactory() {

    if (factoryImpl != null) {
      return factoryImpl;
    } else {
      try {
        Class<?> clazz = Class.forName(ODataJPAFactory.IMPLEMENTATION);

        Object object = clazz.newInstance();
        factoryImpl = (ODataJPAFactory) object;

      } catch (Exception e) {
        throw new RuntimeException(e);
      }

      return factoryImpl;
    }
  }

where private static final String IMPLEMENTATION =
      "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";


Simple said - overriding this logic in the olingo project is next to impossible as you would end up with nearly the whole project copy'n'pasted over; Simple changing the e.g.  resolver etc. wont works as there are many usages of the ODataJPAFactory createFactory() method;


Implementing JTA to work in olingo on the other hand is quite easy. You can check on the fly if your JTA or not via e.g.:

 public static boolean isResourceLocal(EntityManager em) {
        try {
            EntityTransaction tx = em.getTransaction();
            return true;
        } catch (IllegalStateException ex) {
            return false;
        }
    }

and this one can then set into a boolean var classwide in the JPAProcessorImpl; so the setTransaction would become:

private boolean setTransaction() {
      if(isLocalTX) {
          final EntityTransaction transaction = em.getTransaction();
          if (!transaction.isActive()) {
              em.getTransaction().begin();
              return true;
          }
      } else {
          try {
              transaction = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");
              transaction.begin();
          } catch (NamingException e) {
              e.printStackTrace();
          } catch (NotSupportedException e) {
              e.printStackTrace();
          } catch (SystemException e) {
              e.printStackTrace();
          }
      }


    return false;
  }


and this would work on all JTA bases Servers. The rest of the transaction logic would simply look like e.g.:

if (isLocalTransaction) {
        em.getTransaction().commit();
      }
if(transaction != null) {
            transaction.commit();
      }
Or even
if (isLocalTransaction) {
        em.getTransaction().commit();
      }
else {
            transaction.commit();
      }
in case we expect a 100% availbilty of transactional context;



Problem is now that this needs at least the dependency of 
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>6.0</version>
        </dependency>
as else there is no UserTransaction class available; Would this dependency be ok for the JPA part of the olingo project?

What do you think?

Best,

Korbinian



----- Ursprüngliche Mail -----
> Von: "Chandan V.A" <ch...@sap.com>
> An: user@olingo.apache.org
> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
> Betreff: RE: olingo JPA / JTA - wrong transactions used
> 
> Hello Korbinian,
> Please check the JIRA item - https://issues.apache.org/jira/browse/OLINGO-549
> for updates on Olingo V4 JPA processor. Current status is there is no
> support for V4 JPA processor and the development is in progress.
> 
> Thanks
> Kind Regards
> Chandan
> 
> -----Original Message-----
> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> Sent: Wednesday, February 18, 2015 2:48 PM
> To: user@olingo.apache.org
> Subject: Re: olingo JPA / JTA - wrong transactions used
> 
> Hello Chandan,
> 
> thank you for the info. Will try this. I've seen that Olingo also has a OData
> V4 in Beta2 - but I couldn't really find information about its "readyness".
> Would it work in a simple CRUD scenario with JPA? Reason is as it seems as
> my other system I talk to via OData is moving from V3 to V4 currently, at
> least the doc of its alredy speaks of OData V4 ready.
> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
> 
> Best,
> 
> Korbinian
> 
> 
> 
> ----- Ursprüngliche Mail -----
> > Von: "Chandan V.A" <ch...@sap.com>
> > An: user@olingo.apache.org
> > Gesendet: Dienstag, 17. Februar 2015 07:11:28
> > Betreff: RE: olingo JPA / JTA - wrong transactions used
> > 
> > Hello Korbinian,
> > You can extend the
> > org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and implement
> > the processor methods as it is done in
> > org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault. In
> > your implementation for Create, Update and Delete you could begin the JTA
> > transaction and close the transaction by either commit or rollback.
> > 
> > I have not tried the scenario with JTA based transactions but only Resource
> > Local based transactions. Please check and tell if the above solution works
> > for your case. Else raise a JIRA feature request to support JTA based
> > transactions.
> > 
> > Regards
> > Chandan
> > 
> > -----Original Message-----
> > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > Sent: Monday, February 16, 2015 2:16 PM
> > To: user@olingo.apache.org
> > Subject: olingo JPA / JTA - wrong transactions used
> > 
> > Hi,
> > 
> > I'm using Olingo 2.0.2 and I can query all items so far. When I want to
> > update content, I get error:
> > 
> > ...
> > <message xml:lang="en">"OData - JPA Runtime: JPA update request is not
> > correct"message>
> >     <innererror>class java.lang.IllegalStateException :
> > Exception Description: Cannot use an EntityTransaction while using
> > JTA.innererror>
> > ....
> > 
> > Digging deeper into the code, I ended up in file ODataJPAContextImpl
> > 
> > and there in the function
> > 
> > private  Object processUpdate(PutMergePatchUriInfo updateView,
> >       final InputStream content, final Map<String, Object> properties,
> >       final
> >       String requestContentType)
> >       throws ODataJPAModelException, ODataJPARuntimeException {
> > ...
> > boolean isLocalTransaction = setTransaction();
> > 
> > ...
> > }
> > 
> > with
> > 
> > private boolean setTransaction() {
> >     final EntityTransaction transaction = em.getTransaction();
> >     if (!transaction.isActive()) {
> >       em.getTransaction().begin();
> >       return true;
> >     }
> > 
> >     return false;
> >   }
> > 
> > 
> > So far I understood this one is the function that collides with my JTA
> > setup.
> > I now wonder how I can suppress to initialize this method?
> > 
> > I've sending in the right EntityManagerFactory into Olingo, e.g.:
> > 
> > public class ConnectorODataJPAServiceFactory extends ODataJPAServiceFactory
> > {
> > 
> >     private static final String PERSISTENCE_UNIT_NAME = "myPU";
> > 
> >     @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
> >     EntityManagerFactory emf;
> > 
> > 
> >     @Override
> >     public ODataJPAContext initializeODataJPAContext() throws
> >     ODataJPARuntimeException {
> >         ODataJPAContext oDatJPAContext = this.getODataJPAContext();
> > 
> >         try {
> >             CdiContainer.get().getNonContextualManager().postConstruct(this);
> >             oDatJPAContext.setEntityManagerFactory(emf);
> >             oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
> >             oDatJPAContext.setPageSize(100);
> >             setDetailErrors(true);
> >             return oDatJPAContext;
> >         } catch (Exception e) {
> >             System.out.print(e);
> >             throw new RuntimeException(e);
> >         }
> >     }
> > 
> > ...
> > 
> > So where is the catch here?
> > 
> > 
> > Best,
> > 
> > Korbinian
> > 
> 

Re: olingo JPA / JTA - wrong transactions used

Posted by Korbinian Bachl <ko...@whiskyworld.de>.
Hello Chandan,

I finally had some success in using JTA based transactions. However, this only worked when I cloned the current git and changed it in the JPAProcessorImpl directly; If I try to do this from within my project onto the intialization with 

oDatJPAContext.setODataProcessor(new ODataJPAProcessorJTA(oDatJPAContext));

I then have to do a ODataJPAProcessorJTA which is 99% copy n paste from ODataJPAProcessor and then also need a 95% copy n paste JPAProcessorImplJTA from JPAProcessorImpl;

As if this isn't ugly enough, it gets real dirty when trying to use it as you simply cant force olingo to use it! Problem is that it comes from the JPAAccessFactoryImpl class static; is a static one and sits in ODataJPAFactoryImpl and finally this one gets called in public abstract class ODataJPAFactory

using

 public static ODataJPAFactory createFactory() {

    if (factoryImpl != null) {
      return factoryImpl;
    } else {
      try {
        Class<?> clazz = Class.forName(ODataJPAFactory.IMPLEMENTATION);

        Object object = clazz.newInstance();
        factoryImpl = (ODataJPAFactory) object;

      } catch (Exception e) {
        throw new RuntimeException(e);
      }

      return factoryImpl;
    }
  }

where private static final String IMPLEMENTATION =
      "org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl";


Simple said - overriding this logic in the olingo project is next to impossible as you would end up with nearly the whole project copy'n'pasted over; Simple changing the e.g.  resolver etc. wont works as there are many usages of the ODataJPAFactory createFactory() method;


Implementing JTA to work in olingo on the other hand is quite easy. You can check on the fly if your JTA or not via e.g.:

 public static boolean isResourceLocal(EntityManager em) {
        try {
            EntityTransaction tx = em.getTransaction();
            return true;
        } catch (IllegalStateException ex) {
            return false;
        }
    }

and this one can then set into a boolean var classwide in the JPAProcessorImpl; so the setTransaction would become:

private boolean setTransaction() {
      if(isLocalTX) {
          final EntityTransaction transaction = em.getTransaction();
          if (!transaction.isActive()) {
              em.getTransaction().begin();
              return true;
          }
      } else {
          try {
              transaction = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");
              transaction.begin();
          } catch (NamingException e) {
              e.printStackTrace();
          } catch (NotSupportedException e) {
              e.printStackTrace();
          } catch (SystemException e) {
              e.printStackTrace();
          }
      }


    return false;
  }


and this would work on all JTA bases Servers. The rest of the transaction logic would simply look like e.g.:

if (isLocalTransaction) {
        em.getTransaction().commit();
      }
if(transaction != null) {
            transaction.commit();
      }
Or even
if (isLocalTransaction) {
        em.getTransaction().commit();
      }
else {
            transaction.commit();
      }
in case we expect a 100% availbilty of transactional context;



Problem is now that this needs at least the dependency of 
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>6.0</version>
        </dependency>
as else there is no UserTransaction class available; Would this dependency be ok for the JPA part of the olingo project?

What do you think?

Best,

Korbinian



----- Ursprüngliche Mail -----
> Von: "Chandan V.A" <ch...@sap.com>
> An: user@olingo.apache.org
> Gesendet: Mittwoch, 18. Februar 2015 10:26:11
> Betreff: RE: olingo JPA / JTA - wrong transactions used
> 
> Hello Korbinian,
> Please check the JIRA item - https://issues.apache.org/jira/browse/OLINGO-549
> for updates on Olingo V4 JPA processor. Current status is there is no
> support for V4 JPA processor and the development is in progress.
> 
> Thanks
> Kind Regards
> Chandan
> 
> -----Original Message-----
> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> Sent: Wednesday, February 18, 2015 2:48 PM
> To: user@olingo.apache.org
> Subject: Re: olingo JPA / JTA - wrong transactions used
> 
> Hello Chandan,
> 
> thank you for the info. Will try this. I've seen that Olingo also has a OData
> V4 in Beta2 - but I couldn't really find information about its "readyness".
> Would it work in a simple CRUD scenario with JPA? Reason is as it seems as
> my other system I talk to via OData is moving from V3 to V4 currently, at
> least the doc of its alredy speaks of OData V4 ready.
> (Beside: how to setup JPA? - the onlingo 2.x way wont work)
> 
> Best,
> 
> Korbinian
> 
> 
> 
> ----- Ursprüngliche Mail -----
> > Von: "Chandan V.A" <ch...@sap.com>
> > An: user@olingo.apache.org
> > Gesendet: Dienstag, 17. Februar 2015 07:11:28
> > Betreff: RE: olingo JPA / JTA - wrong transactions used
> > 
> > Hello Korbinian,
> > You can extend the
> > org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and implement
> > the processor methods as it is done in
> > org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault. In
> > your implementation for Create, Update and Delete you could begin the JTA
> > transaction and close the transaction by either commit or rollback.
> > 
> > I have not tried the scenario with JTA based transactions but only Resource
> > Local based transactions. Please check and tell if the above solution works
> > for your case. Else raise a JIRA feature request to support JTA based
> > transactions.
> > 
> > Regards
> > Chandan
> > 
> > -----Original Message-----
> > From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> > Sent: Monday, February 16, 2015 2:16 PM
> > To: user@olingo.apache.org
> > Subject: olingo JPA / JTA - wrong transactions used
> > 
> > Hi,
> > 
> > I'm using Olingo 2.0.2 and I can query all items so far. When I want to
> > update content, I get error:
> > 
> > ...
> > <message xml:lang="en">"OData - JPA Runtime: JPA update request is not
> > correct"message>
> >     <innererror>class java.lang.IllegalStateException :
> > Exception Description: Cannot use an EntityTransaction while using
> > JTA.innererror>
> > ....
> > 
> > Digging deeper into the code, I ended up in file ODataJPAContextImpl
> > 
> > and there in the function
> > 
> > private  Object processUpdate(PutMergePatchUriInfo updateView,
> >       final InputStream content, final Map<String, Object> properties,
> >       final
> >       String requestContentType)
> >       throws ODataJPAModelException, ODataJPARuntimeException {
> > ...
> > boolean isLocalTransaction = setTransaction();
> > 
> > ...
> > }
> > 
> > with
> > 
> > private boolean setTransaction() {
> >     final EntityTransaction transaction = em.getTransaction();
> >     if (!transaction.isActive()) {
> >       em.getTransaction().begin();
> >       return true;
> >     }
> > 
> >     return false;
> >   }
> > 
> > 
> > So far I understood this one is the function that collides with my JTA
> > setup.
> > I now wonder how I can suppress to initialize this method?
> > 
> > I've sending in the right EntityManagerFactory into Olingo, e.g.:
> > 
> > public class ConnectorODataJPAServiceFactory extends ODataJPAServiceFactory
> > {
> > 
> >     private static final String PERSISTENCE_UNIT_NAME = "myPU";
> > 
> >     @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
> >     EntityManagerFactory emf;
> > 
> > 
> >     @Override
> >     public ODataJPAContext initializeODataJPAContext() throws
> >     ODataJPARuntimeException {
> >         ODataJPAContext oDatJPAContext = this.getODataJPAContext();
> > 
> >         try {
> >             CdiContainer.get().getNonContextualManager().postConstruct(this);
> >             oDatJPAContext.setEntityManagerFactory(emf);
> >             oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
> >             oDatJPAContext.setPageSize(100);
> >             setDetailErrors(true);
> >             return oDatJPAContext;
> >         } catch (Exception e) {
> >             System.out.print(e);
> >             throw new RuntimeException(e);
> >         }
> >     }
> > 
> > ...
> > 
> > So where is the catch here?
> > 
> > 
> > Best,
> > 
> > Korbinian
> > 
> 

RE: olingo JPA / JTA - wrong transactions used

Posted by "V.A, Chandan" <ch...@sap.com>.
Hello Korbinian,
Please check the JIRA item - https://issues.apache.org/jira/browse/OLINGO-549 for updates on Olingo V4 JPA processor. Current status is there is no support for V4 JPA processor and the development is in progress.

Thanks
Kind Regards
Chandan

-----Original Message-----
From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de] 
Sent: Wednesday, February 18, 2015 2:48 PM
To: user@olingo.apache.org
Subject: Re: olingo JPA / JTA - wrong transactions used

Hello Chandan,

thank you for the info. Will try this. I've seen that Olingo also has a OData V4 in Beta2 - but I couldn't really find information about its "readyness". Would it work in a simple CRUD scenario with JPA? Reason is as it seems as my other system I talk to via OData is moving from V3 to V4 currently, at least the doc of its alredy speaks of OData V4 ready.
(Beside: how to setup JPA? - the onlingo 2.x way wont work)

Best,

Korbinian



----- Ursprüngliche Mail -----
> Von: "Chandan V.A" <ch...@sap.com>
> An: user@olingo.apache.org
> Gesendet: Dienstag, 17. Februar 2015 07:11:28
> Betreff: RE: olingo JPA / JTA - wrong transactions used
> 
> Hello Korbinian,
> You can extend the
> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and implement
> the processor methods as it is done in
> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault. In
> your implementation for Create, Update and Delete you could begin the JTA
> transaction and close the transaction by either commit or rollback.
> 
> I have not tried the scenario with JTA based transactions but only Resource
> Local based transactions. Please check and tell if the above solution works
> for your case. Else raise a JIRA feature request to support JTA based
> transactions.
> 
> Regards
> Chandan
> 
> -----Original Message-----
> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> Sent: Monday, February 16, 2015 2:16 PM
> To: user@olingo.apache.org
> Subject: olingo JPA / JTA - wrong transactions used
> 
> Hi,
> 
> I'm using Olingo 2.0.2 and I can query all items so far. When I want to
> update content, I get error:
> 
> ...
> <message xml:lang="en">"OData - JPA Runtime: JPA update request is not
> correct"message>
>     <innererror>class java.lang.IllegalStateException :
> Exception Description: Cannot use an EntityTransaction while using
> JTA.innererror>
> ....
> 
> Digging deeper into the code, I ended up in file ODataJPAContextImpl
> 
> and there in the function
> 
> private  Object processUpdate(PutMergePatchUriInfo updateView,
>       final InputStream content, final Map<String, Object> properties, final
>       String requestContentType)
>       throws ODataJPAModelException, ODataJPARuntimeException {
> ...
> boolean isLocalTransaction = setTransaction();
> 
> ...
> }
> 
> with
> 
> private boolean setTransaction() {
>     final EntityTransaction transaction = em.getTransaction();
>     if (!transaction.isActive()) {
>       em.getTransaction().begin();
>       return true;
>     }
> 
>     return false;
>   }
> 
> 
> So far I understood this one is the function that collides with my JTA setup.
> I now wonder how I can suppress to initialize this method?
> 
> I've sending in the right EntityManagerFactory into Olingo, e.g.:
> 
> public class ConnectorODataJPAServiceFactory extends ODataJPAServiceFactory {
> 
>     private static final String PERSISTENCE_UNIT_NAME = "myPU";
> 
>     @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
>     EntityManagerFactory emf;
> 
> 
>     @Override
>     public ODataJPAContext initializeODataJPAContext() throws
>     ODataJPARuntimeException {
>         ODataJPAContext oDatJPAContext = this.getODataJPAContext();
> 
>         try {
>             CdiContainer.get().getNonContextualManager().postConstruct(this);
>             oDatJPAContext.setEntityManagerFactory(emf);
>             oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
>             oDatJPAContext.setPageSize(100);
>             setDetailErrors(true);
>             return oDatJPAContext;
>         } catch (Exception e) {
>             System.out.print(e);
>             throw new RuntimeException(e);
>         }
>     }
> 
> ...
> 
> So where is the catch here?
> 
> 
> Best,
> 
> Korbinian
> 

Re: olingo JPA / JTA - wrong transactions used

Posted by Korbinian Bachl <ko...@whiskyworld.de>.
Hello Chandan,

thank you for the info. Will try this. I've seen that Olingo also has a OData V4 in Beta2 - but I couldn't really find information about its "readyness". Would it work in a simple CRUD scenario with JPA? Reason is as it seems as my other system I talk to via OData is moving from V3 to V4 currently, at least the doc of its alredy speaks of OData V4 ready.
(Beside: how to setup JPA? - the onlingo 2.x way wont work)

Best,

Korbinian



----- Ursprüngliche Mail -----
> Von: "Chandan V.A" <ch...@sap.com>
> An: user@olingo.apache.org
> Gesendet: Dienstag, 17. Februar 2015 07:11:28
> Betreff: RE: olingo JPA / JTA - wrong transactions used
> 
> Hello Korbinian,
> You can extend the
> org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and implement
> the processor methods as it is done in
> org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault. In
> your implementation for Create, Update and Delete you could begin the JTA
> transaction and close the transaction by either commit or rollback.
> 
> I have not tried the scenario with JTA based transactions but only Resource
> Local based transactions. Please check and tell if the above solution works
> for your case. Else raise a JIRA feature request to support JTA based
> transactions.
> 
> Regards
> Chandan
> 
> -----Original Message-----
> From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de]
> Sent: Monday, February 16, 2015 2:16 PM
> To: user@olingo.apache.org
> Subject: olingo JPA / JTA - wrong transactions used
> 
> Hi,
> 
> I'm using Olingo 2.0.2 and I can query all items so far. When I want to
> update content, I get error:
> 
> ...
> <message xml:lang="en">"OData - JPA Runtime: JPA update request is not
> correct"message>
>     <innererror>class java.lang.IllegalStateException :
> Exception Description: Cannot use an EntityTransaction while using
> JTA.innererror>
> ....
> 
> Digging deeper into the code, I ended up in file ODataJPAContextImpl
> 
> and there in the function
> 
> private  Object processUpdate(PutMergePatchUriInfo updateView,
>       final InputStream content, final Map<String, Object> properties, final
>       String requestContentType)
>       throws ODataJPAModelException, ODataJPARuntimeException {
> ...
> boolean isLocalTransaction = setTransaction();
> 
> ...
> }
> 
> with
> 
> private boolean setTransaction() {
>     final EntityTransaction transaction = em.getTransaction();
>     if (!transaction.isActive()) {
>       em.getTransaction().begin();
>       return true;
>     }
> 
>     return false;
>   }
> 
> 
> So far I understood this one is the function that collides with my JTA setup.
> I now wonder how I can suppress to initialize this method?
> 
> I've sending in the right EntityManagerFactory into Olingo, e.g.:
> 
> public class ConnectorODataJPAServiceFactory extends ODataJPAServiceFactory {
> 
>     private static final String PERSISTENCE_UNIT_NAME = "myPU";
> 
>     @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
>     EntityManagerFactory emf;
> 
> 
>     @Override
>     public ODataJPAContext initializeODataJPAContext() throws
>     ODataJPARuntimeException {
>         ODataJPAContext oDatJPAContext = this.getODataJPAContext();
> 
>         try {
>             CdiContainer.get().getNonContextualManager().postConstruct(this);
>             oDatJPAContext.setEntityManagerFactory(emf);
>             oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
>             oDatJPAContext.setPageSize(100);
>             setDetailErrors(true);
>             return oDatJPAContext;
>         } catch (Exception e) {
>             System.out.print(e);
>             throw new RuntimeException(e);
>         }
>     }
> 
> ...
> 
> So where is the catch here?
> 
> 
> Best,
> 
> Korbinian
> 

RE: olingo JPA / JTA - wrong transactions used

Posted by "V.A, Chandan" <ch...@sap.com>.
Hello Korbinian,
You can extend the org.apache.olingo.odata2.jpa.processor.api.ODataJPAProcessor and implement the processor methods as it is done in org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault. In your implementation for Create, Update and Delete you could begin the JTA transaction and close the transaction by either commit or rollback.

I have not tried the scenario with JTA based transactions but only Resource Local based transactions. Please check and tell if the above solution works for your case. Else raise a JIRA feature request to support JTA based transactions.

Regards
Chandan

-----Original Message-----
From: Korbinian Bachl [mailto:korbinian.bachl@whiskyworld.de] 
Sent: Monday, February 16, 2015 2:16 PM
To: user@olingo.apache.org
Subject: olingo JPA / JTA - wrong transactions used

Hi,

I'm using Olingo 2.0.2 and I can query all items so far. When I want to update content, I get error:

...
<message xml:lang="en">"OData - JPA Runtime: JPA update request is not correct"message>
    <innererror>class java.lang.IllegalStateException : 
Exception Description: Cannot use an EntityTransaction while using JTA.innererror>
....

Digging deeper into the code, I ended up in file ODataJPAContextImpl

and there in the function 

private  Object processUpdate(PutMergePatchUriInfo updateView,
      final InputStream content, final Map<String, Object> properties, final String requestContentType)
      throws ODataJPAModelException, ODataJPARuntimeException {
...
boolean isLocalTransaction = setTransaction();

...
}

with

private boolean setTransaction() {
    final EntityTransaction transaction = em.getTransaction();
    if (!transaction.isActive()) {
      em.getTransaction().begin();
      return true;
    }

    return false;
  }


So far I understood this one is the function that collides with my JTA setup. I now wonder how I can suppress to initialize this method?

I've sending in the right EntityManagerFactory into Olingo, e.g.:

public class ConnectorODataJPAServiceFactory extends ODataJPAServiceFactory {

    private static final String PERSISTENCE_UNIT_NAME = "myPU";

    @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME)
    EntityManagerFactory emf;


    @Override
    public ODataJPAContext initializeODataJPAContext() throws ODataJPARuntimeException {
        ODataJPAContext oDatJPAContext = this.getODataJPAContext();

        try {
            CdiContainer.get().getNonContextualManager().postConstruct(this);
            oDatJPAContext.setEntityManagerFactory(emf);
            oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
            oDatJPAContext.setPageSize(100);
            setDetailErrors(true);
            return oDatJPAContext;
        } catch (Exception e) {
            System.out.print(e);
            throw new RuntimeException(e);
        }
    }

...

So where is the catch here?


Best,

Korbinian