Are failing tables related directly to those x-tables you have? And
did you review SQL insert/update logs, maybe you can note something
strange there (e.g. wrong order of operations or incomplete data in
duplicated inserts)?
And it really will be great if you can test your code with fewer
tables/records involved while still having failure.

On Thu, Aug 3, 2017 at 12:22 PM, Musall, Maik <m...@selbstdenker.ag> wrote:
> Hi Nikita,
>
> the total number of entities is 130, and two of those have a meaningful 
> string as primary key, while the rest has regular integers. No inheritance, 
> but several flattened m:n relationships. I also have a few m:n relationships 
> with the x-table being an entity of it's own, which contains additional 
> attributes (like a sort key).
>
> Reducing the number of entities involved is not really an option, because 
> having the entire commit going through as one transaction or fail as one 
> transaction is the whole point of doing it in one transaction. I could do 
> this as a test to narrow things down though if you think that could help.
>
> A test schema could be possible, but would be a lot of work obviously.
>
> Thanks
> Maik
>
>
>> Am 02.08.2017 um 09:14 schrieb Nikita Timofeev <ntimof...@objectstyle.com>:
>>
>> Hi Maik,
>>
>> D you have any meaningful PK or FK, inheritance or flattened
>> attributes in your model?
>> And maybe you can reduce number of entities involved or even better
>> provide some test schema on which problem occurs?
>>
>> On Wed, Aug 2, 2017 at 7:46 AM, Musall, Maik <m...@selbstdenker.ag> wrote:
>>> Hi,
>>>
>>> does nobody have any idea? Should I post this on the dev list because it 
>>> could be a Cayenne bug?
>>>
>>> Maik
>>>
>>>
>>>> Am 28.07.2017 um 17:20 schrieb Musall, Maik <m...@selbstdenker.ag>:
>>>>
>>>> Hi,
>>>>
>>>> I've been trying to resolve an unpleasant problem for a few days now. I'm 
>>>> trying to save a graph of new and changed objects related to each other, 
>>>> using a PostgreSQL 9.5 database. The number of objects is in the range 
>>>> between 10 and 100 usually. Several objects of the same class each, and 
>>>> numerous relationships involved. The model as a whole contains a few 
>>>> indirect cyclic relationships, but in these failing inserts, there aren't 
>>>> any cyclic relations involved.
>>>>
>>>> I get something like this:
>>>>
>>>> org.apache.cayenne.CayenneRuntimeException: [v.4.0.B2-SNAPSHOT Jul 12 2017 
>>>> 08:27:18] Commit Exception
>>>>      at 
>>>> org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:774)
>>>>      at 
>>>> org.apache.cayenne.access.DataContext.commitChangesToParent(DataContext.java:682)
>>>>      at 
>>>> com.selbstdenker.canusa.powerd.PDObjectContext.saveChanges(PDObjectContext.java:171)
>>>>      (stuff ommitted)
>>>> Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value 
>>>> violates unique constraint "pdcjourneyelementtexts_pk"
>>>> Detail: Key (journeyelementtextskey)=(1528690) already exists.
>>>>      at 
>>>> org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
>>>>      at 
>>>> org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1927)
>>>>      at 
>>>> org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:405)
>>>>      at 
>>>> org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2892)
>>>>      at 
>>>> com.zaxxer.hikari.pool.ProxyStatement.executeBatch(ProxyStatement.java:125)
>>>>      at 
>>>> com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeBatch(HikariProxyPreparedStatement.java)
>>>>      at 
>>>> org.apache.cayenne.access.jdbc.BatchAction.runAsBatch(BatchAction.java:120)
>>>>      at 
>>>> org.apache.cayenne.access.jdbc.BatchAction.performAction(BatchAction.java:85)
>>>>      at 
>>>> org.apache.cayenne.access.DataNodeQueryAction.runQuery(DataNodeQueryAction.java:97)
>>>>      at 
>>>> org.apache.cayenne.access.DataNode.performQueries(DataNode.java:293)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomainFlushAction.runQueries(DataDomainFlushAction.java:233)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomainFlushAction.flush(DataDomainFlushAction.java:153)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:633)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomain.onSyncNoFilters(DataDomain.java:603)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(DataDomain.java:764)
>>>>      at 
>>>> org.apache.cayenne.commitlog.CommitLogFilter.onSync(CommitLogFilter.java:85)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(DataDomain.java:764)
>>>>      at 
>>>> org.apache.cayenne.tx.TransactionFilter$1.perform(TransactionFilter.java:73)
>>>>      at 
>>>> org.apache.cayenne.tx.TransactionFilter$1.perform(TransactionFilter.java:70)
>>>>      at 
>>>> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(DefaultTransactionManager.java:87)
>>>>      at 
>>>> org.apache.cayenne.tx.DefaultTransactionManager.performInLocalTransaction(DefaultTransactionManager.java:59)
>>>>      at 
>>>> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(DefaultTransactionManager.java:52)
>>>>      at 
>>>> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(DefaultTransactionManager.java:40)
>>>>      at 
>>>> org.apache.cayenne.tx.TransactionFilter.onSync(TransactionFilter.java:70)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(DataDomain.java:764)
>>>>      at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:590)
>>>>      at 
>>>> org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:742)
>>>>      ... 60 more
>>>>
>>>> A few notes:
>>>>
>>>> * Before this insert, the max primary key of this table was 1528658, last 
>>>> sequence value was 1528688.
>>>> * It happens with one of the tables involved each time, and the table this 
>>>> happens with changes randomly.
>>>> * I had all but the m:n cross tables set to database-generated pk, but 
>>>> also tried having everything Cayenne-generated (so that Cayenne would be 
>>>> fetching new sequence values before inserting, which I verified it did). 
>>>> Makes no difference.
>>>> * I verified before each test run that all sequence values are between 0 
>>>> and 32 greater than the current max primary key of the corresponding table 
>>>> (wrote a script for that).
>>>>
>>>> Then I did some research and found that maybe Cayenne fails to figure out 
>>>> a proper insert ordering. So I tried using WeightedAshwoodEntitySorter 
>>>> with @SortWeight (now in cayenne-server), following this mail thread:
>>>> https://lists.apache.org/thread.html/0452cd5ca9de85f19882539710588f1b221da7627f845902ed10a7b6@1461051077@%3Cuser.cayenne.apache.org%3E
>>>>  
>>>> <https://lists.apache.org/thread.html/0452cd5ca9de85f19882539710588f1b221da7627f845902ed10a7b6@1461051077@%3Cuser.cayenne.apache.org%3E>
>>>> but with that the application won't even start up because one of the first 
>>>> DML statements already fails:
>>>>
>>>> Caused by: java.lang.NullPointerException: No record for DbEntity: 
>>>> org.apache.cayenne.map.DbEntity@a92be4f[name=PDCUserLeafletLog]
>>>>      at 
>>>> org.apache.cayenne.ashwood.AshwoodEntitySorter$DbEntityComparator.compare(AshwoodEntitySorter.java:368)
>>>>      at 
>>>> org.apache.cayenne.ashwood.AshwoodEntitySorter$DbEntityComparator.compare(AshwoodEntitySorter.java:352)
>>>>      at 
>>>> org.apache.cayenne.ashwood.WeightedAshwoodEntitySorter$WeightedDbEntityComparator.compare(WeightedAshwoodEntitySorter.java:103)
>>>>      at 
>>>> org.apache.cayenne.ashwood.WeightedAshwoodEntitySorter$WeightedDbEntityComparator.compare(WeightedAshwoodEntitySorter.java:95)
>>>>      at java.util.TimSort.countRunAndMakeAscending(TimSort.java:355)
>>>>      at java.util.TimSort.sort(TimSort.java:220)
>>>>      at java.util.Arrays.sort(Arrays.java:1512)
>>>>      at java.util.ArrayList.sort(ArrayList.java:1454)
>>>>      at java.util.Collections.sort(Collections.java:175)
>>>>      at 
>>>> org.apache.cayenne.ashwood.AshwoodEntitySorter.sortDbEntities(AshwoodEntitySorter.java:182)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomainInsertBucket.appendQueriesInternal(DataDomainInsertBucket.java:56)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomainSyncBucket.appendQueries(DataDomainSyncBucket.java:78)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomainFlushAction.preprocess(DataDomainFlushAction.java:185)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomainFlushAction.flush(DataDomainFlushAction.java:143)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:633)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomain.onSyncNoFilters(DataDomain.java:603)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(DataDomain.java:764)
>>>>      at 
>>>> org.apache.cayenne.commitlog.CommitLogFilter.onSync(CommitLogFilter.java:85)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(DataDomain.java:764)
>>>>      at 
>>>> org.apache.cayenne.tx.TransactionFilter$1.perform(TransactionFilter.java:73)
>>>>      at 
>>>> org.apache.cayenne.tx.TransactionFilter$1.perform(TransactionFilter.java:70)
>>>>      at 
>>>> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(DefaultTransactionManager.java:87)
>>>>      at 
>>>> org.apache.cayenne.tx.DefaultTransactionManager.performInLocalTransaction(DefaultTransactionManager.java:59)
>>>>      at 
>>>> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(DefaultTransactionManager.java:52)
>>>>      at 
>>>> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(DefaultTransactionManager.java:40)
>>>>      at 
>>>> org.apache.cayenne.tx.TransactionFilter.onSync(TransactionFilter.java:70)
>>>>      at 
>>>> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(DataDomain.java:764)
>>>>      at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:590)
>>>>      at 
>>>> org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:742)
>>>>      ... 18 more
>>>>
>>>> This again points to this mail thread: 
>>>> http://cayenne.195.n3.nabble.com/Erratic-AshwoodEntitySorter-NPE-on-Latest-Snapshot-td4027453.html#a4028225
>>>>  
>>>> <http://cayenne.195.n3.nabble.com/Erratic-AshwoodEntitySorter-NPE-on-Latest-Snapshot-td4027453.html#a4028225>
>>>> and the NPE message is actually an output of the mentioned commit that 
>>>> Andrus added at the time, but the mail thread stopped there in December.
>>>>
>>>> The mentioned class PDCUserLeafletLog has @SortWeight(1000), inherited 
>>>> from the CayenneDataObject subclass that I use for everything. I assigned 
>>>> lower sort weights, starting at 1, for the main root classes that should 
>>>> be inserted first, incrementing for each relationship from there.
>>>>
>>>> So at this point, I'm at a loss how to solve this. Any help is greatly 
>>>> appreciated.
>>>>
>>>> Thanks
>>>> Maik
>>>>
>>>
>>
>>
>>
>> --
>> Best regards,
>> Nikita Timofeev
>



-- 
Best regards,
Nikita Timofeev

Reply via email to