You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by "Lize Anthonin (OceanOPS)" <al...@groupcls.com> on 2021/11/04 14:38:19 UTC

Insertion order issue

Hi,

I am using Cayenne in a web app (through AgRest, but this is purely cayenne related, well I think so) that contains one service through a POST method.
Basically, I submit a JSON body with multiple object in it, pass it through the service method defined below, process each object and for each ones doing some insert into an Oracle DB.
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Path("getid")
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public List<IdResponse> getID(final List<IdInput> inputs)
{
                There I loop over this list, process the object IdInput and make the necessary insertions
}

My issue there is that when I commit the changes, the order of the inserts seems to fail randomly, from one request to another. I have relationships set in those modifications, and through the logs I can see the PK being fetched from the sequences, but then sometimes (most of the times) the referencing entity is inserted before the referenced entity. And of course the commit fail for violation of parent key.

I've tried to secure as much as possible the context, through different ways:

  *   stateless thread context through the provided cayenne filter (stateless because the session one would be committed via another commit made in another filter, weird, but I send only one request, this filter commit should happen prior to the 'service' commit)
  *   per method context
  *   custom stateless context through a filter that I made myself.
I thought I got it with he per method context, but it failed after a while.
And I tried committing after each processing in the loop, or after the loop, but same results.

I'm probably missing something, but I'm not getting why it happen sometimes, not always(or never!). A threading issue maybe? But I'm processing only one request, so I'm a bit lost.
Any thoughts? (before I commit after each insertion of entities haha)
How the order of inserts are defined? Maybe I miss-configured some relationships in the modeler, but they come from a reverse engineering and look ok...

Many thanks in advance
Anthonin
________________________________

Ce message et toutes les pi?ces jointes (ci-apr?s le "message") sont ?tablis ? l'intention exclusive de ses destinataires et sont confidentiels. Si vous recevez ce message par erreur ou s'il ne vous est pas destin?, merci de le d?truire ainsi que toute copie de votre syst?me et d'en avertir imm?diatement l'exp?diteur. Toute lecture non autoris?e, toute utilisation de ce message qui n'est pas conforme ? sa destination, toute diffusion ou toute publication, totale ou partielle, est interdite. L'Internet ne permettant pas d'assurer l'int?grit? de ce message ?lectronique susceptible d'alt?ration, l'exp?diteur (et ses filiales) d?cline(nt) toute responsabilit? au titre de ce message dans l'hypoth?se o? il aurait ?t? modifi? ou falsifi?.

This message and any attachments (the "message") is intended solely for the intended recipient(s) and is confidential. If you receive this message in error, or are not the intended recipient(s), please delete it and any copies from your systems and immediately notify the sender. Any unauthorized view, use that does not comply with its purpose, dissemination or disclosure, either whole or partial, is prohibited. Since the internet cannot guarantee the integrity of this message which may not be reliable, the sender (and its subsidiaries) shall not be liable for the message if modified or falsified.

Re: Insertion order issue

Posted by Lon Varscsak <lo...@gmail.com>.
I have a DB that doesn't have deferred constraints, so I had ObjectStyle
build org.apache.cayenne.access.flush.operation.GraphBasedDbRowOpSorter.
It's less efficient, but honestly I don't really notice a performance hit.
It's also not perfect (it triggers fetches sometimes of related data), but
in terms of un-deferrable constraints it works great.

-Lon

On Fri, Nov 5, 2021 at 8:52 AM Lize Anthonin (OceanOPS) <al...@groupcls.com>
wrote:

> Thanks again for spending time on this ! :)
>
> A) yes you're right... I think I'll implement this solution and move on, I
> lost enough time already on this.
> B) I just tried anyway, it does not change anything. I'll revert to what I
> had.
> BTW, I also have a custom adapter modifying the SQLTreeProcessor to apply
> ST_AsText/ST_geomfromtext functions on ESRI SDE geometries (to which I
> attribute the Wkt cayenne type) and also to work around an issue being
> addressed in cayenne about date formatting, having consequences in AgRest (
> https://groups.google.com/g/agrest-user/c/MxFktjHhXGI,
> https://issues.apache.org/jira/browse/CAY-2700). So basically I extend
> the JdbcAdapter (so that I can have a date format in AgRest - input - close
> to the ISO one), to which I set an extended OraclePkGenerator. It's rather
> easy and works great thanks to the great work done regarding DI in Cayenne!
> Anyway, this does not change anything to that issue.
> Even if A sorts this out, I wonder why this is happening. Do you think
> reverse relationships can mess up the order ?(automatically generated while
> reverse engineering)
>
> anthonin
>
> -----Original Message-----
> From: Michael Gentry <bl...@gmail.com>
> Sent: Friday, November 5, 2021 4:35 PM
> To: Cayenne Users <us...@cayenne.apache.org>
> Subject: Re: Insertion order issue
>
> CAUTION: This message comes from an external server, do not click on links
> or open attachments unless you know the sender and are sure the content is
> safe.
>
>
> Hi Anthonin,
>
> A) If my memory hasn't failed me, a DEFERRABLE/INITIALLY DEFERRED
> constraint is checked at the END (commit) of the transaction instead of
> each statement as it happens. The constraint check still happens...just
> deferred. If there is a constraint error at the end, Oracle will roll back
> the transaction and you'll get an error/exception in your code.
>
> B) I don't think your custom PK generator will cause your current issue.
> Unless, of course, there is a bug. :-) It certainly can be annoying to set
> the sequence name/size for each entity, so I understand wanting to avoid
> that.
>
> mrg
>
>
> On Fri, Nov 5, 2021 at 11:09 AM Lize Anthonin (OceanOPS) <
> alize@groupcls.com>
> wrote:
>
> > Hi Michael,
> >
> > A) I'll look into that, I have to check the potential implications first.
> > I wanted to find an applicative work around before touching the DB.
> > But thanks, that would solve it indeed.
> > B) Just to define the sequence pattern. The default Oracle PK
> > generator uses sequence like 'PK_<TABLE_NAME>'. All my sequences are
> > like '<TABLE_NAME>_SEQ'. Since my model contains a lot of entities, I
> > extended the OraclePkGenerator to modify the sequence naming, it was
> > faster to implement. Do you think that could impact this? If so, I'll
> > spend some time defining the custom sequences. I'll try on the few
> entities I'm working on.
> >
> > anthonin
> >
> > -----Original Message-----
> > From: Michael Gentry <bl...@gmail.com>
> > Sent: Friday, November 5, 2021 2:25 PM
> > To: Cayenne Users <us...@cayenne.apache.org>
> > Subject: Re: Insertion order issue
> >
> > CAUTION: This message comes from an external server, do not click on
> > links or open attachments unless you know the sender and are sure the
> > content is safe.
> >
> >
> > Hi Anthonin,
> >
> > A) Since you are using Oracle, you may need to use a DEFERRABLE
> > constraint (INITIALLY DEFERRED).
> >
> > B) Any reason you are using a custom PK generator instead of using the
> > standard sequence generator supported by Cayenne? (Cayenne Modeler ->
> > select DB Entity -> PK Generation Strategy -> Custom Sequence -> enter
> > Sequence Name and Cache Size -- looks like you are using 1).
> >
> > mrg
> >
> >
> > On Fri, Nov 5, 2021 at 5:44 AM Lize Anthonin (OceanOPS) <
> > alize@groupcls.com>
> > wrote:
> >
> > > Hi Michael,
> > >
> > > Thanks for your answer.
> > > I tried, but does not seem to make any difference. I added
> > > WeightedAshwoodEntitySorter (amongst other things) in a module
> > > loaded as init-param for the CayenneFilter, as follows:
> > > @Override
> > > public void configure(Binder binder) {
> > >             binder.bind(RequestHandler.class)
> > >                 .to(StatelessContextRequestHandler.class)
> > >                 .withoutScope();
> > >
> > >             OraclePkGeneratorCustom pkgen = new
> > OraclePkGeneratorCustom();
> > >             pkgen.setPkCacheSize(1);
> > >             binder.bind(PkGenerator.class).toInstance(pkgen);
> > >
> > >
> > > binder.bind(EntitySorter.class).to(WeightedAshwoodEntitySorter.class
> > > );
> > > }
> > >
> > > And then the annotation as you mentioned on the child entity. It
> > > still stays rather random...
> > >
> > >
> > > Here is the stack trace, as you can see I use Cayenne 4.2.M3. That
> > > would have been smarter of me to share it initially!
> > > java.sql.SQLIntegrityConstraintViolationException: ORA-02291:
> > > integrity constraint (JCOMMOPS_B.PTF_HARDWARE_FK) violated - parent
> > > key not found
> > >
> > >         at
> > > oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:509)
> > > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> > >         at
> > > oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:461)
> > > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> > >         at
> > > oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1104)
> > > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> > >         at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:553)
> > > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> > >         at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:269)
> > > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> > >         at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:655)
> > > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> > >         at
> > > oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement
> > > .j
> > > ava:270)
> > > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> > >         at
> > > oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement
> > > .j
> > > ava:91)
> > > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> > >         at
> > > oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedSt
> > > at
> > > ement.java:970)
> > > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> > >         at
> > > oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatem
> > > en
> > > t.java:1205)
> > > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> > >         at
> > > oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePre
> > > pa
> > > redStatement.java:3666)
> > > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> > >         at
> > > oracle.jdbc.driver.T4CPreparedStatement.executeInternal(T4CPreparedS
> > > ta
> > > tement.java:1426)
> > > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> > >         at
> > > oracle.jdbc.driver.OraclePreparedStatement.executeLargeUpdate(Oracle
> > > Pr
> > > eparedStatement.java:3756)
> > > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> > >         at
> > > oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePrepa
> > > re
> > > dStatement.java:3736)
> > > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> > >         at
> > > oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(Orac
> > > le
> > > PreparedStatementWrapper.java:1063)
> > > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> > >         at
> > > org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeUpda
> > > te
> > > (DelegatingPreparedStatement.java:136)
> > > ~[tomcat-dbcp.jar:9.0.40]
> > >         at
> > > org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeUpda
> > > te
> > > (DelegatingPreparedStatement.java:136)
> > > ~[tomcat-dbcp.jar:9.0.40]
> > >         at
> > > org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(Ba
> > > tc
> > > hAction.java:185)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.access.jdbc.BatchAction.performAction(BatchAction
> > > .j
> > > ava:96)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.access.DataNodeQueryAction.runQuery(DataNodeQuery
> > > Ac
> > > tion.java:97)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$
> > > ex
> > > ecuteQueries$6(DefaultDataDomainFlushAction.java:177)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at java.util.HashMap.forEach(HashMap.java:1425) ~[?:?]
> > >         at
> > > org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.execute
> > > Qu
> > > eries(DefaultDataDomainFlushAction.java:176)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(D
> > > ef
> > > aultDataDomainFlushAction.java:89)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637
> > > )
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.access.DataDomain.onSyncNoFilters(DataDomain.java
> > > :6
> > > 09)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSyn
> > > c(
> > > DataDomain.java:835)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(TransactionF
> > > il
> > > ter.java:61)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandl
> > > er
> > > .performInTransaction(DefaultTransactionManager.java:180)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandl
> > > er
> > > .performInNewTransaction(DefaultTransactionManager.java:152)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHan
> > > dl
> > > er.handle(DefaultTransactionManager.java:95)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction
> > > (D
> > > efaultTransactionManager.java:62)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction
> > > (D
> > > efaultTransactionManager.java:40)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.tx.TransactionFilter.onSync(TransactionFilter.java:
> > > 61)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSyn
> > > c(
> > > DataDomain.java:834)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.access.DataContext.flushToParent(DataContext.java
> > > :7
> > > 37)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.cayenne.access.DataContext.commitChanges(DataContext.java
> > > :6
> > > 86)
> > > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.oceanops.api.id.IdGenerator.commitChanges(IdGenerator.java:47)
> > > ~[classes/:?]
> > >         at
> > > org.oceanops.api.id.WebServiceManager.getID(WebServiceManager.java:5
> > > 6)
> > > ~[classes/:?]
> > >         at
> > > jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
> > > Method) ~[?:?]
> > >         at
> > > jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcc
> > > es
> > > sorImpl.java:62)
> > > ~[?:?]
> > >         at
> > > jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingM
> > > et
> > > hodAccessorImpl.java:43)
> > > ~[?:?]
> > >         at java.lang.reflect.Method.invoke(Method.java:564) ~[?:?]
> > >         at
> > > org.glassfish.jersey.server.model.internal.ResourceMethodInvocationH
> > > an
> > > dlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.j
> > > av
> > > a:52)
> > > ~[jersey-server-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.server.model.internal.AbstractJavaResourceMetho
> > > dD
> > > ispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124)
> > > [jersey-server-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.server.model.internal.AbstractJavaResourceMetho
> > > dD
> > > ispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)
> > > [jersey-server-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatc
> > > he
> > > rProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProv
> > > id
> > > er.java:219)
> > > [jersey-server-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.server.model.internal.AbstractJavaResourceMetho
> > > dD
> > > ispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
> > > [jersey-server-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(Resou
> > > rc
> > > eMethodInvoker.java:475)
> > > [jersey-server-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(Resour
> > > ce
> > > MethodInvoker.java:397)
> > > [jersey-server-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(Resour
> > > ce
> > > MethodInvoker.java:81)
> > > [jersey-server-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:2
> > > 55
> > > )
> > > [jersey-server-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
> > > [jersey-common-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
> > > [jersey-common-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.internal.Errors.process(Errors.java:292)
> > > [jersey-common-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.internal.Errors.process(Errors.java:274)
> > > [jersey-common-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.internal.Errors.process(Errors.java:244)
> > > [jersey-common-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.process.internal.RequestScope.runInScope(Reques
> > > tS
> > > cope.java:265)
> > > [jersey-common-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java
> > > :2
> > > 34)
> > > [jersey-server-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHan
> > > dl
> > > er.java:684)
> > > [jersey-server-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.j
> > > av
> > > a:394) [jersey-container-servlet-core-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:
> > > 34
> > > 6) [jersey-container-servlet-core-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.servlet.ServletContainer.service(ServletContain
> > > er
> > > .java:366)
> > > [jersey-contain[apache-tomcat-9.0.40]: er-servlet-core-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.servlet.ServletContainer.service(ServletContain
> > > er
> > > .java:319) [jersey-container-servlet-core-2.35.jar:?]
> > >         at
> > > org.glassfish.jersey.servlet.ServletContainer.service(ServletContain
> > > er
> > > .java:205) [jersey-container-servlet-core-2.35.jar:?]
> > >         at
> > > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(App
> > > li
> > > cationFilterChain.java:231)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.apache.catalina.core.ApplicationFilterChain.doFilter(Application
> > > Fi
> > > lterChain.java:166)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:5
> > > 3)
> > > [tomcat-websocket.jar:9.0.40]
> > >         at
> > > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(App
> > > li
> > > cationFilterChain.java:193)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.apache.catalina.core.ApplicationFilterChain.doFilter(Application
> > > Fi
> > > lterChain.java:166)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.oceanops.api.filters.AuthFilter.doFilter(AuthFilter.java:40)
> > > [api-1.3-SNAPSHOT-classes.jar:?]
> > >         at
> > > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(App
> > > li
> > > cationFilterChain.java:193)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.apache.catalina.core.ApplicationFilterChain.doFilter(Application
> > > Fi
> > > lterChain.java:166)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.apache.cayenne.configuration.web.CayenneFilter.doFilter(CayenneF
> > > il
> > > ter.java:127)
> > > [cayenne-web-4.2.M3.jar:4.2.M3]
> > >         at
> > > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(App
> > > li
> > > cationFilterChain.java:193)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.apache.catalina.core.ApplicationFilterChain.doFilter(Application
> > > Fi
> > > lterChain.java:166)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapper
> > > Va
> > > lve.java:202)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.apache.catalina.core.StandardContextValve.invoke(StandardContext
> > > Va
> > > lve.java:97)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.apache.catalina.authenticator.AuthenticatorBase.invoke(Authentic
> > > at
> > > orBase.java:542)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.
> > > ja
> > > va:143)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.
> > > ja
> > > va:92)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAcc
> > > es
> > > sLogValve.java:690)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVa
> > > lv
> > > e.java:78)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.ja
> > > va
> > > :343)
> > > [catalina.jar:9.0.40]
> > >         at
> > > org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:
> > > 374)
> > > [tomcat-coyote.jar:9.0.40]
> > >         at
> > > org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLi
> > > gh
> > > t.java:65)
> > > [tomcat-coyote.jar:9.0.40]
> > >         at
> > > org.apache.coyote.AbstractProtocol$ConnectionHandler.process(Abstrac
> > > tP
> > > rotocol.java:880)
> > > [tomcat-coyote.jar:9.0.40]
> > >         at
> > > org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndp
> > > oi
> > > nt.java:1601)
> > > [tomcat-coyote.jar:9.0.40]
> > >         at
> > > org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBa
> > > se
> > > .java:49)
> > > [tomcat-coyote.jar:9.0.40]
> > >         at
> > > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor
> > > .j
> > > ava:1130)
> > > [?:?]
> > >         at
> > > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.
> > > java:630)
> > > [?:?]
> > >         at
> > > org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskT
> > > hr
> > > ead.java:61)
> > > [tomcat-util.jar:9.0.40]
> > >         at java.lang.Thread.run(Thread.java:832) [?:?] Caused by:
> > > oracle.jdbc.OracleDatabaseException: ORA-02291: integrity constraint
> > > (JCOMMOPS_B.PTF_HARDWARE_FK) violated - parent key not found
> > >
> > >
> > >
> > > -----Original Message-----
> > > From: Michael Gentry <bl...@gmail.com>
> > > Sent: Thursday, November 4, 2021 7:28 PM
> > > To: Cayenne Users <us...@cayenne.apache.org>
> > > Subject: Re: Insertion order issue
> > >
> > > CAUTION: This message comes from an external server, do not click on
> > > links or open attachments unless you know the sender and are sure
> > > the content is safe.
> > >
> > >
> > > Hi Anthonin,
> > >
> > > Perhaps put a @SortWeight(2) annotation [1] on your child entity?
> > > Also, you need to configure a different entity sorter:
> > >
> > > // Need WeightedAshwoodEntitySorter for @SortWeight to work.
> > > Module        entitySorterModule = (binder) ->
> > > binder.bind(EntitySorter.class).to(WeightedAshwoodEntitySorter.class);
> > > ServerRuntime runtime            =
> > > ServerRuntimeBuilder.builder().addModule(myModule)....
> > >
> > > If this doesn't help, please provide a stack track and Cayenne
> > > version information.
> > >
> > > Thanks!
> > >
> > > mrg
> > >
> > >
> > > [1]
> > >
> > > https://cayenne.apache.org/docs/4.0/api/org/apache/cayenne/ashwood/S
> > > or
> > > tWeight.html
> > >
> > >
> > > On Thu, Nov 4, 2021 at 10:38 AM Lize Anthonin (OceanOPS) <
> > > alize@groupcls.com>
> > > wrote:
> > >
> > > > Hi,
> > > >
> > > > I am using Cayenne in a web app (through AgRest, but this is
> > > > purely cayenne related, well I think so) that contains one service
> > > > through a POST method.
> > > > Basically, I submit a JSON body with multiple object in it, pass
> > > > it through the service method defined below, process each object
> > > > and for each ones doing some insert into an Oracle DB.
> > > > @POST
> > > > @Consumes(MediaType.APPLICATION_JSON)
> > > > @Path("getid")
> > > > @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") public
> > > > List<IdResponse> getID(final List<IdInput> inputs) {
> > > >                 There I loop over this list, process the object
> > > > IdInput and make the necessary insertions }
> > > >
> > > > My issue there is that when I commit the changes, the order of the
> > > > inserts seems to fail randomly, from one request to another. I
> > > > have relationships set in those modifications, and through the
> > > > logs I can see the PK being fetched from the sequences, but then
> > > > sometimes (most of the times) the referencing entity is inserted
> > > > before the referenced entity. And of course the commit fail for
> > > > violation of
> > parent key.
> > > >
> > > > I've tried to secure as much as possible the context, through
> > > > different
> > > > ways:
> > > >
> > > >   *   stateless thread context through the provided cayenne filter
> > > > (stateless because the session one would be committed via another
> > > > commit made in another filter, weird, but I send only one request,
> > > > this filter commit should happen prior to the 'service' commit)
> > > >   *   per method context
> > > >   *   custom stateless context through a filter that I made myself.
> > > > I thought I got it with he per method context, but it failed after
> > > > a
> > > while.
> > > > And I tried committing after each processing in the loop, or after
> > > > the loop, but same results.
> > > >
> > > > I'm probably missing something, but I'm not getting why it happen
> > > > sometimes, not always(or never!). A threading issue maybe? But I'm
> > > > processing only one request, so I'm a bit lost.
> > > > Any thoughts? (before I commit after each insertion of entities
> > > > haha) How the order of inserts are defined? Maybe I
> > > > miss-configured some relationships in the modeler, but they come
> > > > from a reverse engineering and look ok...
> > > >
> > > > Many thanks in advance
> > > > Anthonin
> > > > ________________________________
> > > >
> > > > Ce message et toutes les pi?ces jointes (ci-apr?s le "message")
> > > > sont ?tablis ? l'intention exclusive de ses destinataires et sont
> > > confidentiels.
> > > > Si vous recevez ce message par erreur ou s'il ne vous est pas
> > > > destin?, merci de le d?truire ainsi que toute copie de votre
> > > > syst?me et d'en avertir imm?diatement l'exp?diteur. Toute lecture
> > > > non autoris?e, toute utilisation de ce message qui n'est pas
> conforme ?
> > > > sa destination, toute diffusion ou toute publication, totale ou
> > > > partielle, est interdite. L'Internet ne permettant pas d'assurer
> > > > l'int?grit? de ce message ?lectronique susceptible d'alt?ration,
> > > > l'exp?diteur (et ses
> > > > filiales) d?cline(nt) toute responsabilit? au titre de ce message
> > > > dans
> > > l'hypoth?se o? il aurait ?t?
> > > > modifi? ou falsifi?.
> > > >
> > > > This message and any attachments (the "message") is intended
> > > > solely for the intended recipient(s) and is confidential. If you
> > > > receive this message in error, or are not the intended
> > > > recipient(s), please delete it and any copies from your systems
> > > > and immediately notify the
> > sender.
> > > > Any unauthorized view, use that does not comply with its purpose,
> > > > dissemination or disclosure, either whole or partial, is prohibited.
> > > > Since the internet cannot guarantee the integrity of this message
> > > > which may not be reliable, the sender (and its subsidiaries) shall
> > > > not be liable for the message if modified or falsified.
> > > >
> > > ________________________________
> > >
> > > Ce message et toutes les pièces jointes (ci-après le "message") sont
> > > établis à l'intention exclusive de ses destinataires et sont
> > confidentiels.
> > > Si vous recevez ce message par erreur ou s'il ne vous est pas
> > > destiné, merci de le détruire ainsi que toute copie de votre système
> > > et d'en avertir immédiatement l'expéditeur. Toute lecture non
> > > autorisée, toute utilisation de ce message qui n'est pas conforme à
> > > sa destination, toute diffusion ou toute publication, totale ou
> > > partielle, est interdite. L'Internet ne permettant pas d'assurer
> > > l'intégrité de ce message électronique susceptible d'altération,
> > > l’expéditeur (et ses
> > > filiales) décline(nt) toute responsabilité au titre de ce message
> > > dans l'hypothèse où il aurait été modifié ou falsifié.
> > >
> > > This message and any attachments (the "message") is intended solely
> > > for the intended recipient(s) and is confidential. If you receive
> > > this message in error, or are not the intended recipient(s), please
> > > delete it and any copies from your systems and immediately notify the
> sender.
> > > Any unauthorized view, use that does not comply with its purpose,
> > > dissemination or disclosure, either whole or partial, is prohibited.
> > > Since the internet cannot guarantee the integrity of this message
> > > which may not be reliable, the sender (and its subsidiaries) shall
> > > not be liable for the message if modified or falsified.
> > >
> > ________________________________
> >
> > Ce message et toutes les pièces jointes (ci-après le "message") sont
> > établis à l'intention exclusive de ses destinataires et sont
> confidentiels.
> > Si vous recevez ce message par erreur ou s'il ne vous est pas destiné,
> > merci de le détruire ainsi que toute copie de votre système et d'en
> > avertir immédiatement l'expéditeur. Toute lecture non autorisée, toute
> > utilisation de ce message qui n'est pas conforme à sa destination,
> > toute diffusion ou toute publication, totale ou partielle, est
> > interdite. L'Internet ne permettant pas d'assurer l'intégrité de ce
> > message électronique susceptible d'altération, l’expéditeur (et ses
> > filiales) décline(nt) toute responsabilité au titre de ce message dans
> > l'hypothèse où il aurait été modifié ou falsifié.
> >
> > This message and any attachments (the "message") is intended solely
> > for the intended recipient(s) and is confidential. If you receive this
> > message in error, or are not the intended recipient(s), please delete
> > it and any copies from your systems and immediately notify the sender.
> > Any unauthorized view, use that does not comply with its purpose,
> > dissemination or disclosure, either whole or partial, is prohibited.
> > Since the internet cannot guarantee the integrity of this message
> > which may not be reliable, the sender (and its subsidiaries) shall not
> > be liable for the message if modified or falsified.
> >
> ________________________________
>
> Ce message et toutes les pièces jointes (ci-après le "message") sont
> établis à l'intention exclusive de ses destinataires et sont confidentiels.
> Si vous recevez ce message par erreur ou s'il ne vous est pas destiné,
> merci de le détruire ainsi que toute copie de votre système et d'en avertir
> immédiatement l'expéditeur. Toute lecture non autorisée, toute utilisation
> de ce message qui n'est pas conforme à sa destination, toute diffusion ou
> toute publication, totale ou partielle, est interdite. L'Internet ne
> permettant pas d'assurer l'intégrité de ce message électronique susceptible
> d'altération, l’expéditeur (et ses filiales) décline(nt) toute
> responsabilité au titre de ce message dans l'hypothèse où il aurait été
> modifié ou falsifié.
>
> This message and any attachments (the "message") is intended solely for
> the intended recipient(s) and is confidential. If you receive this message
> in error, or are not the intended recipient(s), please delete it and any
> copies from your systems and immediately notify the sender. Any
> unauthorized view, use that does not comply with its purpose, dissemination
> or disclosure, either whole or partial, is prohibited. Since the internet
> cannot guarantee the integrity of this message which may not be reliable,
> the sender (and its subsidiaries) shall not be liable for the message if
> modified or falsified.
>

RE: Insertion order issue

Posted by "Lize Anthonin (OceanOPS)" <al...@groupcls.com>.
Thanks again for spending time on this ! :)

A) yes you're right... I think I'll implement this solution and move on, I lost enough time already on this.
B) I just tried anyway, it does not change anything. I'll revert to what I had.
BTW, I also have a custom adapter modifying the SQLTreeProcessor to apply ST_AsText/ST_geomfromtext functions on ESRI SDE geometries (to which I attribute the Wkt cayenne type) and also to work around an issue being addressed in cayenne about date formatting, having consequences in AgRest (https://groups.google.com/g/agrest-user/c/MxFktjHhXGI, https://issues.apache.org/jira/browse/CAY-2700). So basically I extend the JdbcAdapter (so that I can have a date format in AgRest - input - close to the ISO one), to which I set an extended OraclePkGenerator. It's rather easy and works great thanks to the great work done regarding DI in Cayenne!
Anyway, this does not change anything to that issue.
Even if A sorts this out, I wonder why this is happening. Do you think reverse relationships can mess up the order ?(automatically generated while reverse engineering)

anthonin

-----Original Message-----
From: Michael Gentry <bl...@gmail.com>
Sent: Friday, November 5, 2021 4:35 PM
To: Cayenne Users <us...@cayenne.apache.org>
Subject: Re: Insertion order issue

CAUTION: This message comes from an external server, do not click on links or open attachments unless you know the sender and are sure the content is safe.


Hi Anthonin,

A) If my memory hasn't failed me, a DEFERRABLE/INITIALLY DEFERRED constraint is checked at the END (commit) of the transaction instead of each statement as it happens. The constraint check still happens...just deferred. If there is a constraint error at the end, Oracle will roll back the transaction and you'll get an error/exception in your code.

B) I don't think your custom PK generator will cause your current issue.
Unless, of course, there is a bug. :-) It certainly can be annoying to set the sequence name/size for each entity, so I understand wanting to avoid that.

mrg


On Fri, Nov 5, 2021 at 11:09 AM Lize Anthonin (OceanOPS) <al...@groupcls.com>
wrote:

> Hi Michael,
>
> A) I'll look into that, I have to check the potential implications first.
> I wanted to find an applicative work around before touching the DB.
> But thanks, that would solve it indeed.
> B) Just to define the sequence pattern. The default Oracle PK
> generator uses sequence like 'PK_<TABLE_NAME>'. All my sequences are
> like '<TABLE_NAME>_SEQ'. Since my model contains a lot of entities, I
> extended the OraclePkGenerator to modify the sequence naming, it was
> faster to implement. Do you think that could impact this? If so, I'll
> spend some time defining the custom sequences. I'll try on the few entities I'm working on.
>
> anthonin
>
> -----Original Message-----
> From: Michael Gentry <bl...@gmail.com>
> Sent: Friday, November 5, 2021 2:25 PM
> To: Cayenne Users <us...@cayenne.apache.org>
> Subject: Re: Insertion order issue
>
> CAUTION: This message comes from an external server, do not click on
> links or open attachments unless you know the sender and are sure the
> content is safe.
>
>
> Hi Anthonin,
>
> A) Since you are using Oracle, you may need to use a DEFERRABLE
> constraint (INITIALLY DEFERRED).
>
> B) Any reason you are using a custom PK generator instead of using the
> standard sequence generator supported by Cayenne? (Cayenne Modeler ->
> select DB Entity -> PK Generation Strategy -> Custom Sequence -> enter
> Sequence Name and Cache Size -- looks like you are using 1).
>
> mrg
>
>
> On Fri, Nov 5, 2021 at 5:44 AM Lize Anthonin (OceanOPS) <
> alize@groupcls.com>
> wrote:
>
> > Hi Michael,
> >
> > Thanks for your answer.
> > I tried, but does not seem to make any difference. I added
> > WeightedAshwoodEntitySorter (amongst other things) in a module
> > loaded as init-param for the CayenneFilter, as follows:
> > @Override
> > public void configure(Binder binder) {
> >             binder.bind(RequestHandler.class)
> >                 .to(StatelessContextRequestHandler.class)
> >                 .withoutScope();
> >
> >             OraclePkGeneratorCustom pkgen = new
> OraclePkGeneratorCustom();
> >             pkgen.setPkCacheSize(1);
> >             binder.bind(PkGenerator.class).toInstance(pkgen);
> >
> >
> > binder.bind(EntitySorter.class).to(WeightedAshwoodEntitySorter.class
> > );
> > }
> >
> > And then the annotation as you mentioned on the child entity. It
> > still stays rather random...
> >
> >
> > Here is the stack trace, as you can see I use Cayenne 4.2.M3. That
> > would have been smarter of me to share it initially!
> > java.sql.SQLIntegrityConstraintViolationException: ORA-02291:
> > integrity constraint (JCOMMOPS_B.PTF_HARDWARE_FK) violated - parent
> > key not found
> >
> >         at
> > oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:509)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:461)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1104)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:553)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:269)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:655)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement
> > .j
> > ava:270)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement
> > .j
> > ava:91)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedSt
> > at
> > ement.java:970)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatem
> > en
> > t.java:1205)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePre
> > pa
> > redStatement.java:3666)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.T4CPreparedStatement.executeInternal(T4CPreparedS
> > ta
> > tement.java:1426)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.OraclePreparedStatement.executeLargeUpdate(Oracle
> > Pr
> > eparedStatement.java:3756)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePrepa
> > re
> > dStatement.java:3736)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(Orac
> > le
> > PreparedStatementWrapper.java:1063)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeUpda
> > te
> > (DelegatingPreparedStatement.java:136)
> > ~[tomcat-dbcp.jar:9.0.40]
> >         at
> > org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeUpda
> > te
> > (DelegatingPreparedStatement.java:136)
> > ~[tomcat-dbcp.jar:9.0.40]
> >         at
> > org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(Ba
> > tc
> > hAction.java:185)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.jdbc.BatchAction.performAction(BatchAction
> > .j
> > ava:96)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataNodeQueryAction.runQuery(DataNodeQuery
> > Ac
> > tion.java:97)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$
> > ex
> > ecuteQueries$6(DefaultDataDomainFlushAction.java:177)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at java.util.HashMap.forEach(HashMap.java:1425) ~[?:?]
> >         at
> > org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.execute
> > Qu
> > eries(DefaultDataDomainFlushAction.java:176)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(D
> > ef
> > aultDataDomainFlushAction.java:89)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637
> > )
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataDomain.onSyncNoFilters(DataDomain.java
> > :6
> > 09)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSyn
> > c(
> > DataDomain.java:835)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(TransactionF
> > il
> > ter.java:61)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandl
> > er
> > .performInTransaction(DefaultTransactionManager.java:180)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandl
> > er
> > .performInNewTransaction(DefaultTransactionManager.java:152)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHan
> > dl
> > er.handle(DefaultTransactionManager.java:95)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction
> > (D
> > efaultTransactionManager.java:62)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction
> > (D
> > efaultTransactionManager.java:40)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.tx.TransactionFilter.onSync(TransactionFilter.java:
> > 61)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSyn
> > c(
> > DataDomain.java:834)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataContext.flushToParent(DataContext.java
> > :7
> > 37)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataContext.commitChanges(DataContext.java
> > :6
> > 86)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.oceanops.api.id.IdGenerator.commitChanges(IdGenerator.java:47)
> > ~[classes/:?]
> >         at
> > org.oceanops.api.id.WebServiceManager.getID(WebServiceManager.java:5
> > 6)
> > ~[classes/:?]
> >         at
> > jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
> > Method) ~[?:?]
> >         at
> > jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcc
> > es
> > sorImpl.java:62)
> > ~[?:?]
> >         at
> > jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingM
> > et
> > hodAccessorImpl.java:43)
> > ~[?:?]
> >         at java.lang.reflect.Method.invoke(Method.java:564) ~[?:?]
> >         at
> > org.glassfish.jersey.server.model.internal.ResourceMethodInvocationH
> > an
> > dlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.j
> > av
> > a:52)
> > ~[jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.model.internal.AbstractJavaResourceMetho
> > dD
> > ispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.model.internal.AbstractJavaResourceMetho
> > dD
> > ispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatc
> > he
> > rProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProv
> > id
> > er.java:219)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.model.internal.AbstractJavaResourceMetho
> > dD
> > ispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(Resou
> > rc
> > eMethodInvoker.java:475)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(Resour
> > ce
> > MethodInvoker.java:397)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(Resour
> > ce
> > MethodInvoker.java:81)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:2
> > 55
> > )
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
> > [jersey-common-2.35.jar:?]
> >         at
> > org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
> > [jersey-common-2.35.jar:?]
> >         at
> > org.glassfish.jersey.internal.Errors.process(Errors.java:292)
> > [jersey-common-2.35.jar:?]
> >         at
> > org.glassfish.jersey.internal.Errors.process(Errors.java:274)
> > [jersey-common-2.35.jar:?]
> >         at
> > org.glassfish.jersey.internal.Errors.process(Errors.java:244)
> > [jersey-common-2.35.jar:?]
> >         at
> > org.glassfish.jersey.process.internal.RequestScope.runInScope(Reques
> > tS
> > cope.java:265)
> > [jersey-common-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java
> > :2
> > 34)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHan
> > dl
> > er.java:684)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.j
> > av
> > a:394) [jersey-container-servlet-core-2.35.jar:?]
> >         at
> > org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:
> > 34
> > 6) [jersey-container-servlet-core-2.35.jar:?]
> >         at
> > org.glassfish.jersey.servlet.ServletContainer.service(ServletContain
> > er
> > .java:366)
> > [jersey-contain[apache-tomcat-9.0.40]: er-servlet-core-2.35.jar:?]
> >         at
> > org.glassfish.jersey.servlet.ServletContainer.service(ServletContain
> > er
> > .java:319) [jersey-container-servlet-core-2.35.jar:?]
> >         at
> > org.glassfish.jersey.servlet.ServletContainer.service(ServletContain
> > er
> > .java:205) [jersey-container-servlet-core-2.35.jar:?]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(App
> > li
> > cationFilterChain.java:231)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.doFilter(Application
> > Fi
> > lterChain.java:166)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:5
> > 3)
> > [tomcat-websocket.jar:9.0.40]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(App
> > li
> > cationFilterChain.java:193)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.doFilter(Application
> > Fi
> > lterChain.java:166)
> > [catalina.jar:9.0.40]
> >         at
> > org.oceanops.api.filters.AuthFilter.doFilter(AuthFilter.java:40)
> > [api-1.3-SNAPSHOT-classes.jar:?]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(App
> > li
> > cationFilterChain.java:193)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.doFilter(Application
> > Fi
> > lterChain.java:166)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.cayenne.configuration.web.CayenneFilter.doFilter(CayenneF
> > il
> > ter.java:127)
> > [cayenne-web-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(App
> > li
> > cationFilterChain.java:193)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.doFilter(Application
> > Fi
> > lterChain.java:166)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapper
> > Va
> > lve.java:202)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.StandardContextValve.invoke(StandardContext
> > Va
> > lve.java:97)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.authenticator.AuthenticatorBase.invoke(Authentic
> > at
> > orBase.java:542)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.
> > ja
> > va:143)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.
> > ja
> > va:92)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAcc
> > es
> > sLogValve.java:690)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVa
> > lv
> > e.java:78)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.ja
> > va
> > :343)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:
> > 374)
> > [tomcat-coyote.jar:9.0.40]
> >         at
> > org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLi
> > gh
> > t.java:65)
> > [tomcat-coyote.jar:9.0.40]
> >         at
> > org.apache.coyote.AbstractProtocol$ConnectionHandler.process(Abstrac
> > tP
> > rotocol.java:880)
> > [tomcat-coyote.jar:9.0.40]
> >         at
> > org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndp
> > oi
> > nt.java:1601)
> > [tomcat-coyote.jar:9.0.40]
> >         at
> > org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBa
> > se
> > .java:49)
> > [tomcat-coyote.jar:9.0.40]
> >         at
> > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor
> > .j
> > ava:1130)
> > [?:?]
> >         at
> > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.
> > java:630)
> > [?:?]
> >         at
> > org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskT
> > hr
> > ead.java:61)
> > [tomcat-util.jar:9.0.40]
> >         at java.lang.Thread.run(Thread.java:832) [?:?] Caused by:
> > oracle.jdbc.OracleDatabaseException: ORA-02291: integrity constraint
> > (JCOMMOPS_B.PTF_HARDWARE_FK) violated - parent key not found
> >
> >
> >
> > -----Original Message-----
> > From: Michael Gentry <bl...@gmail.com>
> > Sent: Thursday, November 4, 2021 7:28 PM
> > To: Cayenne Users <us...@cayenne.apache.org>
> > Subject: Re: Insertion order issue
> >
> > CAUTION: This message comes from an external server, do not click on
> > links or open attachments unless you know the sender and are sure
> > the content is safe.
> >
> >
> > Hi Anthonin,
> >
> > Perhaps put a @SortWeight(2) annotation [1] on your child entity?
> > Also, you need to configure a different entity sorter:
> >
> > // Need WeightedAshwoodEntitySorter for @SortWeight to work.
> > Module        entitySorterModule = (binder) ->
> > binder.bind(EntitySorter.class).to(WeightedAshwoodEntitySorter.class);
> > ServerRuntime runtime            =
> > ServerRuntimeBuilder.builder().addModule(myModule)....
> >
> > If this doesn't help, please provide a stack track and Cayenne
> > version information.
> >
> > Thanks!
> >
> > mrg
> >
> >
> > [1]
> >
> > https://cayenne.apache.org/docs/4.0/api/org/apache/cayenne/ashwood/S
> > or
> > tWeight.html
> >
> >
> > On Thu, Nov 4, 2021 at 10:38 AM Lize Anthonin (OceanOPS) <
> > alize@groupcls.com>
> > wrote:
> >
> > > Hi,
> > >
> > > I am using Cayenne in a web app (through AgRest, but this is
> > > purely cayenne related, well I think so) that contains one service
> > > through a POST method.
> > > Basically, I submit a JSON body with multiple object in it, pass
> > > it through the service method defined below, process each object
> > > and for each ones doing some insert into an Oracle DB.
> > > @POST
> > > @Consumes(MediaType.APPLICATION_JSON)
> > > @Path("getid")
> > > @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") public
> > > List<IdResponse> getID(final List<IdInput> inputs) {
> > >                 There I loop over this list, process the object
> > > IdInput and make the necessary insertions }
> > >
> > > My issue there is that when I commit the changes, the order of the
> > > inserts seems to fail randomly, from one request to another. I
> > > have relationships set in those modifications, and through the
> > > logs I can see the PK being fetched from the sequences, but then
> > > sometimes (most of the times) the referencing entity is inserted
> > > before the referenced entity. And of course the commit fail for
> > > violation of
> parent key.
> > >
> > > I've tried to secure as much as possible the context, through
> > > different
> > > ways:
> > >
> > >   *   stateless thread context through the provided cayenne filter
> > > (stateless because the session one would be committed via another
> > > commit made in another filter, weird, but I send only one request,
> > > this filter commit should happen prior to the 'service' commit)
> > >   *   per method context
> > >   *   custom stateless context through a filter that I made myself.
> > > I thought I got it with he per method context, but it failed after
> > > a
> > while.
> > > And I tried committing after each processing in the loop, or after
> > > the loop, but same results.
> > >
> > > I'm probably missing something, but I'm not getting why it happen
> > > sometimes, not always(or never!). A threading issue maybe? But I'm
> > > processing only one request, so I'm a bit lost.
> > > Any thoughts? (before I commit after each insertion of entities
> > > haha) How the order of inserts are defined? Maybe I
> > > miss-configured some relationships in the modeler, but they come
> > > from a reverse engineering and look ok...
> > >
> > > Many thanks in advance
> > > Anthonin
> > > ________________________________
> > >
> > > Ce message et toutes les pi?ces jointes (ci-apr?s le "message")
> > > sont ?tablis ? l'intention exclusive de ses destinataires et sont
> > confidentiels.
> > > Si vous recevez ce message par erreur ou s'il ne vous est pas
> > > destin?, merci de le d?truire ainsi que toute copie de votre
> > > syst?me et d'en avertir imm?diatement l'exp?diteur. Toute lecture
> > > non autoris?e, toute utilisation de ce message qui n'est pas conforme ?
> > > sa destination, toute diffusion ou toute publication, totale ou
> > > partielle, est interdite. L'Internet ne permettant pas d'assurer
> > > l'int?grit? de ce message ?lectronique susceptible d'alt?ration,
> > > l'exp?diteur (et ses
> > > filiales) d?cline(nt) toute responsabilit? au titre de ce message
> > > dans
> > l'hypoth?se o? il aurait ?t?
> > > modifi? ou falsifi?.
> > >
> > > This message and any attachments (the "message") is intended
> > > solely for the intended recipient(s) and is confidential. If you
> > > receive this message in error, or are not the intended
> > > recipient(s), please delete it and any copies from your systems
> > > and immediately notify the
> sender.
> > > Any unauthorized view, use that does not comply with its purpose,
> > > dissemination or disclosure, either whole or partial, is prohibited.
> > > Since the internet cannot guarantee the integrity of this message
> > > which may not be reliable, the sender (and its subsidiaries) shall
> > > not be liable for the message if modified or falsified.
> > >
> > ________________________________
> >
> > Ce message et toutes les pièces jointes (ci-après le "message") sont
> > établis à l'intention exclusive de ses destinataires et sont
> confidentiels.
> > Si vous recevez ce message par erreur ou s'il ne vous est pas
> > destiné, merci de le détruire ainsi que toute copie de votre système
> > et d'en avertir immédiatement l'expéditeur. Toute lecture non
> > autorisée, toute utilisation de ce message qui n'est pas conforme à
> > sa destination, toute diffusion ou toute publication, totale ou
> > partielle, est interdite. L'Internet ne permettant pas d'assurer
> > l'intégrité de ce message électronique susceptible d'altération,
> > l’expéditeur (et ses
> > filiales) décline(nt) toute responsabilité au titre de ce message
> > dans l'hypothèse où il aurait été modifié ou falsifié.
> >
> > This message and any attachments (the "message") is intended solely
> > for the intended recipient(s) and is confidential. If you receive
> > this message in error, or are not the intended recipient(s), please
> > delete it and any copies from your systems and immediately notify the sender.
> > Any unauthorized view, use that does not comply with its purpose,
> > dissemination or disclosure, either whole or partial, is prohibited.
> > Since the internet cannot guarantee the integrity of this message
> > which may not be reliable, the sender (and its subsidiaries) shall
> > not be liable for the message if modified or falsified.
> >
> ________________________________
>
> Ce message et toutes les pièces jointes (ci-après le "message") sont
> établis à l'intention exclusive de ses destinataires et sont confidentiels.
> Si vous recevez ce message par erreur ou s'il ne vous est pas destiné,
> merci de le détruire ainsi que toute copie de votre système et d'en
> avertir immédiatement l'expéditeur. Toute lecture non autorisée, toute
> utilisation de ce message qui n'est pas conforme à sa destination,
> toute diffusion ou toute publication, totale ou partielle, est
> interdite. L'Internet ne permettant pas d'assurer l'intégrité de ce
> message électronique susceptible d'altération, l’expéditeur (et ses
> filiales) décline(nt) toute responsabilité au titre de ce message dans
> l'hypothèse où il aurait été modifié ou falsifié.
>
> This message and any attachments (the "message") is intended solely
> for the intended recipient(s) and is confidential. If you receive this
> message in error, or are not the intended recipient(s), please delete
> it and any copies from your systems and immediately notify the sender.
> Any unauthorized view, use that does not comply with its purpose,
> dissemination or disclosure, either whole or partial, is prohibited.
> Since the internet cannot guarantee the integrity of this message
> which may not be reliable, the sender (and its subsidiaries) shall not
> be liable for the message if modified or falsified.
>
________________________________

Ce message et toutes les pièces jointes (ci-après le "message") sont établis à l'intention exclusive de ses destinataires et sont confidentiels. Si vous recevez ce message par erreur ou s'il ne vous est pas destiné, merci de le détruire ainsi que toute copie de votre système et d'en avertir immédiatement l'expéditeur. Toute lecture non autorisée, toute utilisation de ce message qui n'est pas conforme à sa destination, toute diffusion ou toute publication, totale ou partielle, est interdite. L'Internet ne permettant pas d'assurer l'intégrité de ce message électronique susceptible d'altération, l’expéditeur (et ses filiales) décline(nt) toute responsabilité au titre de ce message dans l'hypothèse où il aurait été modifié ou falsifié.

This message and any attachments (the "message") is intended solely for the intended recipient(s) and is confidential. If you receive this message in error, or are not the intended recipient(s), please delete it and any copies from your systems and immediately notify the sender. Any unauthorized view, use that does not comply with its purpose, dissemination or disclosure, either whole or partial, is prohibited. Since the internet cannot guarantee the integrity of this message which may not be reliable, the sender (and its subsidiaries) shall not be liable for the message if modified or falsified.

Re: Insertion order issue

Posted by Michael Gentry <bl...@gmail.com>.
Hi Anthonin,

A) If my memory hasn't failed me, a DEFERRABLE/INITIALLY DEFERRED
constraint is checked at the END (commit) of the transaction instead of
each statement as it happens. The constraint check still happens...just
deferred. If there is a constraint error at the end, Oracle will roll back
the transaction and you'll get an error/exception in your code.

B) I don't think your custom PK generator will cause your current issue.
Unless, of course, there is a bug. :-) It certainly can be annoying to set
the sequence name/size for each entity, so I understand wanting to avoid
that.

mrg


On Fri, Nov 5, 2021 at 11:09 AM Lize Anthonin (OceanOPS) <al...@groupcls.com>
wrote:

> Hi Michael,
>
> A) I'll look into that, I have to check the potential implications first.
> I wanted to find an applicative work around before touching the DB. But
> thanks, that would solve it indeed.
> B) Just to define the sequence pattern. The default Oracle PK generator
> uses sequence like 'PK_<TABLE_NAME>'. All my sequences are like
> '<TABLE_NAME>_SEQ'. Since my model contains a lot of entities, I extended
> the OraclePkGenerator to modify the sequence naming, it was faster to
> implement. Do you think that could impact this? If so, I'll spend some time
> defining the custom sequences. I'll try on the few entities I'm working on.
>
> anthonin
>
> -----Original Message-----
> From: Michael Gentry <bl...@gmail.com>
> Sent: Friday, November 5, 2021 2:25 PM
> To: Cayenne Users <us...@cayenne.apache.org>
> Subject: Re: Insertion order issue
>
> CAUTION: This message comes from an external server, do not click on links
> or open attachments unless you know the sender and are sure the content is
> safe.
>
>
> Hi Anthonin,
>
> A) Since you are using Oracle, you may need to use a DEFERRABLE constraint
> (INITIALLY DEFERRED).
>
> B) Any reason you are using a custom PK generator instead of using the
> standard sequence generator supported by Cayenne? (Cayenne Modeler ->
> select DB Entity -> PK Generation Strategy -> Custom Sequence -> enter
> Sequence Name and Cache Size -- looks like you are using 1).
>
> mrg
>
>
> On Fri, Nov 5, 2021 at 5:44 AM Lize Anthonin (OceanOPS) <
> alize@groupcls.com>
> wrote:
>
> > Hi Michael,
> >
> > Thanks for your answer.
> > I tried, but does not seem to make any difference. I added
> > WeightedAshwoodEntitySorter (amongst other things) in a module loaded
> > as init-param for the CayenneFilter, as follows:
> > @Override
> > public void configure(Binder binder) {
> >             binder.bind(RequestHandler.class)
> >                 .to(StatelessContextRequestHandler.class)
> >                 .withoutScope();
> >
> >             OraclePkGeneratorCustom pkgen = new
> OraclePkGeneratorCustom();
> >             pkgen.setPkCacheSize(1);
> >             binder.bind(PkGenerator.class).toInstance(pkgen);
> >
> >
> > binder.bind(EntitySorter.class).to(WeightedAshwoodEntitySorter.class);
> > }
> >
> > And then the annotation as you mentioned on the child entity. It still
> > stays rather random...
> >
> >
> > Here is the stack trace, as you can see I use Cayenne 4.2.M3. That
> > would have been smarter of me to share it initially!
> > java.sql.SQLIntegrityConstraintViolationException: ORA-02291:
> > integrity constraint (JCOMMOPS_B.PTF_HARDWARE_FK) violated - parent
> > key not found
> >
> >         at
> > oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:509)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:461)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1104)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:553)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:269)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:655)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.j
> > ava:270)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.j
> > ava:91)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStat
> > ement.java:970)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatemen
> > t.java:1205)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePrepa
> > redStatement.java:3666)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.T4CPreparedStatement.executeInternal(T4CPreparedSta
> > tement.java:1426)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.OraclePreparedStatement.executeLargeUpdate(OraclePr
> > eparedStatement.java:3756)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePrepare
> > dStatement.java:3736)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(Oracle
> > PreparedStatementWrapper.java:1063)
> > ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
> >         at
> > org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeUpdate
> > (DelegatingPreparedStatement.java:136)
> > ~[tomcat-dbcp.jar:9.0.40]
> >         at
> > org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeUpdate
> > (DelegatingPreparedStatement.java:136)
> > ~[tomcat-dbcp.jar:9.0.40]
> >         at
> > org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(Batc
> > hAction.java:185)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.jdbc.BatchAction.performAction(BatchAction.j
> > ava:96)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataNodeQueryAction.runQuery(DataNodeQueryAc
> > tion.java:97)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$ex
> > ecuteQueries$6(DefaultDataDomainFlushAction.java:177)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at java.util.HashMap.forEach(HashMap.java:1425) ~[?:?]
> >         at
> > org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQu
> > eries(DefaultDataDomainFlushAction.java:176)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(Def
> > aultDataDomainFlushAction.java:89)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataDomain.onSyncNoFilters(DataDomain.java:6
> > 09)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > DataDomain.java:835)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(TransactionFil
> > ter.java:61)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler
> > .performInTransaction(DefaultTransactionManager.java:180)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler
> > .performInNewTransaction(DefaultTransactionManager.java:152)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandl
> > er.handle(DefaultTransactionManager.java:95)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(D
> > efaultTransactionManager.java:62)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(D
> > efaultTransactionManager.java:40)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.tx.TransactionFilter.onSync(TransactionFilter.java:
> > 61)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > DataDomain.java:834)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:7
> > 37)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:6
> > 86)
> > ~[cayenne-server-4.2.M3.jar:4.2.M3]
> >         at
> > org.oceanops.api.id.IdGenerator.commitChanges(IdGenerator.java:47)
> > ~[classes/:?]
> >         at
> > org.oceanops.api.id.WebServiceManager.getID(WebServiceManager.java:56)
> > ~[classes/:?]
> >         at
> > jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
> > Method) ~[?:?]
> >         at
> > jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcces
> > sorImpl.java:62)
> > ~[?:?]
> >         at
> > jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMet
> > hodAccessorImpl.java:43)
> > ~[?:?]
> >         at java.lang.reflect.Method.invoke(Method.java:564) ~[?:?]
> >         at
> > org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHan
> > dlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.jav
> > a:52)
> > ~[jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodD
> > ispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodD
> > ispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatche
> > rProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvid
> > er.java:219)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodD
> > ispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(Resourc
> > eMethodInvoker.java:475)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(Resource
> > MethodInvoker.java:397)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(Resource
> > MethodInvoker.java:81)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:255
> > )
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
> > [jersey-common-2.35.jar:?]
> >         at
> > org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
> > [jersey-common-2.35.jar:?]
> >         at
> > org.glassfish.jersey.internal.Errors.process(Errors.java:292)
> > [jersey-common-2.35.jar:?]
> >         at
> > org.glassfish.jersey.internal.Errors.process(Errors.java:274)
> > [jersey-common-2.35.jar:?]
> >         at
> > org.glassfish.jersey.internal.Errors.process(Errors.java:244)
> > [jersey-common-2.35.jar:?]
> >         at
> > org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestS
> > cope.java:265)
> > [jersey-common-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:2
> > 34)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandl
> > er.java:684)
> > [jersey-server-2.35.jar:?]
> >         at
> > org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.jav
> > a:394) [jersey-container-servlet-core-2.35.jar:?]
> >         at
> > org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:34
> > 6) [jersey-container-servlet-core-2.35.jar:?]
> >         at
> > org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer
> > .java:366)
> > [jersey-contain[apache-tomcat-9.0.40]: er-servlet-core-2.35.jar:?]
> >         at
> > org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer
> > .java:319) [jersey-container-servlet-core-2.35.jar:?]
> >         at
> > org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer
> > .java:205) [jersey-container-servlet-core-2.35.jar:?]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appli
> > cationFilterChain.java:231)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFi
> > lterChain.java:166)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
> > [tomcat-websocket.jar:9.0.40]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appli
> > cationFilterChain.java:193)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFi
> > lterChain.java:166)
> > [catalina.jar:9.0.40]
> >         at
> > org.oceanops.api.filters.AuthFilter.doFilter(AuthFilter.java:40)
> > [api-1.3-SNAPSHOT-classes.jar:?]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appli
> > cationFilterChain.java:193)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFi
> > lterChain.java:166)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.cayenne.configuration.web.CayenneFilter.doFilter(CayenneFil
> > ter.java:127)
> > [cayenne-web-4.2.M3.jar:4.2.M3]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appli
> > cationFilterChain.java:193)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFi
> > lterChain.java:166)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperVa
> > lve.java:202)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.StandardContextValve.invoke(StandardContextVa
> > lve.java:97)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.authenticator.AuthenticatorBase.invoke(Authenticat
> > orBase.java:542)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.ja
> > va:143)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.ja
> > va:92)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAcces
> > sLogValve.java:690)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValv
> > e.java:78)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java
> > :343)
> > [catalina.jar:9.0.40]
> >         at
> > org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:
> > 374)
> > [tomcat-coyote.jar:9.0.40]
> >         at
> > org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLigh
> > t.java:65)
> > [tomcat-coyote.jar:9.0.40]
> >         at
> > org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractP
> > rotocol.java:880)
> > [tomcat-coyote.jar:9.0.40]
> >         at
> > org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoi
> > nt.java:1601)
> > [tomcat-coyote.jar:9.0.40]
> >         at
> > org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase
> > .java:49)
> > [tomcat-coyote.jar:9.0.40]
> >         at
> > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.j
> > ava:1130)
> > [?:?]
> >         at
> > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.
> > java:630)
> > [?:?]
> >         at
> > org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThr
> > ead.java:61)
> > [tomcat-util.jar:9.0.40]
> >         at java.lang.Thread.run(Thread.java:832) [?:?] Caused by:
> > oracle.jdbc.OracleDatabaseException: ORA-02291: integrity constraint
> > (JCOMMOPS_B.PTF_HARDWARE_FK) violated - parent key not found
> >
> >
> >
> > -----Original Message-----
> > From: Michael Gentry <bl...@gmail.com>
> > Sent: Thursday, November 4, 2021 7:28 PM
> > To: Cayenne Users <us...@cayenne.apache.org>
> > Subject: Re: Insertion order issue
> >
> > CAUTION: This message comes from an external server, do not click on
> > links or open attachments unless you know the sender and are sure the
> > content is safe.
> >
> >
> > Hi Anthonin,
> >
> > Perhaps put a @SortWeight(2) annotation [1] on your child entity?
> > Also, you need to configure a different entity sorter:
> >
> > // Need WeightedAshwoodEntitySorter for @SortWeight to work.
> > Module        entitySorterModule = (binder) ->
> > binder.bind(EntitySorter.class).to(WeightedAshwoodEntitySorter.class);
> > ServerRuntime runtime            =
> > ServerRuntimeBuilder.builder().addModule(myModule)....
> >
> > If this doesn't help, please provide a stack track and Cayenne version
> > information.
> >
> > Thanks!
> >
> > mrg
> >
> >
> > [1]
> >
> > https://cayenne.apache.org/docs/4.0/api/org/apache/cayenne/ashwood/Sor
> > tWeight.html
> >
> >
> > On Thu, Nov 4, 2021 at 10:38 AM Lize Anthonin (OceanOPS) <
> > alize@groupcls.com>
> > wrote:
> >
> > > Hi,
> > >
> > > I am using Cayenne in a web app (through AgRest, but this is purely
> > > cayenne related, well I think so) that contains one service through
> > > a POST method.
> > > Basically, I submit a JSON body with multiple object in it, pass it
> > > through the service method defined below, process each object and
> > > for each ones doing some insert into an Oracle DB.
> > > @POST
> > > @Consumes(MediaType.APPLICATION_JSON)
> > > @Path("getid")
> > > @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") public
> > > List<IdResponse> getID(final List<IdInput> inputs) {
> > >                 There I loop over this list, process the object
> > > IdInput and make the necessary insertions }
> > >
> > > My issue there is that when I commit the changes, the order of the
> > > inserts seems to fail randomly, from one request to another. I have
> > > relationships set in those modifications, and through the logs I can
> > > see the PK being fetched from the sequences, but then sometimes
> > > (most of the times) the referencing entity is inserted before the
> > > referenced entity. And of course the commit fail for violation of
> parent key.
> > >
> > > I've tried to secure as much as possible the context, through
> > > different
> > > ways:
> > >
> > >   *   stateless thread context through the provided cayenne filter
> > > (stateless because the session one would be committed via another
> > > commit made in another filter, weird, but I send only one request,
> > > this filter commit should happen prior to the 'service' commit)
> > >   *   per method context
> > >   *   custom stateless context through a filter that I made myself.
> > > I thought I got it with he per method context, but it failed after a
> > while.
> > > And I tried committing after each processing in the loop, or after
> > > the loop, but same results.
> > >
> > > I'm probably missing something, but I'm not getting why it happen
> > > sometimes, not always(or never!). A threading issue maybe? But I'm
> > > processing only one request, so I'm a bit lost.
> > > Any thoughts? (before I commit after each insertion of entities
> > > haha) How the order of inserts are defined? Maybe I miss-configured
> > > some relationships in the modeler, but they come from a reverse
> > > engineering and look ok...
> > >
> > > Many thanks in advance
> > > Anthonin
> > > ________________________________
> > >
> > > Ce message et toutes les pi?ces jointes (ci-apr?s le "message") sont
> > > ?tablis ? l'intention exclusive de ses destinataires et sont
> > confidentiels.
> > > Si vous recevez ce message par erreur ou s'il ne vous est pas
> > > destin?, merci de le d?truire ainsi que toute copie de votre syst?me
> > > et d'en avertir imm?diatement l'exp?diteur. Toute lecture non
> > > autoris?e, toute utilisation de ce message qui n'est pas conforme ?
> > > sa destination, toute diffusion ou toute publication, totale ou
> > > partielle, est interdite. L'Internet ne permettant pas d'assurer
> > > l'int?grit? de ce message ?lectronique susceptible d'alt?ration,
> > > l'exp?diteur (et ses
> > > filiales) d?cline(nt) toute responsabilit? au titre de ce message
> > > dans
> > l'hypoth?se o? il aurait ?t?
> > > modifi? ou falsifi?.
> > >
> > > This message and any attachments (the "message") is intended solely
> > > for the intended recipient(s) and is confidential. If you receive
> > > this message in error, or are not the intended recipient(s), please
> > > delete it and any copies from your systems and immediately notify the
> sender.
> > > Any unauthorized view, use that does not comply with its purpose,
> > > dissemination or disclosure, either whole or partial, is prohibited.
> > > Since the internet cannot guarantee the integrity of this message
> > > which may not be reliable, the sender (and its subsidiaries) shall
> > > not be liable for the message if modified or falsified.
> > >
> > ________________________________
> >
> > Ce message et toutes les pièces jointes (ci-après le "message") sont
> > établis à l'intention exclusive de ses destinataires et sont
> confidentiels.
> > Si vous recevez ce message par erreur ou s'il ne vous est pas destiné,
> > merci de le détruire ainsi que toute copie de votre système et d'en
> > avertir immédiatement l'expéditeur. Toute lecture non autorisée, toute
> > utilisation de ce message qui n'est pas conforme à sa destination,
> > toute diffusion ou toute publication, totale ou partielle, est
> > interdite. L'Internet ne permettant pas d'assurer l'intégrité de ce
> > message électronique susceptible d'altération, l’expéditeur (et ses
> > filiales) décline(nt) toute responsabilité au titre de ce message dans
> > l'hypothèse où il aurait été modifié ou falsifié.
> >
> > This message and any attachments (the "message") is intended solely
> > for the intended recipient(s) and is confidential. If you receive this
> > message in error, or are not the intended recipient(s), please delete
> > it and any copies from your systems and immediately notify the sender.
> > Any unauthorized view, use that does not comply with its purpose,
> > dissemination or disclosure, either whole or partial, is prohibited.
> > Since the internet cannot guarantee the integrity of this message
> > which may not be reliable, the sender (and its subsidiaries) shall not
> > be liable for the message if modified or falsified.
> >
> ________________________________
>
> Ce message et toutes les pièces jointes (ci-après le "message") sont
> établis à l'intention exclusive de ses destinataires et sont confidentiels.
> Si vous recevez ce message par erreur ou s'il ne vous est pas destiné,
> merci de le détruire ainsi que toute copie de votre système et d'en avertir
> immédiatement l'expéditeur. Toute lecture non autorisée, toute utilisation
> de ce message qui n'est pas conforme à sa destination, toute diffusion ou
> toute publication, totale ou partielle, est interdite. L'Internet ne
> permettant pas d'assurer l'intégrité de ce message électronique susceptible
> d'altération, l’expéditeur (et ses filiales) décline(nt) toute
> responsabilité au titre de ce message dans l'hypothèse où il aurait été
> modifié ou falsifié.
>
> This message and any attachments (the "message") is intended solely for
> the intended recipient(s) and is confidential. If you receive this message
> in error, or are not the intended recipient(s), please delete it and any
> copies from your systems and immediately notify the sender. Any
> unauthorized view, use that does not comply with its purpose, dissemination
> or disclosure, either whole or partial, is prohibited. Since the internet
> cannot guarantee the integrity of this message which may not be reliable,
> the sender (and its subsidiaries) shall not be liable for the message if
> modified or falsified.
>

RE: Insertion order issue

Posted by "Lize Anthonin (OceanOPS)" <al...@groupcls.com>.
Hi Michael,

A) I'll look into that, I have to check the potential implications first. I wanted to find an applicative work around before touching the DB. But thanks, that would solve it indeed.
B) Just to define the sequence pattern. The default Oracle PK generator uses sequence like 'PK_<TABLE_NAME>'. All my sequences are like '<TABLE_NAME>_SEQ'. Since my model contains a lot of entities, I extended the OraclePkGenerator to modify the sequence naming, it was faster to implement. Do you think that could impact this? If so, I'll spend some time defining the custom sequences. I'll try on the few entities I'm working on.

anthonin

-----Original Message-----
From: Michael Gentry <bl...@gmail.com>
Sent: Friday, November 5, 2021 2:25 PM
To: Cayenne Users <us...@cayenne.apache.org>
Subject: Re: Insertion order issue

CAUTION: This message comes from an external server, do not click on links or open attachments unless you know the sender and are sure the content is safe.


Hi Anthonin,

A) Since you are using Oracle, you may need to use a DEFERRABLE constraint (INITIALLY DEFERRED).

B) Any reason you are using a custom PK generator instead of using the standard sequence generator supported by Cayenne? (Cayenne Modeler -> select DB Entity -> PK Generation Strategy -> Custom Sequence -> enter Sequence Name and Cache Size -- looks like you are using 1).

mrg


On Fri, Nov 5, 2021 at 5:44 AM Lize Anthonin (OceanOPS) <al...@groupcls.com>
wrote:

> Hi Michael,
>
> Thanks for your answer.
> I tried, but does not seem to make any difference. I added
> WeightedAshwoodEntitySorter (amongst other things) in a module loaded
> as init-param for the CayenneFilter, as follows:
> @Override
> public void configure(Binder binder) {
>             binder.bind(RequestHandler.class)
>                 .to(StatelessContextRequestHandler.class)
>                 .withoutScope();
>
>             OraclePkGeneratorCustom pkgen = new OraclePkGeneratorCustom();
>             pkgen.setPkCacheSize(1);
>             binder.bind(PkGenerator.class).toInstance(pkgen);
>
>
> binder.bind(EntitySorter.class).to(WeightedAshwoodEntitySorter.class);
> }
>
> And then the annotation as you mentioned on the child entity. It still
> stays rather random...
>
>
> Here is the stack trace, as you can see I use Cayenne 4.2.M3. That
> would have been smarter of me to share it initially!
> java.sql.SQLIntegrityConstraintViolationException: ORA-02291:
> integrity constraint (JCOMMOPS_B.PTF_HARDWARE_FK) violated - parent
> key not found
>
>         at
> oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:509)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:461)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1104)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:553)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:269)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:655)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.j
> ava:270)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.j
> ava:91)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStat
> ement.java:970)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatemen
> t.java:1205)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePrepa
> redStatement.java:3666)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.T4CPreparedStatement.executeInternal(T4CPreparedSta
> tement.java:1426)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.OraclePreparedStatement.executeLargeUpdate(OraclePr
> eparedStatement.java:3756)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePrepare
> dStatement.java:3736)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(Oracle
> PreparedStatementWrapper.java:1063)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeUpdate
> (DelegatingPreparedStatement.java:136)
> ~[tomcat-dbcp.jar:9.0.40]
>         at
> org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeUpdate
> (DelegatingPreparedStatement.java:136)
> ~[tomcat-dbcp.jar:9.0.40]
>         at
> org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(Batc
> hAction.java:185)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.jdbc.BatchAction.performAction(BatchAction.j
> ava:96)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataNodeQueryAction.runQuery(DataNodeQueryAc
> tion.java:97)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$ex
> ecuteQueries$6(DefaultDataDomainFlushAction.java:177)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at java.util.HashMap.forEach(HashMap.java:1425) ~[?:?]
>         at
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQu
> eries(DefaultDataDomainFlushAction.java:176)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(Def
> aultDataDomainFlushAction.java:89)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataDomain.onSyncNoFilters(DataDomain.java:6
> 09)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> DataDomain.java:835)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(TransactionFil
> ter.java:61)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler
> .performInTransaction(DefaultTransactionManager.java:180)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler
> .performInNewTransaction(DefaultTransactionManager.java:152)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandl
> er.handle(DefaultTransactionManager.java:95)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(D
> efaultTransactionManager.java:62)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(D
> efaultTransactionManager.java:40)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.tx.TransactionFilter.onSync(TransactionFilter.java:
> 61)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> DataDomain.java:834)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:7
> 37)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:6
> 86)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.oceanops.api.id.IdGenerator.commitChanges(IdGenerator.java:47)
> ~[classes/:?]
>         at
> org.oceanops.api.id.WebServiceManager.getID(WebServiceManager.java:56)
> ~[classes/:?]
>         at
> jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
> Method) ~[?:?]
>         at
> jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcces
> sorImpl.java:62)
> ~[?:?]
>         at
> jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMet
> hodAccessorImpl.java:43)
> ~[?:?]
>         at java.lang.reflect.Method.invoke(Method.java:564) ~[?:?]
>         at
> org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHan
> dlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.jav
> a:52)
> ~[jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodD
> ispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodD
> ispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatche
> rProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvid
> er.java:219)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodD
> ispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(Resourc
> eMethodInvoker.java:475)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(Resource
> MethodInvoker.java:397)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(Resource
> MethodInvoker.java:81)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:255
> )
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
> [jersey-common-2.35.jar:?]
>         at
> org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
> [jersey-common-2.35.jar:?]
>         at
> org.glassfish.jersey.internal.Errors.process(Errors.java:292)
> [jersey-common-2.35.jar:?]
>         at
> org.glassfish.jersey.internal.Errors.process(Errors.java:274)
> [jersey-common-2.35.jar:?]
>         at
> org.glassfish.jersey.internal.Errors.process(Errors.java:244)
> [jersey-common-2.35.jar:?]
>         at
> org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestS
> cope.java:265)
> [jersey-common-2.35.jar:?]
>         at
> org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:2
> 34)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandl
> er.java:684)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.jav
> a:394) [jersey-container-servlet-core-2.35.jar:?]
>         at
> org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:34
> 6) [jersey-container-servlet-core-2.35.jar:?]
>         at
> org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer
> .java:366)
> [jersey-contain[apache-tomcat-9.0.40]: er-servlet-core-2.35.jar:?]
>         at
> org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer
> .java:319) [jersey-container-servlet-core-2.35.jar:?]
>         at
> org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer
> .java:205) [jersey-container-servlet-core-2.35.jar:?]
>         at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appli
> cationFilterChain.java:231)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFi
> lterChain.java:166)
> [catalina.jar:9.0.40]
>         at
> org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
> [tomcat-websocket.jar:9.0.40]
>         at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appli
> cationFilterChain.java:193)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFi
> lterChain.java:166)
> [catalina.jar:9.0.40]
>         at
> org.oceanops.api.filters.AuthFilter.doFilter(AuthFilter.java:40)
> [api-1.3-SNAPSHOT-classes.jar:?]
>         at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appli
> cationFilterChain.java:193)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFi
> lterChain.java:166)
> [catalina.jar:9.0.40]
>         at
> org.apache.cayenne.configuration.web.CayenneFilter.doFilter(CayenneFil
> ter.java:127)
> [cayenne-web-4.2.M3.jar:4.2.M3]
>         at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appli
> cationFilterChain.java:193)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFi
> lterChain.java:166)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperVa
> lve.java:202)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextVa
> lve.java:97)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.authenticator.AuthenticatorBase.invoke(Authenticat
> orBase.java:542)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.ja
> va:143)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.ja
> va:92)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAcces
> sLogValve.java:690)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValv
> e.java:78)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java
> :343)
> [catalina.jar:9.0.40]
>         at
> org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:
> 374)
> [tomcat-coyote.jar:9.0.40]
>         at
> org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLigh
> t.java:65)
> [tomcat-coyote.jar:9.0.40]
>         at
> org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractP
> rotocol.java:880)
> [tomcat-coyote.jar:9.0.40]
>         at
> org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoi
> nt.java:1601)
> [tomcat-coyote.jar:9.0.40]
>         at
> org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase
> .java:49)
> [tomcat-coyote.jar:9.0.40]
>         at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.j
> ava:1130)
> [?:?]
>         at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.
> java:630)
> [?:?]
>         at
> org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThr
> ead.java:61)
> [tomcat-util.jar:9.0.40]
>         at java.lang.Thread.run(Thread.java:832) [?:?] Caused by:
> oracle.jdbc.OracleDatabaseException: ORA-02291: integrity constraint
> (JCOMMOPS_B.PTF_HARDWARE_FK) violated - parent key not found
>
>
>
> -----Original Message-----
> From: Michael Gentry <bl...@gmail.com>
> Sent: Thursday, November 4, 2021 7:28 PM
> To: Cayenne Users <us...@cayenne.apache.org>
> Subject: Re: Insertion order issue
>
> CAUTION: This message comes from an external server, do not click on
> links or open attachments unless you know the sender and are sure the
> content is safe.
>
>
> Hi Anthonin,
>
> Perhaps put a @SortWeight(2) annotation [1] on your child entity?
> Also, you need to configure a different entity sorter:
>
> // Need WeightedAshwoodEntitySorter for @SortWeight to work.
> Module        entitySorterModule = (binder) ->
> binder.bind(EntitySorter.class).to(WeightedAshwoodEntitySorter.class);
> ServerRuntime runtime            =
> ServerRuntimeBuilder.builder().addModule(myModule)....
>
> If this doesn't help, please provide a stack track and Cayenne version
> information.
>
> Thanks!
>
> mrg
>
>
> [1]
>
> https://cayenne.apache.org/docs/4.0/api/org/apache/cayenne/ashwood/Sor
> tWeight.html
>
>
> On Thu, Nov 4, 2021 at 10:38 AM Lize Anthonin (OceanOPS) <
> alize@groupcls.com>
> wrote:
>
> > Hi,
> >
> > I am using Cayenne in a web app (through AgRest, but this is purely
> > cayenne related, well I think so) that contains one service through
> > a POST method.
> > Basically, I submit a JSON body with multiple object in it, pass it
> > through the service method defined below, process each object and
> > for each ones doing some insert into an Oracle DB.
> > @POST
> > @Consumes(MediaType.APPLICATION_JSON)
> > @Path("getid")
> > @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") public
> > List<IdResponse> getID(final List<IdInput> inputs) {
> >                 There I loop over this list, process the object
> > IdInput and make the necessary insertions }
> >
> > My issue there is that when I commit the changes, the order of the
> > inserts seems to fail randomly, from one request to another. I have
> > relationships set in those modifications, and through the logs I can
> > see the PK being fetched from the sequences, but then sometimes
> > (most of the times) the referencing entity is inserted before the
> > referenced entity. And of course the commit fail for violation of parent key.
> >
> > I've tried to secure as much as possible the context, through
> > different
> > ways:
> >
> >   *   stateless thread context through the provided cayenne filter
> > (stateless because the session one would be committed via another
> > commit made in another filter, weird, but I send only one request,
> > this filter commit should happen prior to the 'service' commit)
> >   *   per method context
> >   *   custom stateless context through a filter that I made myself.
> > I thought I got it with he per method context, but it failed after a
> while.
> > And I tried committing after each processing in the loop, or after
> > the loop, but same results.
> >
> > I'm probably missing something, but I'm not getting why it happen
> > sometimes, not always(or never!). A threading issue maybe? But I'm
> > processing only one request, so I'm a bit lost.
> > Any thoughts? (before I commit after each insertion of entities
> > haha) How the order of inserts are defined? Maybe I miss-configured
> > some relationships in the modeler, but they come from a reverse
> > engineering and look ok...
> >
> > Many thanks in advance
> > Anthonin
> > ________________________________
> >
> > Ce message et toutes les pi?ces jointes (ci-apr?s le "message") sont
> > ?tablis ? l'intention exclusive de ses destinataires et sont
> confidentiels.
> > Si vous recevez ce message par erreur ou s'il ne vous est pas
> > destin?, merci de le d?truire ainsi que toute copie de votre syst?me
> > et d'en avertir imm?diatement l'exp?diteur. Toute lecture non
> > autoris?e, toute utilisation de ce message qui n'est pas conforme ?
> > sa destination, toute diffusion ou toute publication, totale ou
> > partielle, est interdite. L'Internet ne permettant pas d'assurer
> > l'int?grit? de ce message ?lectronique susceptible d'alt?ration,
> > l'exp?diteur (et ses
> > filiales) d?cline(nt) toute responsabilit? au titre de ce message
> > dans
> l'hypoth?se o? il aurait ?t?
> > modifi? ou falsifi?.
> >
> > This message and any attachments (the "message") is intended solely
> > for the intended recipient(s) and is confidential. If you receive
> > this message in error, or are not the intended recipient(s), please
> > delete it and any copies from your systems and immediately notify the sender.
> > Any unauthorized view, use that does not comply with its purpose,
> > dissemination or disclosure, either whole or partial, is prohibited.
> > Since the internet cannot guarantee the integrity of this message
> > which may not be reliable, the sender (and its subsidiaries) shall
> > not be liable for the message if modified or falsified.
> >
> ________________________________
>
> Ce message et toutes les pièces jointes (ci-après le "message") sont
> établis à l'intention exclusive de ses destinataires et sont confidentiels.
> Si vous recevez ce message par erreur ou s'il ne vous est pas destiné,
> merci de le détruire ainsi que toute copie de votre système et d'en
> avertir immédiatement l'expéditeur. Toute lecture non autorisée, toute
> utilisation de ce message qui n'est pas conforme à sa destination,
> toute diffusion ou toute publication, totale ou partielle, est
> interdite. L'Internet ne permettant pas d'assurer l'intégrité de ce
> message électronique susceptible d'altération, l’expéditeur (et ses
> filiales) décline(nt) toute responsabilité au titre de ce message dans
> l'hypothèse où il aurait été modifié ou falsifié.
>
> This message and any attachments (the "message") is intended solely
> for the intended recipient(s) and is confidential. If you receive this
> message in error, or are not the intended recipient(s), please delete
> it and any copies from your systems and immediately notify the sender.
> Any unauthorized view, use that does not comply with its purpose,
> dissemination or disclosure, either whole or partial, is prohibited.
> Since the internet cannot guarantee the integrity of this message
> which may not be reliable, the sender (and its subsidiaries) shall not
> be liable for the message if modified or falsified.
>
________________________________

Ce message et toutes les pièces jointes (ci-après le "message") sont établis à l'intention exclusive de ses destinataires et sont confidentiels. Si vous recevez ce message par erreur ou s'il ne vous est pas destiné, merci de le détruire ainsi que toute copie de votre système et d'en avertir immédiatement l'expéditeur. Toute lecture non autorisée, toute utilisation de ce message qui n'est pas conforme à sa destination, toute diffusion ou toute publication, totale ou partielle, est interdite. L'Internet ne permettant pas d'assurer l'intégrité de ce message électronique susceptible d'altération, l’expéditeur (et ses filiales) décline(nt) toute responsabilité au titre de ce message dans l'hypothèse où il aurait été modifié ou falsifié.

This message and any attachments (the "message") is intended solely for the intended recipient(s) and is confidential. If you receive this message in error, or are not the intended recipient(s), please delete it and any copies from your systems and immediately notify the sender. Any unauthorized view, use that does not comply with its purpose, dissemination or disclosure, either whole or partial, is prohibited. Since the internet cannot guarantee the integrity of this message which may not be reliable, the sender (and its subsidiaries) shall not be liable for the message if modified or falsified.

Re: Insertion order issue

Posted by Michael Gentry <bl...@gmail.com>.
Hi Anthonin,

A) Since you are using Oracle, you may need to use a DEFERRABLE constraint
(INITIALLY DEFERRED).

B) Any reason you are using a custom PK generator instead of using the
standard sequence generator supported by Cayenne? (Cayenne Modeler ->
select DB Entity -> PK Generation Strategy -> Custom Sequence -> enter
Sequence Name and Cache Size -- looks like you are using 1).

mrg


On Fri, Nov 5, 2021 at 5:44 AM Lize Anthonin (OceanOPS) <al...@groupcls.com>
wrote:

> Hi Michael,
>
> Thanks for your answer.
> I tried, but does not seem to make any difference. I added
> WeightedAshwoodEntitySorter (amongst other things) in a module loaded as
> init-param for the CayenneFilter, as follows:
> @Override
> public void configure(Binder binder) {
>             binder.bind(RequestHandler.class)
>                 .to(StatelessContextRequestHandler.class)
>                 .withoutScope();
>
>             OraclePkGeneratorCustom pkgen = new OraclePkGeneratorCustom();
>             pkgen.setPkCacheSize(1);
>             binder.bind(PkGenerator.class).toInstance(pkgen);
>
>
> binder.bind(EntitySorter.class).to(WeightedAshwoodEntitySorter.class);
> }
>
> And then the annotation as you mentioned on the child entity. It still
> stays rather random...
>
>
> Here is the stack trace, as you can see I use Cayenne 4.2.M3. That would
> have been smarter of me to share it initially!
> java.sql.SQLIntegrityConstraintViolationException: ORA-02291: integrity
> constraint (JCOMMOPS_B.PTF_HARDWARE_FK) violated - parent key not found
>
>         at
> oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:509)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:461)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1104)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:553)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:269)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:655)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:270)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:91)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:970)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1205)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3666)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.T4CPreparedStatement.executeInternal(T4CPreparedStatement.java:1426)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.OraclePreparedStatement.executeLargeUpdate(OraclePreparedStatement.java:3756)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3736)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1063)
> ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
>         at
> org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:136)
> ~[tomcat-dbcp.jar:9.0.40]
>         at
> org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:136)
> ~[tomcat-dbcp.jar:9.0.40]
>         at
> org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(BatchAction.java:185)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.jdbc.BatchAction.performAction(BatchAction.java:96)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataNodeQueryAction.runQuery(DataNodeQueryAction.java:97)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(DefaultDataDomainFlushAction.java:177)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at java.util.HashMap.forEach(HashMap.java:1425) ~[?:?]
>         at
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(DefaultDataDomainFlushAction.java:176)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(DefaultDataDomainFlushAction.java:89)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataDomain.onSyncNoFilters(DataDomain.java:609)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(DataDomain.java:835)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(TransactionFilter.java:61)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(DefaultTransactionManager.java:180)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(DefaultTransactionManager.java:152)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(DefaultTransactionManager.java:95)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(DefaultTransactionManager.java:62)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(DefaultTransactionManager.java:40)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.tx.TransactionFilter.onSync(TransactionFilter.java:61)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(DataDomain.java:834)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:737)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at
> org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:686)
> ~[cayenne-server-4.2.M3.jar:4.2.M3]
>         at org.oceanops.api.id.IdGenerator.commitChanges(IdGenerator.java:47)
> ~[classes/:?]
>         at org.oceanops.api.id.WebServiceManager.getID(WebServiceManager.java:56)
> ~[classes/:?]
>         at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
> Method) ~[?:?]
>         at
> jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> ~[?:?]
>         at
> jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> ~[?:?]
>         at java.lang.reflect.Method.invoke(Method.java:564) ~[?:?]
>         at
> org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)
> ~[jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:219)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:475)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:397)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:255)
> [jersey-server-2.35.jar:?]
>         at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
> [jersey-common-2.35.jar:?]
>         at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
> [jersey-common-2.35.jar:?]
>         at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
> [jersey-common-2.35.jar:?]
>         at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
> [jersey-common-2.35.jar:?]
>         at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
> [jersey-common-2.35.jar:?]
>         at
> org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
> [jersey-common-2.35.jar:?]
>         at
> org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:234)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684)
> [jersey-server-2.35.jar:?]
>         at
> org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)
> [jersey-container-servlet-core-2.35.jar:?]
>         at
> org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
> [jersey-container-servlet-core-2.35.jar:?]
>         at
> org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:366)
> [jersey-contain[apache-tomcat-9.0.40]: er-servlet-core-2.35.jar:?]
>         at
> org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:319)
> [jersey-container-servlet-core-2.35.jar:?]
>         at
> org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
> [jersey-container-servlet-core-2.35.jar:?]
>         at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
> [catalina.jar:9.0.40]
>         at
> org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
> [tomcat-websocket.jar:9.0.40]
>         at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
> [catalina.jar:9.0.40]
>         at
> org.oceanops.api.filters.AuthFilter.doFilter(AuthFilter.java:40)
> [api-1.3-SNAPSHOT-classes.jar:?]
>         at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
> [catalina.jar:9.0.40]
>         at
> org.apache.cayenne.configuration.web.CayenneFilter.doFilter(CayenneFilter.java:127)
> [cayenne-web-4.2.M3.jar:4.2.M3]
>         at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
> [catalina.jar:9.0.40]
>         at
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
> [catalina.jar:9.0.40]
>         at
> org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
> [tomcat-coyote.jar:9.0.40]
>         at
> org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
> [tomcat-coyote.jar:9.0.40]
>         at
> org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:880)
> [tomcat-coyote.jar:9.0.40]
>         at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1601)
> [tomcat-coyote.jar:9.0.40]
>         at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
> [tomcat-coyote.jar:9.0.40]
>         at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
> [?:?]
>         at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
> [?:?]
>         at
> org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
> [tomcat-util.jar:9.0.40]
>         at java.lang.Thread.run(Thread.java:832) [?:?]
> Caused by: oracle.jdbc.OracleDatabaseException: ORA-02291: integrity
> constraint (JCOMMOPS_B.PTF_HARDWARE_FK) violated - parent key not found
>
>
>
> -----Original Message-----
> From: Michael Gentry <bl...@gmail.com>
> Sent: Thursday, November 4, 2021 7:28 PM
> To: Cayenne Users <us...@cayenne.apache.org>
> Subject: Re: Insertion order issue
>
> CAUTION: This message comes from an external server, do not click on links
> or open attachments unless you know the sender and are sure the content is
> safe.
>
>
> Hi Anthonin,
>
> Perhaps put a @SortWeight(2) annotation [1] on your child entity? Also,
> you need to configure a different entity sorter:
>
> // Need WeightedAshwoodEntitySorter for @SortWeight to work.
> Module        entitySorterModule = (binder) ->
> binder.bind(EntitySorter.class).to(WeightedAshwoodEntitySorter.class);
> ServerRuntime runtime            =
> ServerRuntimeBuilder.builder().addModule(myModule)....
>
> If this doesn't help, please provide a stack track and Cayenne version
> information.
>
> Thanks!
>
> mrg
>
>
> [1]
>
> https://cayenne.apache.org/docs/4.0/api/org/apache/cayenne/ashwood/SortWeight.html
>
>
> On Thu, Nov 4, 2021 at 10:38 AM Lize Anthonin (OceanOPS) <
> alize@groupcls.com>
> wrote:
>
> > Hi,
> >
> > I am using Cayenne in a web app (through AgRest, but this is purely
> > cayenne related, well I think so) that contains one service through a
> > POST method.
> > Basically, I submit a JSON body with multiple object in it, pass it
> > through the service method defined below, process each object and for
> > each ones doing some insert into an Oracle DB.
> > @POST
> > @Consumes(MediaType.APPLICATION_JSON)
> > @Path("getid")
> > @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") public
> > List<IdResponse> getID(final List<IdInput> inputs) {
> >                 There I loop over this list, process the object
> > IdInput and make the necessary insertions }
> >
> > My issue there is that when I commit the changes, the order of the
> > inserts seems to fail randomly, from one request to another. I have
> > relationships set in those modifications, and through the logs I can
> > see the PK being fetched from the sequences, but then sometimes (most
> > of the times) the referencing entity is inserted before the referenced
> > entity. And of course the commit fail for violation of parent key.
> >
> > I've tried to secure as much as possible the context, through
> > different
> > ways:
> >
> >   *   stateless thread context through the provided cayenne filter
> > (stateless because the session one would be committed via another
> > commit made in another filter, weird, but I send only one request,
> > this filter commit should happen prior to the 'service' commit)
> >   *   per method context
> >   *   custom stateless context through a filter that I made myself.
> > I thought I got it with he per method context, but it failed after a
> while.
> > And I tried committing after each processing in the loop, or after the
> > loop, but same results.
> >
> > I'm probably missing something, but I'm not getting why it happen
> > sometimes, not always(or never!). A threading issue maybe? But I'm
> > processing only one request, so I'm a bit lost.
> > Any thoughts? (before I commit after each insertion of entities haha)
> > How the order of inserts are defined? Maybe I miss-configured some
> > relationships in the modeler, but they come from a reverse engineering
> > and look ok...
> >
> > Many thanks in advance
> > Anthonin
> > ________________________________
> >
> > Ce message et toutes les pi?ces jointes (ci-apr?s le "message") sont
> > ?tablis ? l'intention exclusive de ses destinataires et sont
> confidentiels.
> > Si vous recevez ce message par erreur ou s'il ne vous est pas destin?,
> > merci de le d?truire ainsi que toute copie de votre syst?me et d'en
> > avertir imm?diatement l'exp?diteur. Toute lecture non autoris?e, toute
> > utilisation de ce message qui n'est pas conforme ? sa destination,
> > toute diffusion ou toute publication, totale ou partielle, est
> > interdite. L'Internet ne permettant pas d'assurer l'int?grit? de ce
> > message ?lectronique susceptible d'alt?ration, l'exp?diteur (et ses
> > filiales) d?cline(nt) toute responsabilit? au titre de ce message dans
> l'hypoth?se o? il aurait ?t?
> > modifi? ou falsifi?.
> >
> > This message and any attachments (the "message") is intended solely
> > for the intended recipient(s) and is confidential. If you receive this
> > message in error, or are not the intended recipient(s), please delete
> > it and any copies from your systems and immediately notify the sender.
> > Any unauthorized view, use that does not comply with its purpose,
> > dissemination or disclosure, either whole or partial, is prohibited.
> > Since the internet cannot guarantee the integrity of this message
> > which may not be reliable, the sender (and its subsidiaries) shall not
> > be liable for the message if modified or falsified.
> >
> ________________________________
>
> Ce message et toutes les pièces jointes (ci-après le "message") sont
> établis à l'intention exclusive de ses destinataires et sont confidentiels.
> Si vous recevez ce message par erreur ou s'il ne vous est pas destiné,
> merci de le détruire ainsi que toute copie de votre système et d'en avertir
> immédiatement l'expéditeur. Toute lecture non autorisée, toute utilisation
> de ce message qui n'est pas conforme à sa destination, toute diffusion ou
> toute publication, totale ou partielle, est interdite. L'Internet ne
> permettant pas d'assurer l'intégrité de ce message électronique susceptible
> d'altération, l’expéditeur (et ses filiales) décline(nt) toute
> responsabilité au titre de ce message dans l'hypothèse où il aurait été
> modifié ou falsifié.
>
> This message and any attachments (the "message") is intended solely for
> the intended recipient(s) and is confidential. If you receive this message
> in error, or are not the intended recipient(s), please delete it and any
> copies from your systems and immediately notify the sender. Any
> unauthorized view, use that does not comply with its purpose, dissemination
> or disclosure, either whole or partial, is prohibited. Since the internet
> cannot guarantee the integrity of this message which may not be reliable,
> the sender (and its subsidiaries) shall not be liable for the message if
> modified or falsified.
>

RE: Insertion order issue

Posted by "Lize Anthonin (OceanOPS)" <al...@groupcls.com>.
Hi Michael,

Thanks for your answer.
I tried, but does not seem to make any difference. I added WeightedAshwoodEntitySorter (amongst other things) in a module loaded as init-param for the CayenneFilter, as follows:
@Override
public void configure(Binder binder) {
            binder.bind(RequestHandler.class)
                .to(StatelessContextRequestHandler.class)
                .withoutScope();

            OraclePkGeneratorCustom pkgen = new OraclePkGeneratorCustom();
            pkgen.setPkCacheSize(1);
            binder.bind(PkGenerator.class).toInstance(pkgen);

            binder.bind(EntitySorter.class).to(WeightedAshwoodEntitySorter.class);
}

And then the annotation as you mentioned on the child entity. It still stays rather random...


Here is the stack trace, as you can see I use Cayenne 4.2.M3. That would have been smarter of me to share it initially!
java.sql.SQLIntegrityConstraintViolationException: ORA-02291: integrity constraint (JCOMMOPS_B.PTF_HARDWARE_FK) violated - parent key not found

        at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:509) ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
        at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:461) ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
        at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1104) ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
        at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:553) ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
        at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:269) ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
        at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:655) ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
        at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:270) ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
        at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:91) ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
        at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:970) ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
        at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1205) ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
        at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3666) ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
        at oracle.jdbc.driver.T4CPreparedStatement.executeInternal(T4CPreparedStatement.java:1426) ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
        at oracle.jdbc.driver.OraclePreparedStatement.executeLargeUpdate(OraclePreparedStatement.java:3756) ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
        at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3736) ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
        at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1063) ~[ojdbc10-19.12.0.0.jar:19.12.0.0.0]
        at org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:136) ~[tomcat-dbcp.jar:9.0.40]
        at org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:136) ~[tomcat-dbcp.jar:9.0.40]
        at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(BatchAction.java:185) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.access.jdbc.BatchAction.performAction(BatchAction.java:96) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.access.DataNodeQueryAction.runQuery(DataNodeQueryAction.java:97) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(DefaultDataDomainFlushAction.java:177) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at java.util.HashMap.forEach(HashMap.java:1425) ~[?:?]
        at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(DefaultDataDomainFlushAction.java:176) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(DefaultDataDomainFlushAction.java:89) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.access.DataDomain.onSyncNoFilters(DataDomain.java:609) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(DataDomain.java:835) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(TransactionFilter.java:61) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(DefaultTransactionManager.java:180) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(DefaultTransactionManager.java:152) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(DefaultTransactionManager.java:95) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(DefaultTransactionManager.java:62) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(DefaultTransactionManager.java:40) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.tx.TransactionFilter.onSync(TransactionFilter.java:61) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(DataDomain.java:834) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:737) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:686) ~[cayenne-server-4.2.M3.jar:4.2.M3]
        at org.oceanops.api.id.IdGenerator.commitChanges(IdGenerator.java:47) ~[classes/:?]
        at org.oceanops.api.id.WebServiceManager.getID(WebServiceManager.java:56) ~[classes/:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:564) ~[?:?]
        at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52) ~[jersey-server-2.35.jar:?]
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124) [jersey-server-2.35.jar:?]
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167) [jersey-server-2.35.jar:?]
        at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:219) [jersey-server-2.35.jar:?]
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79) [jersey-server-2.35.jar:?]
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:475) [jersey-server-2.35.jar:?]
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:397) [jersey-server-2.35.jar:?]
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81) [jersey-server-2.35.jar:?]
        at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:255) [jersey-server-2.35.jar:?]
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) [jersey-common-2.35.jar:?]
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244) [jersey-common-2.35.jar:?]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:292) [jersey-common-2.35.jar:?]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:274) [jersey-common-2.35.jar:?]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:244) [jersey-common-2.35.jar:?]
        at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265) [jersey-common-2.35.jar:?]
        at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:234) [jersey-server-2.35.jar:?]
        at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684) [jersey-server-2.35.jar:?]
        at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394) [jersey-container-servlet-core-2.35.jar:?]
        at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346) [jersey-container-servlet-core-2.35.jar:?]
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:366) [jersey-contain[apache-tomcat-9.0.40]: er-servlet-core-2.35.jar:?]
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:319) [jersey-container-servlet-core-2.35.jar:?]
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205) [jersey-container-servlet-core-2.35.jar:?]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [catalina.jar:9.0.40]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:9.0.40]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-websocket.jar:9.0.40]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:9.0.40]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:9.0.40]
        at org.oceanops.api.filters.AuthFilter.doFilter(AuthFilter.java:40) [api-1.3-SNAPSHOT-classes.jar:?]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:9.0.40]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:9.0.40]
        at org.apache.cayenne.configuration.web.CayenneFilter.doFilter(CayenneFilter.java:127) [cayenne-web-4.2.M3.jar:4.2.M3]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:9.0.40]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:9.0.40]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) [catalina.jar:9.0.40]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [catalina.jar:9.0.40]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) [catalina.jar:9.0.40]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) [catalina.jar:9.0.40]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [catalina.jar:9.0.40]
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690) [catalina.jar:9.0.40]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [catalina.jar:9.0.40]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [catalina.jar:9.0.40]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) [tomcat-coyote.jar:9.0.40]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-coyote.jar:9.0.40]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:880) [tomcat-coyote.jar:9.0.40]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1601) [tomcat-coyote.jar:9.0.40]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-coyote.jar:9.0.40]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) [?:?]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:9.0.40]
        at java.lang.Thread.run(Thread.java:832) [?:?]
Caused by: oracle.jdbc.OracleDatabaseException: ORA-02291: integrity constraint (JCOMMOPS_B.PTF_HARDWARE_FK) violated - parent key not found



-----Original Message-----
From: Michael Gentry <bl...@gmail.com>
Sent: Thursday, November 4, 2021 7:28 PM
To: Cayenne Users <us...@cayenne.apache.org>
Subject: Re: Insertion order issue

CAUTION: This message comes from an external server, do not click on links or open attachments unless you know the sender and are sure the content is safe.


Hi Anthonin,

Perhaps put a @SortWeight(2) annotation [1] on your child entity? Also, you need to configure a different entity sorter:

// Need WeightedAshwoodEntitySorter for @SortWeight to work.
Module        entitySorterModule = (binder) ->
binder.bind(EntitySorter.class).to(WeightedAshwoodEntitySorter.class);
ServerRuntime runtime            =
ServerRuntimeBuilder.builder().addModule(myModule)....

If this doesn't help, please provide a stack track and Cayenne version information.

Thanks!

mrg


[1]
https://cayenne.apache.org/docs/4.0/api/org/apache/cayenne/ashwood/SortWeight.html


On Thu, Nov 4, 2021 at 10:38 AM Lize Anthonin (OceanOPS) <al...@groupcls.com>
wrote:

> Hi,
>
> I am using Cayenne in a web app (through AgRest, but this is purely
> cayenne related, well I think so) that contains one service through a
> POST method.
> Basically, I submit a JSON body with multiple object in it, pass it
> through the service method defined below, process each object and for
> each ones doing some insert into an Oracle DB.
> @POST
> @Consumes(MediaType.APPLICATION_JSON)
> @Path("getid")
> @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") public
> List<IdResponse> getID(final List<IdInput> inputs) {
>                 There I loop over this list, process the object
> IdInput and make the necessary insertions }
>
> My issue there is that when I commit the changes, the order of the
> inserts seems to fail randomly, from one request to another. I have
> relationships set in those modifications, and through the logs I can
> see the PK being fetched from the sequences, but then sometimes (most
> of the times) the referencing entity is inserted before the referenced
> entity. And of course the commit fail for violation of parent key.
>
> I've tried to secure as much as possible the context, through
> different
> ways:
>
>   *   stateless thread context through the provided cayenne filter
> (stateless because the session one would be committed via another
> commit made in another filter, weird, but I send only one request,
> this filter commit should happen prior to the 'service' commit)
>   *   per method context
>   *   custom stateless context through a filter that I made myself.
> I thought I got it with he per method context, but it failed after a while.
> And I tried committing after each processing in the loop, or after the
> loop, but same results.
>
> I'm probably missing something, but I'm not getting why it happen
> sometimes, not always(or never!). A threading issue maybe? But I'm
> processing only one request, so I'm a bit lost.
> Any thoughts? (before I commit after each insertion of entities haha)
> How the order of inserts are defined? Maybe I miss-configured some
> relationships in the modeler, but they come from a reverse engineering
> and look ok...
>
> Many thanks in advance
> Anthonin
> ________________________________
>
> Ce message et toutes les pi?ces jointes (ci-apr?s le "message") sont
> ?tablis ? l'intention exclusive de ses destinataires et sont confidentiels.
> Si vous recevez ce message par erreur ou s'il ne vous est pas destin?,
> merci de le d?truire ainsi que toute copie de votre syst?me et d'en
> avertir imm?diatement l'exp?diteur. Toute lecture non autoris?e, toute
> utilisation de ce message qui n'est pas conforme ? sa destination,
> toute diffusion ou toute publication, totale ou partielle, est
> interdite. L'Internet ne permettant pas d'assurer l'int?grit? de ce
> message ?lectronique susceptible d'alt?ration, l'exp?diteur (et ses
> filiales) d?cline(nt) toute responsabilit? au titre de ce message dans l'hypoth?se o? il aurait ?t?
> modifi? ou falsifi?.
>
> This message and any attachments (the "message") is intended solely
> for the intended recipient(s) and is confidential. If you receive this
> message in error, or are not the intended recipient(s), please delete
> it and any copies from your systems and immediately notify the sender.
> Any unauthorized view, use that does not comply with its purpose,
> dissemination or disclosure, either whole or partial, is prohibited.
> Since the internet cannot guarantee the integrity of this message
> which may not be reliable, the sender (and its subsidiaries) shall not
> be liable for the message if modified or falsified.
>
________________________________

Ce message et toutes les pièces jointes (ci-après le "message") sont établis à l'intention exclusive de ses destinataires et sont confidentiels. Si vous recevez ce message par erreur ou s'il ne vous est pas destiné, merci de le détruire ainsi que toute copie de votre système et d'en avertir immédiatement l'expéditeur. Toute lecture non autorisée, toute utilisation de ce message qui n'est pas conforme à sa destination, toute diffusion ou toute publication, totale ou partielle, est interdite. L'Internet ne permettant pas d'assurer l'intégrité de ce message électronique susceptible d'altération, l’expéditeur (et ses filiales) décline(nt) toute responsabilité au titre de ce message dans l'hypothèse où il aurait été modifié ou falsifié.

This message and any attachments (the "message") is intended solely for the intended recipient(s) and is confidential. If you receive this message in error, or are not the intended recipient(s), please delete it and any copies from your systems and immediately notify the sender. Any unauthorized view, use that does not comply with its purpose, dissemination or disclosure, either whole or partial, is prohibited. Since the internet cannot guarantee the integrity of this message which may not be reliable, the sender (and its subsidiaries) shall not be liable for the message if modified or falsified.

Re: Insertion order issue

Posted by Michael Gentry <bl...@gmail.com>.
Hi Anthonin,

Perhaps put a @SortWeight(2) annotation [1] on your child entity? Also, you
need to configure a different entity sorter:

// Need WeightedAshwoodEntitySorter for @SortWeight to work.
Module        entitySorterModule = (binder) ->
binder.bind(EntitySorter.class).to(WeightedAshwoodEntitySorter.class);
ServerRuntime runtime            =
ServerRuntimeBuilder.builder().addModule(myModule)....

If this doesn't help, please provide a stack track and Cayenne version
information.

Thanks!

mrg


[1]
https://cayenne.apache.org/docs/4.0/api/org/apache/cayenne/ashwood/SortWeight.html


On Thu, Nov 4, 2021 at 10:38 AM Lize Anthonin (OceanOPS) <al...@groupcls.com>
wrote:

> Hi,
>
> I am using Cayenne in a web app (through AgRest, but this is purely
> cayenne related, well I think so) that contains one service through a POST
> method.
> Basically, I submit a JSON body with multiple object in it, pass it
> through the service method defined below, process each object and for each
> ones doing some insert into an Oracle DB.
> @POST
> @Consumes(MediaType.APPLICATION_JSON)
> @Path("getid")
> @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
> public List<IdResponse> getID(final List<IdInput> inputs)
> {
>                 There I loop over this list, process the object IdInput
> and make the necessary insertions
> }
>
> My issue there is that when I commit the changes, the order of the inserts
> seems to fail randomly, from one request to another. I have relationships
> set in those modifications, and through the logs I can see the PK being
> fetched from the sequences, but then sometimes (most of the times) the
> referencing entity is inserted before the referenced entity. And of course
> the commit fail for violation of parent key.
>
> I've tried to secure as much as possible the context, through different
> ways:
>
>   *   stateless thread context through the provided cayenne filter
> (stateless because the session one would be committed via another commit
> made in another filter, weird, but I send only one request, this filter
> commit should happen prior to the 'service' commit)
>   *   per method context
>   *   custom stateless context through a filter that I made myself.
> I thought I got it with he per method context, but it failed after a while.
> And I tried committing after each processing in the loop, or after the
> loop, but same results.
>
> I'm probably missing something, but I'm not getting why it happen
> sometimes, not always(or never!). A threading issue maybe? But I'm
> processing only one request, so I'm a bit lost.
> Any thoughts? (before I commit after each insertion of entities haha)
> How the order of inserts are defined? Maybe I miss-configured some
> relationships in the modeler, but they come from a reverse engineering and
> look ok...
>
> Many thanks in advance
> Anthonin
> ________________________________
>
> Ce message et toutes les pi?ces jointes (ci-apr?s le "message") sont
> ?tablis ? l'intention exclusive de ses destinataires et sont confidentiels.
> Si vous recevez ce message par erreur ou s'il ne vous est pas destin?,
> merci de le d?truire ainsi que toute copie de votre syst?me et d'en avertir
> imm?diatement l'exp?diteur. Toute lecture non autoris?e, toute utilisation
> de ce message qui n'est pas conforme ? sa destination, toute diffusion ou
> toute publication, totale ou partielle, est interdite. L'Internet ne
> permettant pas d'assurer l'int?grit? de ce message ?lectronique susceptible
> d'alt?ration, l'exp?diteur (et ses filiales) d?cline(nt) toute
> responsabilit? au titre de ce message dans l'hypoth?se o? il aurait ?t?
> modifi? ou falsifi?.
>
> This message and any attachments (the "message") is intended solely for
> the intended recipient(s) and is confidential. If you receive this message
> in error, or are not the intended recipient(s), please delete it and any
> copies from your systems and immediately notify the sender. Any
> unauthorized view, use that does not comply with its purpose, dissemination
> or disclosure, either whole or partial, is prohibited. Since the internet
> cannot guarantee the integrity of this message which may not be reliable,
> the sender (and its subsidiaries) shall not be liable for the message if
> modified or falsified.
>