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 <blackn...@gmail.com>
> Sent: Thursday, November 4, 2021 7:28 PM
> To: Cayenne Users <user@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.
>

Reply via email to