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