Re: Generating an ERD from Cayenne Model

2024-02-07 Thread Andrus Adamchik
Hi Andrew,

Cool! IMO Cayenne model metadata is generally underused, as most developers 
(myself included) are focusing on the ORM aspect of the framework, and ignore 
the possibilities that an easily-accessible model brings to the table. So 
thanks for the example.

Andrus

> On Feb 7, 2024, at 3:01 PM, Andrew Lindesay  wrote:
> 
> Hello;
> 
> Possibly of interest; I recently needed to update an ERD and decided to try 
> scripting it's production from a Cayenne data model file [1] using the 
> open-source Graphor application.
> 
> [1] http://www.lindesay.co.nz/blog/2024/2024-hds-model-to-graphor/
> 
> Regards.
> 
> -- 
> Andrew Lindesay



Re: How to use a custom aggregate function?

2024-01-05 Thread Andrus Adamchik
> Thanks for the quick reply. I tried #1 but both constructors of
> ASTAggregateFunctionCall are package private.

Oh well. Indeed, we need a better abstraction there.


> Option #2 I tried using the alias in the count to check in the
> SQLTreeProcessor when to change it to another function, i.e.
> 
> property.count().alias("__ARRAY_AGG__");


Ah, a nice shortcut. I was thinking more along the lines of 
"someProperty.function("array_agg", List.class)", and then generating your own 
logic for the GROUP BY clause, which is more involved, but also more reliable.

Andrus


> On Jan 5, 2024, at 4:18 AM, Mark Stobbe  wrote:
> 
> Hi Andrus,
> 
> Thanks for the quick reply. I tried #1 but both constructors of
> ASTAggregateFunctionCall are package private.
> Option #2 I tried using the alias in the count to check in the
> SQLTreeProcessor when to change it to another function, i.e.
> 
> property.count().alias("__ARRAY_AGG__");
> 
> ...
> 
> protected Optional onFunctionNode(Node parent, FunctionNode child, int
> index)
> {
> if ("__ARRAY_AGG__".equals(child.getAlias()))
> {
> return Optional.of(new FunctionNode("ARRAY_AGG", null));
> }
> 
> return Optional.empty();
> }
> 
> Problem here is that the return type doesn't match with the count causing:
> 
> Caused by: org.postgresql.util.PSQLException: Bad value for type long :
> {123,456}
> at org.postgresql.jdbc.PgResultSet.toLong(PgResultSet.java:3233)
> at org.postgresql.jdbc.PgResultSet.getLong(PgResultSet.java:2449)
> at
> io.agroal.pool.wrapper.ResultSetWrapper.getLong(ResultSetWrapper.java:158)
> at
> org.apache.cayenne.access.types.LongType.materializeObject(LongType.java:37)
> at
> org.apache.cayenne.access.types.LongType.materializeObject(LongType.java:28)
> at
> org.apache.cayenne.access.jdbc.reader.ScalarRowReader.readRow(ScalarRowReader.java:50)
> at
> org.apache.cayenne.access.jdbc.reader.CompoundRowReader.readRow(CompoundRowReader.java:47)
> at
> org.apache.cayenne.access.jdbc.reader.CompoundRowReader.readRow(CompoundRowReader.java:28)
> at
> org.apache.cayenne.access.jdbc.JDBCResultIterator.nextRow(JDBCResultIterator.java:104)
> at
> org.apache.cayenne.access.jdbc.LimitResultIterator.nextRow(LimitResultIterator.java:115)
> at
> org.apache.cayenne.access.jdbc.LimitResultIterator.allRows(LimitResultIterator.java:95)
> at
> org.apache.cayenne.access.jdbc.SelectAction.performAction(SelectAction.java:139)
> at
> org.apache.cayenne.access.DataNodeQueryAction.runQuery(DataNodeQueryAction.java:97)
> at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> 
> Best regards,
> Mark
> 
> On Thu, Jan 4, 2024 at 5:57 PM Andrus Adamchik  wrote:
> 
>> Hi Marc,
>> 
>> Upgrading to 4.2 final is probably a good idea regardless of the
>> aggregation function use :)
>> 
>> Regarding your question. There are a few ways to approach it (and I wish
>> we could abstract it a bit better) :
>> 
>> 1. Instead of someProperty.function(..), try to create a subclass of
>> ASTAggregateFunctionCall. E.g. you can follow an expample of ASTMin.
>> 2. You can customize the generated SQL via a custom SQLTreeProcessor
>> (something that was mentioned a few months ago in a different context)
>> 
>> I am really curious if #1 works, and if it doesn't, be happy to provide
>> pointers on #2.
>> 
>> Thanks,
>> Andrus
>> 
>> 
>>> On Jan 4, 2024, at 10:12 AM, Mark Stobbe  wrote:
>>> 
>>> Hi all,
>>> 
>>> Does anyone know how to use "array_agg" as a function? I am using Cayenne
>>> 4.2.M3, but it's ok if I need to upgrade to a later version.
>>> 
>>> I was trying with someProperty.function("array_agg", List.class)
>>> but it will not automatically group by all the other fields since it
>>> doesn't recognise it as a ASTAggregateFunctionCall
>>> 
>>> Mark
>> 
>> 



Re: How to use a custom aggregate function?

2024-01-04 Thread Andrus Adamchik
Hi Marc,

Upgrading to 4.2 final is probably a good idea regardless of the aggregation 
function use :) 

Regarding your question. There are a few ways to approach it (and I wish we 
could abstract it a bit better) :

1. Instead of someProperty.function(..), try to create a subclass of 
ASTAggregateFunctionCall. E.g. you can follow an expample of ASTMin.
2. You can customize the generated SQL via a custom SQLTreeProcessor (something 
that was mentioned a few months ago in a different context) 

I am really curious if #1 works, and if it doesn't, be happy to provide 
pointers on #2.

Thanks,
Andrus


> On Jan 4, 2024, at 10:12 AM, Mark Stobbe  wrote:
> 
> Hi all,
> 
> Does anyone know how to use "array_agg" as a function? I am using Cayenne
> 4.2.M3, but it's ok if I need to upgrade to a later version.
> 
> I was trying with someProperty.function("array_agg", List.class)
> but it will not automatically group by all the other fields since it
> doesn't recognise it as a ASTAggregateFunctionCall
> 
> Mark



Re: How to deal with localized content in the db

2023-11-01 Thread Andrus Adamchik
Hi Riccardo,

The best practice is to actually map all those localized columns as explicit 
properties (Cayenne ObjAttributes), and deal with language switching in the 
code layer above Cayenne. 

Thanks,
Andrus


> On Nov 1, 2023, at 4:27 AM, Riccardo De Menna  wrote:
> 
> Hi Everyone,
> 
> I was wondering if someone could point out a best practice on how to deal 
> with localized content in the db. I come from the webobjects world where I 
> would just flag a property in the eomodel as localizable. Then fetching from 
> name, email, address columns would actually take data from name_en, email_en, 
> address_en and such. I’m sure this must be something people have dealt with 
> before.
> 
> Regards,
> Riccardo De Menna



ApacheCon in Halifax in October

2023-08-10 Thread Andrus Adamchik
Hi,

With my ongoing move from Europe to North America, I am thinking of going to 
"Community over Code" (ex. ApacheCon) in Halifax in October - 
https://communityovercode.org/ . Not presenting anything, just to hang around.

Anyone in the Cayenne community is in the area and/or planning to attend? Would 
be great to meet people. It's been a long time since I've gone to any 
conferences :) 

Andrus




Re: Cayenne 4.2 and 'To Dep PK' direction

2023-06-07 Thread Andrus Adamchik
Hi Tore,

I wonder what type of errors are you getting due to that?

Andrus 

> On Jun 7, 2023, at 12:26 AM, Tore Halset  wrote:
> 
> Hello.
> 
> Trying to upgrade an old large app from cayenne 4.1.1 to 4.2. We get lots of 
> test fails with cayenne 4.2. Every fail so far has been that our model has 
> "To Dep PK" set the wrong way in our model.
> 
> Can it be that Cayenne 4.2 is more strict on having "To Dep PK" the correct 
> way than 4.1.1 was?
> 
> Luckily we have pretty good test coverage on this and I am happy to fix those 
> wrong "To Dep PK"s in our model, but this might be something to look out for 
> for others as well.
> 
> Regards,
> Tore Halset.



[ANN] Cayenne 4.2 goes GA

2023-05-29 Thread Andrus Adamchik
Very happy to announce that we have a final GA release of Cayenne 4.2 available.

It contains a number of bug fixes, most notable being a fix for the recent 
nasty issue that resulted in missing objects in commits for certain mappings. 
But of course it is also a huge milestone that was more than 3 years in the 
making. Since 4.1 we developed a number of new features. I will try to record a 
video or write a blog post presenting them in more detail, but let me quickly 
list them here:

1. Runtime:

* Callback annotations on entity classes
* Customizable SQL generator API 
* Nested queries
* Ordering on aggregate functions
* Property API is made type-specific
* Custom functions and operators in queries
* New attributes types: JSON, geospatial

2. Modeler:

* Acquire drivers from Maven Central
* Improvements to attribute and relationships mapping
* Lots of bug fixes in DB Import, etc.

3. A few modules got deprecated as irrelevant and will be removed in 5.0:

* ROP-related modules
* cayenne-web
* clustering transports (cayenne-xmpp, etc.)
* ...

And of course we are not going to stop and are looking forward to Cayenne 5.0 
where we are planning to tackle limitations in inheritance mapping, improve 
query APIs, etc., etc. The list of new things is quite long already. 

Finally, some links:

* 4.2 release notes: 
https://github.com/apache/cayenne/blob/STABLE-4.2/RELEASE-NOTES.txt
* Modeler download: https://cayenne.apache.org/download/

Andrus

Re: Join ordering

2023-05-21 Thread Andrus Adamchik
Hi Mark,

SQL translator in 4.2 is highly customizable via SQLTreeProcessor (returned 
from DbAdapter). So can you rearrange your joins with a custom adapter / tree 
processor.

Before you do that, please confirm whether this is still a problem with a newer 
version of Cayenne. Either with 4.2.RC2 (released) or the 4.2 final (upcoming, 
temporarily available at [1], and soon to be promoted to Central.

Andrus

[1] https://repository.apache.org/content/repositories/orgapachecayenne-1052/


> On May 21, 2023, at 1:19 AM, Mark Stobbe  wrote:
> 
> Hi all,
> 
> We are running into an issue with the specific join ordering that Cayenne (
> 4.2.M3) does. We are using a ColumnSelect to select multiple columns across
> different tables with a simple where statement.
> 
> SELECT * FROM my_table t0 LEFT JOIN my_detail1 t1 ON t0.fk_one = t1.id LEFT
> JOIN my_detail2 t2 ON t0.fk_two = t2.id LEFT JOIN my_detail3 t3 ON
> t0.fk_three = t3.id LEFT JOIN my_detail4 t4 ON t0.fk_four = t4.id
> ... JOIN my_children t12 ON t0.id = t12.fk_parent WHERE ( ((t12.c_from >=
> '2023-05-16 10:00:00' AND t12.c_from <= '2023-05-17 10:00:00') OR (t12.c_to
>> = '2023-05-16 10:00:00' AND t12.c_to <= '2023-05-17 10:00:00'))
> )
> ...
> LIMIT 25
> 
> This query takes approx. 30 seconds
> where as if I manually change the ordering of the joins to:
> 
> SELECT * FROM my_table t0
> JOIN my_children t12 ON t0.id = t12.fk_parent LEFT JOIN my_detail1 t1 ON
> t0.fk_one = t1.id LEFT JOIN my_detail2 t2 ON t0.fk_two = t2.id LEFT JOIN
> my_detail3 t3 ON t0.fk_three = t3.id LEFT JOIN my_detail4 t4 ON t0.fk_four
> = t4.id
> ... WHERE ( ((t12.c_from >= '2023-05-16 10:00:00' AND t12.c_from <=
> '2023-05-17 10:00:00') OR (t12.c_to >= '2023-05-16 10:00:00' AND t12.c_to
> <= '2023-05-17 10:00:00'))
> )
> ...
> LIMIT 25
> 
> Then the query returns in a few milliseconds.
> Can we somehow indicate the join ordering or at least prefer joins from the
> where to go before the joins needed for the select ?
> 
> Mark



Re: Force update of column

2023-04-28 Thread Andrus Adamchik
Hi Lon,

certainly not via "standard" means. That logic is not configurable. But 
everything is customizable of course :) 

Thanks,
Andrus

> On Apr 27, 2023, at 12:09 AM, Lon Varscsak  wrote:
> 
> Hey all,
> 
> I of course have an unusual situation that I'm not sure how to handle.  :)
> 
> I was going to write a lot of background, but I don't know if it would help
> or just confuse the situation. 藍
> 
> The situation I have is in one specific situation, I'd like Cayenne to
> always add an attribute to the UPDATE/INSERT statements, not just if the
> value is changed.  Can you think of any way to achieve that?
> 
> Thanks,
> 
> Lon



Re: Graal (Native Image) with Cayenne

2023-04-05 Thread Andrus Adamchik
Yeah, would be great if you could share the JSON, but also outline the overall 
approach. And if this JOSN file is required for the process, we'd need a way to 
test and maintain it going forward.

Andrus


> On Apr 5, 2023, at 1:58 PM, Andrew Lindesay  wrote:
> 
> Hi Andrus;
> 
> Thanks for coming back to me.  It seems that for my situation, I need to let 
> the build tool know that each of the "injectable" classes should be allowed 
> to be scanned for constructors in the build product by supplying the Graal 
> build-tool with;
> 
> ```
> -H:ReflectionConfigurationFiles=/...path.../reflection.json
> ```
> 
> The snipped `reflection.json` file looks like;
> 
> ```
> [
>  {
>"name": "org.apache.cayenne.access.DataDomain",
>"queryAllDeclaredConstructors": true
>  },
>  {
>"name": 
> "org.apache.cayenne.access.dbsync.DefaultSchemaUpdateStrategyFactory",
>"queryAllDeclaredConstructors": true
>  },
>  ... continued 
> ]
> ```
> 
> There are entries for 117 classes.  It seems this file can be supplied with 
> the library jar in some way in order to instruct the Graal build tool.  Maybe 
> once I have this fully working I can add a PR for it to cover the known 
> classes in the jar(s).
> 
> Regards.
> 
> -- 
> Andrew Lindesay
> 
> On Wed, 5 Apr 2023, at 20:31, Andrus Adamchik wrote:
>> Hi Andrew,
>> 
>> I don't have first-hand experience, but Cayenne was reported to work 
>> with GraalVM. E.g.: 
>> https://lists.apache.org/list?user@cayenne.apache.org:2023-1:graalvm
>> 
>> Andrus
>> 
>> 
>>> On Apr 5, 2023, at 10:26 AM, Andrew Lindesay  wrote:
>>> 
>>> Hello;
>>> 
>>> Has anybody here experimented with running an application using Cayenne 
>>> with the GraalVM "native image" compiler?  The resultant executable seems 
>>> to be having a problem with the DI system at run time; probably because 
>>> there's some reflection going on in there -- seems likely.  Is there any 
>>> documentation / guidance about how to start the `ServerRuntime` without the 
>>> DI mechanism?
>>> 
>>> Caused by: org.apache.cayenne.di.DIRuntimeException: No applicable 
>>> constructor is found for constructor injection in class 
>>> 'org.apache.cayenne.log.Slf4jJdbcEventLogger'
>>> at 
>>> org.apache.cayenne.di.spi.ConstructorInjectingProvider.initConstructor(ConstructorInjectingProvider.java:103)
>>>  ~[na:na]
>>> at 
>>> org.apache.cayenne.di.spi.ConstructorInjectingProvider.(ConstructorInjectingProvider.java:42)
>>>  ~[na:na]
>>> at 
>>> org.apache.cayenne.di.spi.DefaultBindingBuilder.to(DefaultBindingBuilder.java:44)
>>>  ~[na:na]
>>> at 
>>> org.apache.cayenne.configuration.server.ServerModule.configure(ServerModule.java:349)
>>>  ~[na:na]
>>> at 
>>> org.apache.cayenne.di.spi.DefaultInjector.(DefaultInjector.java:68) 
>>> ~[na:na]
>>> at 
>>> org.apache.cayenne.di.DIBootstrap.createInjector(DIBootstrap.java:38) 
>>> ~[na:na]
>>> at 
>>> org.apache.cayenne.di.DIBootstrap.createInjector(DIBootstrap.java:46) 
>>> ~[na:na]
>>> at 
>>> org.apache.cayenne.configuration.CayenneRuntime.(CayenneRuntime.java:79)
>>>  ~[haikudepotserver-webapp:4.1.1]
>>> at 
>>> org.apache.cayenne.configuration.server.ServerRuntime.(ServerRuntime.java:75)
>>>  ~[haikudepotserver-webapp:4.1.1]
>>> at 
>>> org.apache.cayenne.configuration.server.ServerRuntimeBuilder.build(ServerRuntimeBuilder.java:207)
>>>  ~[na:na]
>>> 
>>> Regards.
>>> 
>>> -- 
>>> Andrew Lindesay



Re: Graal (Native Image) with Cayenne

2023-04-05 Thread Andrus Adamchik
Hi Andrew,

I don't have first-hand experience, but Cayenne was reported to work with 
GraalVM. E.g.: 
https://lists.apache.org/list?user@cayenne.apache.org:2023-1:graalvm

Andrus


> On Apr 5, 2023, at 10:26 AM, Andrew Lindesay  wrote:
> 
> Hello;
> 
> Has anybody here experimented with running an application using Cayenne with 
> the GraalVM "native image" compiler?  The resultant executable seems to be 
> having a problem with the DI system at run time; probably because there's 
> some reflection going on in there -- seems likely.  Is there any 
> documentation / guidance about how to start the `ServerRuntime` without the 
> DI mechanism?
> 
> Caused by: org.apache.cayenne.di.DIRuntimeException: No applicable 
> constructor is found for constructor injection in class 
> 'org.apache.cayenne.log.Slf4jJdbcEventLogger'
>   at 
> org.apache.cayenne.di.spi.ConstructorInjectingProvider.initConstructor(ConstructorInjectingProvider.java:103)
>  ~[na:na]
>   at 
> org.apache.cayenne.di.spi.ConstructorInjectingProvider.(ConstructorInjectingProvider.java:42)
>  ~[na:na]
>   at 
> org.apache.cayenne.di.spi.DefaultBindingBuilder.to(DefaultBindingBuilder.java:44)
>  ~[na:na]
>   at 
> org.apache.cayenne.configuration.server.ServerModule.configure(ServerModule.java:349)
>  ~[na:na]
>   at 
> org.apache.cayenne.di.spi.DefaultInjector.(DefaultInjector.java:68) 
> ~[na:na]
>   at 
> org.apache.cayenne.di.DIBootstrap.createInjector(DIBootstrap.java:38) ~[na:na]
>   at 
> org.apache.cayenne.di.DIBootstrap.createInjector(DIBootstrap.java:46) ~[na:na]
>   at 
> org.apache.cayenne.configuration.CayenneRuntime.(CayenneRuntime.java:79)
>  ~[haikudepotserver-webapp:4.1.1]
>   at 
> org.apache.cayenne.configuration.server.ServerRuntime.(ServerRuntime.java:75)
>  ~[haikudepotserver-webapp:4.1.1]
>   at 
> org.apache.cayenne.configuration.server.ServerRuntimeBuilder.build(ServerRuntimeBuilder.java:207)
>  ~[na:na]
> 
> Regards.
> 
> -- 
> Andrew Lindesay



Re: Possible regression on 4.2.RC2

2023-03-09 Thread Andrus Adamchik
Hi Henrique,

Thanks for your feedback and testing!

> IMO, if RC2 has this unexpected behaviour (!) maybe we should discourage its 
> usage? I know, it’s only a RC, but Cayenne has always been so stable for me, 
> never thought twice of using RCs.

I'd say we outrun this by releasing "4.2 final" quickly. It is about time I 
think.

Andrus


> On Mar 9, 2023, at 9:00 PM, Henrique Gomes  wrote:
> 
> Hi Nikita,
> 
> Thank you for the feedback!
> I have good news, I could not reproduce the fault after cherry picking that 
> commit on top of 4.2RC2! All my objects were saved on every attempt.
> 
> Just for completeness, `mvn package` in that configuration fails with:
> 
> [ERROR] Failures:
> [ERROR]   OpIdFactoryTest.testEqualsAndHashCode:57 
> expected:<> but 
> was:<>
> 
> But that seems to have been fixed in 
> https://github.com/apache/cayenne/commit/78868d820fd30cf088846e6f89619e91a4206fad
> 
> 
> I’ve also tested STABLE-4.2 (current at 
> e6f2f59f369a9fdf5575d35b47f2ac30ee050da3) and all looks good there too.
> 
> IMO, if RC2 has this unexpected behaviour (!) maybe we should discourage its 
> usage? I know, it’s only a RC, but Cayenne has always been so stable for me, 
> never thought twice of using RCs.
> 
> For now, I’ll stay with RC1. It’s quite cumbersome for me to use anything 
> other than official releases on production, too much work to setup the CI to 
> build my own version of a library. Hoping the next version will be out soon.
> 
> Thank you again for your help!
> 
> Kind regards,
> 
> Henrique Gomes
> 
> 
>> On 9 Mar 2023, at 09:37, Nikita Timofeev  wrote:
>> 
>> Also I've described exact cause of the problem in this issue
>> https://issues.apache.org/jira/browse/CAY-2801
>> 
>> On Thu, Mar 9, 2023 at 11:25 AM Nikita Timofeev
>>  wrote:
>>> 
>>> Hi!
>>> 
>>> Thanks for the information and even more for the debugging you already did.
>>> There was a commit a bit after 4.2.RC2 was released that could be
>>> related to your problem.
>>> Would be great if you could try it and see if it helps.
>>> 
>>> https://github.com/apache/cayenne/commit/53c9408e026d926601baf6e68b9761489c273397
>>> 
>>> On Wed, Mar 8, 2023 at 6:26 PM Henrique Gomes  wrote:
 
 
 Hello,
 
 I want to ask for help debugging an issue:
 
 On January I updated Cayenne from 4.2.RC1 to 4.2.RC2.
 Immediately after that, we had an issue of objects not being persisted to 
 the db; an http endpoint on our service accepts a batch of records and 
 creates objects to save:
 
 ObjectContext ctx = server.newContext();
 
 for (Aggregation post : request.getEntries()) {
 
   MyDataObject dbo = ctx.newObject(MyDataObject.class);
 
   dbo.setValueDate(post.getValueDate());
 
   dbo.setVersion(post.getVersion());
 
   dbo.setUuid(post.getUuidBytes());
 
   ... etc ...
   }
 
 try {
 
   ctx.commitChanges();
 
 
 The endpoint is called with up to 250 items at a time, and we store ~4000 
 on each daily run of that job.
 We found that after the update, a small number, like 2 sometime more, 
 records would be missing from the db, but not always.
 
 
 Rolling back seemed to solve the issue. Puzzled, I tried git bisecting 
 Cayenne from RC1 to RC2.
 This is was the result:
 
 
 7bc235f92e2e61d3f4f04d3bebb65a1756d2e092 is the first bad commit
 commit 7bc235f92e2e61d3f4f04d3bebb65a1756d2e092
 Author: Nikita Timofeev 
 Date:   Mon Nov 21 12:59:45 2022 +0300
 
   CAY-2777 Reverse relationship is not set with single table inheritance
 
 .../access/flush/DefaultDataDomainFlushAction.java |   3 +-
 .../apache/cayenne/access/flush/EffectiveOpId.java |   2 +-
 .../access/flush/operation/OpIdFactory.java| 113 ++
 .../org/apache/cayenne/map/ObjRelationship.java|  13 +-
 .../java/org/apache/cayenne/ManyToManyJoinIT.java  |  27 +
 .../SelfRelationship.java  |  28 +
 .../SelfRelationshipSub.java   |  28 +
 .../auto/_Author.java  |   7 +-
 .../auto/_SelfRelationship.java| 132 
 +
 .../auto/_SelfRelationshipSub.java |  91 ++
 .../auto/_Song.java|  10 +-
 .../relationships-many-to-many-join.map.xml|  37 +-
 12 files changed, 472 insertions(+), 19 deletions(-)
 create mode 100644 
 cayenne-server/src/main/java/org/apache/cayenne/access/flush/operation/OpIdFactory.java
 create mode 100644 
 cayenne-server/src/test/java/org/apache/cayenne/testdo/relationships_many_to_many_join/SelfRelationship.java
 create mode 100644 
 cayenne-server/src/test/java/org/apache/cayenne/testdo/relationships_many_to_many_join/SelfRelationshipSub.java
 

[ANN] Cayenne 4.0.3 released

2023-03-04 Thread Andrus Adamchik
Hi, a maintenance release of the older Cayenne 4.0 was posted earlier this 
week. It would allow 4.0 users to run CayenneModeler on Java 17. So if you 
haven't upgraded your code base yet, you should still be able to work with your 
models.

Enjoy!
Andrus

Re: Cayenne web module deprecated

2023-01-31 Thread Andrus Adamchik
Yeah, there's so many ways to create a (web) app these days, that we can't 
support them all properly.

Andrus

> On Jan 31, 2023, at 5:49 PM, John Huss  wrote:
> 
> The web module provides a very small amount of functionality that is pretty
> easy to copy into your own application. I'd suggest looking at the code of
> CayenneFilter
> 
> to see how it works.
> 
> With two servlet options now - javax and jakarta and the limitations
> stemming from defining the runtime fully in the web.xml file, it was
> decided that the web module would be better left as sample code for users
> to implement in their own projects.
> 
> 
> 
> On Tue, Jan 31, 2023 at 1:06 AM Markus Reich  wrote:
> 
>> Hi,
>> 
>> I saw that the web module is deprecated since 4.2
>> I checked the DB First docu of 4.2. but there's the module still in use?
>> What is the new way to use cayenne with J2EE apps?
>> 
>> best regards
>> Meex
>> 



Re: Sharing models?

2023-01-21 Thread Andrus Adamchik
Hi Paul,

You are right. If your models are in different Cayenne projects, they are only 
combined in runtime, and there's no easy way of creating relationships between 
them. And looks like you've already found the workarounds.

I've had a case like yours, where I ended up creating those relationships 
dynamically in the code using "generic" properties. Technically it works, but 
takes away from the dev experience. So I'd go with one of the alternatives that 
you mentioned if possible.

In the future I'd like to see such a feature in Cayenne. When we looked at it 
previously, we ran into a design problem - how can CayenneModeler discover 
those upstream models are in a portable way. I.e. it should would work with 
version control, should resolve the same way on any developer machine, and be 
agnostic of the IDE and build tools. Be happy to brainstorm this further.

Thanks,
Andrus


> On Jan 20, 2023, at 4:26 PM, Paul L. Merchant Jr. 
>  wrote:
> 
> Hi again,
> 
> I have another question coming from EnterpriseObjects land:  I have a 
> situation where two different applications each have their own application 
> specific set of tables in their own schemas and share a third set of tables 
> in another schema.  Each application has tables with relationships to the 
> shared tables, but the applications are not related to each other.
> 
> In EnterpriseObjects it's possible to create separate models of the shared 
> tables and each application's private tables so that one copy of the model of 
> the shared tables can be shared between the applications.
> 
> Can something similar be done in Cayenne?  It appears that multiple projects 
> can be imported into a runtime easily enough, but I'm missing how I can 
> create relationships between objects in two different projects.  The 
> alternatives I see are to either duplication the model of the shared tables 
> in each application's project or including all the models in one project, 
> both of which are less than ideal.  Maybe I've missed something?
> 
> Thanks!
> 
> -- Paul



Re: New user: Cayenne Modeler bug?

2023-01-13 Thread Andrus Adamchik
Hi Paul,

Thanks for the detailed report. Yeah, EOModel importer due to its nature 
(people import their projects once, and then stay on Cayenne and never come 
back) has its share of issues. I just logged a Jira [1], but for now I 
recommend manually removing the failing qualifier from the source EOModel to be 
able to finish the rest of the import, and then manually enter this qualifier 
for the mapped Cayenne query corresponding to this EOFetchSpecification.

Andrus

[1] https://issues.apache.org/jira/browse/CAY-2790


> On Jan 13, 2023, at 7:07 PM, Paul L. Merchant Jr. 
>  wrote:
> 
> Hi everyone, I'm evaluating Cayenne as a replacement for a EnterpriseObjects 
> in a legacy code base. I think I've run into a bug in CayenneModeler 4.2.RC2 
> while importing one of my EOFetchSpecifications:
> 
> CayenneModeler Info
> Version: 4.2.RC2
> Build Date: Dec 01 2022 08:35:36
> Exception: 
> =
> org.apache.cayenne.exp.ExpressionException: [v.4.2.RC2 Dec 01 2022 08:35:36] 
> And: invalid child - null
>   at 
> org.apache.cayenne.exp.parser.AggregateConditionNode.jjtAddChild(AggregateConditionNode.java:94)
>   at 
> org.apache.cayenne.exp.parser.SimpleNode.setOperand(SimpleNode.java:325)
>   at 
> org.apache.cayenne.exp.ExpressionFactory.joinExp(ExpressionFactory.java:1298)
>   at 
> org.apache.cayenne.exp.ExpressionFactory.joinExp(ExpressionFactory.java:1270)
>   at 
> org.apache.cayenne.wocompat.EOQuery$EOFetchSpecificationParser.makeQualifier(EOQuery.java:413)
>   at 
> org.apache.cayenne.wocompat.EOModelProcessor.makeEOQueryDescriptor(EOModelProcessor.java:266)
>   at 
> org.apache.cayenne.wocompat.EOModelProcessor.makeQuery(EOModelProcessor.java:223)
>   at 
> org.apache.cayenne.wocompat.EOModelProcessor.loadEOModel(EOModelProcessor.java:180)
>   at 
> org.apache.cayenne.wocompat.EOModelProcessor.loadEOModel(EOModelProcessor.java:105)
>   at 
> org.apache.cayenne.modeler.action.ImportEOModelAction.importEOModel(ImportEOModelAction.java:124)
>   at 
> org.apache.cayenne.modeler.action.ImportEOModelAction.performAction(ImportEOModelAction.java:88)
>   at 
> org.apache.cayenne.modeler.util.CayenneAction.actionPerformed(CayenneAction.java:171)
>   at 
> java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
>   at 
> java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
>   at 
> java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
>   at 
> java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
>   at 
> java.desktop/javax.swing.AbstractButton.doClick(AbstractButton.java:374)
>   at 
> java.desktop/com.apple.laf.ScreenMenuItem.actionPerformed(ScreenMenuItem.java:129)
>   at java.desktop/java.awt.MenuItem.processActionEvent(MenuItem.java:692)
>   at java.desktop/java.awt.MenuItem.processEvent(MenuItem.java:651)
>   at 
> java.desktop/java.awt.MenuComponent.dispatchEventImpl(MenuComponent.java:379)
>   at 
> java.desktop/java.awt.MenuComponent.dispatchEvent(MenuComponent.java:367)
>   at 
> java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:776)
>   at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
>   at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
>   at 
> java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
>   at 
> java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
>   at 
> java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
>   at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:746)
>   at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:744)
>   at 
> java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
>   at 
> java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
>   at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743)
>   at 
> java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
>   at 
> java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
>   at 
> java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
>   at 
> java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
>   at 
> java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
>   at 
> java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
> 
> 
> The relevant fetch specification is relatively straightforward:
> 
>   qualifier = {
>class = EOAndQualifier;
>qualifiers = (
>{
>

Re: Cayenne and GraalVM

2023-01-12 Thread Andrus Adamchik
Possibly. Though ServiceLoader that does auto-loading is pretty standard Java 
API. 


> On Jan 12, 2023, at 9:11 PM, Michael Gentry  wrote:
> 
> Is that due to reflection?
> 
> On Wed, Jan 11, 2023 at 8:09 AM Andrus Adamchik  wrote:
> 
>> And per the latest comments in that task, Cayenne actually works with
>> Graal, just not the module auto-loading part:
>> 
>> ServerRuntime.builder()
>> 
>>  // no autoloading, each module will need to be explicitly added below
>>  .disableModulesAutoLoading()
>> 
>>  // add the main Cayenne module
>>  .addModule(new ServerModule())
>> 
>>   // ...
>>  .build();
>> Andrus
>> 
>>> On Jan 10, 2023, at 9:57 AM, Andrus Adamchik 
>> wrote:
>>> 
>>> FYI: https://github.com/oracle/graal/issues/5716
>>> 
>>> A discussion on how to package a Cayenne app to a native executable with
>> Graal. If anyone tried doing that before and has some experience, feel free
>> to chime in.
>>> 
>>> Andrus
>> 
>> 



Re: Cayenne and GraalVM

2023-01-11 Thread Andrus Adamchik
And per the latest comments in that task, Cayenne actually works with Graal, 
just not the module auto-loading part:

ServerRuntime.builder()

  // no autoloading, each module will need to be explicitly added below
  .disableModulesAutoLoading() 

  // add the main Cayenne module
  .addModule(new ServerModule())

   // ...
  .build();
Andrus

> On Jan 10, 2023, at 9:57 AM, Andrus Adamchik  wrote:
> 
> FYI: https://github.com/oracle/graal/issues/5716
> 
> A discussion on how to package a Cayenne app to a native executable with 
> Graal. If anyone tried doing that before and has some experience, feel free 
> to chime in.
> 
> Andrus



Cayenne and GraalVM

2023-01-10 Thread Andrus Adamchik
FYI: https://github.com/oracle/graal/issues/5716

A discussion on how to package a Cayenne app to a native executable with Graal. 
If anyone tried doing that before and has some experience, feel free to chime 
in.

Andrus

Re: Regression from 4.2-RC2 to 4.2-RC3

2022-12-14 Thread Andrus Adamchik
> where two ObjectIds could really represent different operations even if their
> snapshots are equal.

Ah, this is what it is. I was wondering how a seemingly logical and clean fix 
could've broken anything :) 



> On Dec 14, 2022, at 1:17 PM, Nikita Timofeev  
> wrote:
> 
> Hi Lon.
> 
> I think this new fix is incompatible with meaningful PKs, where two
> ObjectIds could really represent different operations even if their
> snapshots are equal. And IIRC that is exactly your case.
> Will think if there's a good way to fix this. In the meantime you
> could just safely rollback to 4.2.RC1, there are no major issues fixed
> in RC2 (this one causing your troubles and the one about split path
> expressions).
> 
> On Wed, Dec 14, 2022 at 10:46 AM Andrus Adamchik  wrote:
>> 
>> Correct, we fixed an issue with two identical join table records being 
>> committed in certain cases with inheritance. I'll defer to Nikita to comment 
>> on the effects on your case.
>> 
>> Andrus
>> 
>> 
>>> On Dec 13, 2022, at 10:08 PM, Lon Varscsak  wrote:
>>> 
>>> My guess is the new logic in
>>> DefaultDataDomainFlushAction.mergeSameObjectIds with OpIdFactory has a
>>> flaw.  It's a little above my paygrade to figure out why. 藍
>>> 
>>> On Tue, Dec 13, 2022 at 1:44 PM Lon Varscsak  wrote:
>>> 
>>>> I have a pretty serious regression between these versions.  I'm not 100%
>>>> sure what's going on yet, but figured I'd drop a note and see if anyone has
>>>> any thoughts.  I have a situation where I remove all the objects in a
>>>> relationship, and then reinsert them (same PK).  This has been working in
>>>> 4.2 for a while now (in production), but something changed that when it
>>>> goes to delete the objects in question it only deletes 1 of 4 of them, and
>>>> then tries to insert the same data again resulting in a PK constraint
>>>> violation.
>>>> 
>>>> I vaguely remember there was some work that Nikita had to do to make this
>>>> work..but I have a bad memory. :)
>>>> 
>>>> Also, I'm using the GraphBasedDbRowOpSorter, which is really required to
>>>> do anything meaningful with Sybase and its lack of deferred constraints.
>>>> idk if this could be related...but it's been an issue before.
>>>> 
>>>> Thanks,
>>>> 
>>>> Lon
>>>> 
>> 
> 
> 
> -- 
> Best regards,
> Nikita Timofeev



Re: Regression from 4.2-RC2 to 4.2-RC3

2022-12-13 Thread Andrus Adamchik
Correct, we fixed an issue with two identical join table records being 
committed in certain cases with inheritance. I'll defer to Nikita to comment on 
the effects on your case.

Andrus 


> On Dec 13, 2022, at 10:08 PM, Lon Varscsak  wrote:
> 
> My guess is the new logic in
> DefaultDataDomainFlushAction.mergeSameObjectIds with OpIdFactory has a
> flaw.  It's a little above my paygrade to figure out why. 藍
> 
> On Tue, Dec 13, 2022 at 1:44 PM Lon Varscsak  wrote:
> 
>> I have a pretty serious regression between these versions.  I'm not 100%
>> sure what's going on yet, but figured I'd drop a note and see if anyone has
>> any thoughts.  I have a situation where I remove all the objects in a
>> relationship, and then reinsert them (same PK).  This has been working in
>> 4.2 for a while now (in production), but something changed that when it
>> goes to delete the objects in question it only deletes 1 of 4 of them, and
>> then tries to insert the same data again resulting in a PK constraint
>> violation.
>> 
>> I vaguely remember there was some work that Nikita had to do to make this
>> work..but I have a bad memory. :)
>> 
>> Also, I'm using the GraphBasedDbRowOpSorter, which is really required to
>> do anything meaningful with Sybase and its lack of deferred constraints.
>> idk if this could be related...but it's been an issue before.
>> 
>> Thanks,
>> 
>> Lon
>> 



[ANN] Cayenne 4.2.RC2 release

2022-12-06 Thread Andrus Adamchik
The new release candidate of Cayenne 4.2 (4.2.RC2) is available. It has quite a 
few bug fixes in the Modeler and in the runtime, so we decided to have one more 
RC before a GA release. Also we marked as deprecated the modules that are going 
away in 5.0 to give an advance warning to the users (ROP, web, clustering 
transports). 

Please consider upgrading. If anything, this will make the Modeler look nicer 
on MacOS :) And of course send us feedback so we can make a flawless GA. 

Full release notes: https://cayenne.apache.org/2022/12/cayenne-42rc2-released/

Andrus



Re: Which to pick: Cayenne 4.2 vs. 5.0?

2022-11-21 Thread Andrus Adamchik
Exactly. There's lots of good stuff planned for 5.0, but it is not developed 
yet. So 4.2 is the best choice right now. It is both modern and stable. I also 
use it in prod everywhere. 

4.2 is about to go GA once we figure out how fix some Modeler issues caused by 
the latest MacOS.

Andrus


> On Nov 21, 2022, at 11:56 PM, John Huss  wrote:
> 
> The main feature of 5.0 at this point is the removal of deprecated features
> (like the ROP platform), so either one is a good choice I'd say. But I'd go
> with 4.2.
> 
> On Mon, Nov 21, 2022 at 3:44 PM Hugi Thordarson  wrote:
> 
>> Hi guys!
>> I'm about to be rid of a legacy DB that's been keeping my most important
>> application stuck on a heavily modified Cayenne 4.1 stack. So, finally
>> looking into joining modernity and upgrading Cayenne (yay!).
>> 
>> I see there's a lot of stuff happening in 5.0 at the moment and I'd like
>> to take my "non business-critical" stuff there so I can partake in the fun.
>> 
>> But then there's the more serious (read: paying customer) software. Seeing
>> as how v4.2 is still in the RC stage, with 5.0 receiving active
>> development, would you recommend migrating "real apps" to 4.2 now—or just
>> not bothering, holding out and moving directly to 5.0? Is anyone using the
>> 4.2 RC in production yet?
>> 
>> Cheers,
>> - hugi



Re: About ValueObjectType and Extended types and Collection based objects

2022-10-24 Thread Andrus Adamchik
Hi Riccardo,

Indeed, ValueObjectType and ExtendedType are not generics-aware. Something we 
may need to think about and maybe add to Cayenne. 

What I would recommend in your situation is to map your attributes using custom 
lightweight wrapper types, one class per specific case. E.g. 
CommaSeparatedString, PipeSeparatedDuration. These can be associated with 
ValueObjectTypes. In the code you can use them as is, or create cover methods 
to expose as Lists:

class MyEntity extends _MyEntity {

   List getDurations() {
  return getPipeSeparatedDurations() != null 
 ? getPipeSeparatedDurations().asList() 
 : Collections.emptyList();
   }
}

Andrus


> On Oct 24, 2022, at 8:41 AM, Riccardo De Menna  wrote:
> 
> Hi all,
> 
> I’m new to Cayenne and coming from the WebObjects world I’m trying to figure 
> out how to adjust to the different environment. I was looking for some simple 
> advice on how to do conversions for custom types.
> 
> In particular, how would I go to save a collection based object. Let’s say I 
> have a List and my database is holding data as a string of 
> pipe separated longs representing the epoch millis. In webobjects I would be 
> able to individually map that single column to factory methods and convert 
> them. In cayenne I see I’m supposed to use ValueObjectType (or extended 
> types) but I encountered two issues:
> 
> Issue 1:
> If I want to use List as my value type I can’t return the 
> generic part with getValueType(). And eliminating the generics would make it 
> a useless raw type because it would then clash with any other list based 
> conversion (i.e. List, List bla bla) that requires a 
> different encoding/decoding mechanism.
> One thing that came to mind would be to attempt using a LocalDateTime[].class 
> and then having to converted to a List elsewhere. Is this the 
> only way to go? 
> 
> Issue 2:
> What if my database has different columns holding the same data type but 
> serialized in different ways? I was checking some very old code of mine that 
> I was trying to port and I found that in one cases I had serialized a list of 
> strings as pipe separated and then somewhere else another list of strings as 
> comma separated. How would one go to define different deserialization schemes 
> for the same List object. One based on a specific column of the 
> database?
> 
> Thank you in advance for any support,
> Riccardo De Menna



Re: Any ROP users?

2022-10-04 Thread Andrus Adamchik
Hi Henrique,

Good catch. I wonder if the serialization code causes these vulnerability 
warnings on its own though. Note that org.apache.cayenne.Persistent is declared 
as Serializable, and this you can't change via a custom template (at least not 
yet, see below). So maybe try removing those generated "readState" / 
"writeState" methods by hand and see if it makes a difference. If it does, a 
custom template approach would help you right away.

Whether it is safe to remove it? I'd say yes. Serialization support was 
developed even prior to ROP (even though ROP used it in the early versions). 
Instead, it was about servlet session backup and clustering. Specifically 
Tomcat dumping / restoring HTTP sessions to disk. With REST APIs being the 
prevalent flavor of code running on Tomcat/Jetty these days, I hope not too 
many people need that now (I most certainly don't).

Going forward, I'd love to remove "implements Serializable" from Persistent, 
and make it something the user can do optionally (just like you suggested). In 
5.0 we should make serializability a cgen option, and remove it from the base 
interface.

Let us know whether a custom template fixed it for you though.

Andrus


> On Oct 3, 2022, at 1:42 PM, Henrique Gomes  wrote:
> 
> 
> Hello,
> 
> No, I’m not using ROP either :-) but and also find it neat, and used 
> something similar with
> WebObjects, many moons ago.
> 
> I have been using Cayenne for an internal project, a web service, with quite 
> high traffic,
> Cayenne usage on that, is, for now, on some less frequent called endpoints, 
> trying to
> slowly extend its use, curious to see how it will handle > 1 requests /s.
> 
> What I wanted to add here, is that our internal installation of SonarQube has 
> flagged the
> (de)serialisation as a security vulnerability :-(
> 
> The findings are bellow, in case you want to have a look.
> So, besides adding another data point to the discussion on deprecating ROP, I 
> also need to
> fix this on my project.
> 
> First idea is to just use a custom template and remove everything below the
> "Create serialization support” block. Am I correct in assuming that those 
> methods
> are only used for ROP?
> 
> Many thanks!
> 
> Cheers,
> 
> HG
> 
> 
> 
> 
>  SonarQube findings ———
> 
> Security - Object deserialization is used in {1}
> Vulnerability
> Critical
> cwe
> Available Since
> Mar 27, 2020
> Find Security Bugs (Java)
> Object deserialization of untrusted data can lead to remote code execution, 
> if there is a class in classpath that allows the trigger of malicious 
> operation.
> Libraries developers tend to fix class that provided potential malicious 
> trigger. There are still classes that are known to trigger Denial of 
> Service[1].
> Deserialization is a sensible operation that has a great history of 
> vulnerabilities. The web application might become vulnerable as soon as a new 
> vulnerability is found in the Java Virtual Machine[2] [3].
> Code at risk:
> public UserData deserializeObject(InputStream receivedFile) throws 
> IOException, ClassNotFoundException {
> try (ObjectInputStream in = new ObjectInputStream(receivedFile)) {
> return (UserData) in.readObject();
> }
> }
> Solutions:
> Avoid deserializing object provided by remote users.
> References
> CWE-502: Deserialization of Untrusted Data
> Deserialization of untrusted data
> Serialization and Deserialization
> A tool for generating payloads that exploit unsafe Java object deserialization
> [1] Example of Denial of Service using the class java.util.HashSet
> [2] OpenJDK: Deserialization issue in ObjectInputStream.readSerialData() 
> (CVE-2015-2590)
> [3] Rapid7: Sun Java Calendar Deserialization Privilege Escalation 
> (CVE-2008-5353)
> 
> 
>  SonarQube findings ———
> 
> On 2022/02/11 22:03:03 Aristedes Maniatis wrote:
>> On the heels of the security announcement, there has been discussion on 
>> removing ROP from the next major Cayenne release after 4.2.
>> 
>> ROP was modelled on a similar Java Client feature in Webobjects/EOF and 
>> there is nothing else quite like it in other ORMs. The ability to just 
>> use normal Cayenne operations from the client machine without worrying 
>> about how those operations get to the server and data objects are returned.
>> 
>> It has some limitations:
>> 
>> * limited security. There is no simple way to add an authorisation layer 
>> to restrict access to certain objects or fields. Authentication and 
>> encryption are really simple, but per object authorisation is hard.
>> 
>> * Java client. Although it is possible to write Cayenne in other 
>> languages, no one has done so. There was some work ages ago on 
>> Cocoa/Objective C bindings. Java client UI (swing/javaFX) is not popular 
>> these days.
>> 
>> * upgrading. You need to upgrade the client and server at the same time
>> 
>> 
>> But it is really quite neat. Maybe I'm a bit sentimental since I used to 
>> use it extensively for many years. But I've moved onto 

Re: cdbimport ignores foreign key constrains with SQLite

2022-07-22 Thread Andrus Adamchik


> On Jul 22, 2022, at 3:56 PM, Ali Baharev  wrote:
> 
> FKs have been supported since at least 2009. It does have a well
> documented quirk though: You must enable foreign key support
> explicitly.
> 
> 2. Enabling Foreign Key Support
> https://www.sqlite.org/foreignkeys.html#fk_enable 
> 
> 
> But apart from that, it works like a charm.


IIRC the issue on Cayenne side was with SQLite JDBC driver not bringing over 
the FK metadata during DB import. Again, this was years ago.

A.

Re: cdbimport ignores foreign key constrains with SQLite

2022-07-22 Thread Andrus Adamchik
Last time I checked, SQLite driver didn't support FKs. But this was a long time 
ago, so who knows :)

Derby would certainly support FKs, and the driver is pretty solid.

Andrus

> On Jul 22, 2022, at 3:24 PM, Ali Baharev  wrote:
> 
> Hi,
> 
> I am trying to use cdbimport with the attached toy SQLite database.
> The pom.xml file and the log file are also attached.
> 
> My tables are imported but Cayenne 4.2.RC1 does not recognize any of
> the foreign key constraints. In other words: I can import the tables
> but their relationships are lost.
> 
> I am following the steps in the Cayenne Guide:
> 
> 3. DB-First Flow
> https://cayenne.apache.org/docs/4.2/cayenne-guide/#db-first-flow
> 
> and also the Cayenne Database First tutorial:
> 
> 2. Importing database
> https://cayenne.apache.org/docs/4.2/getting-started-db-first/#importing-database
> 
> What am I doing wrong? Why are my foreign key constraints lost?
> 
> If – for some reason – SQLite is not yet supported, would it work with
> Apache Derby Embedded DB?
> 
> Any help is greatly appreciated.
> 
> Best wishes,
> 
> Ali
> 



Re: SelectQuery deprecation

2022-07-05 Thread Andrus Adamchik
> so it can be changed

so it can be *chained* :)

> On Jul 5, 2022, at 8:47 AM, Andrus Adamchik  wrote:
> 
> Hi Tore,
> 
> Yeah, that's a big one to change. There's no script that I am aware of, and 
> writing a generic one would probably require to work with the Java syntax 
> AST. SelectQuery uses "Java Bean" style with "void" return type of most 
> methods, while ObjectSelect returns "this" (so it can be changed), and most 
> method names have different names. So you can't just "sed" the constructor.
> 
> At the same time, the benefit of the upgrade would be to clean up the code 
> and start using the new style. So you might start by running search/replace 
> on the constructor, and then clean up the rest by hand.
> 
> Andrus
> 
> 
>> On Jul 4, 2022, at 11:15 PM, Tore Halset  wrote:
>> 
>> Hello.
>> 
>> I see that SelectQuery are deprecated and will be removed. I have searched 
>> the mail archive and found the deprecation thread from 2019. Have you moved 
>> away from it in a script based manner or have you re-written all the queries 
>> by hand? We have a lot of them. This is in our biggest project.
>> 
>> % find . -type f -name \*java -exec grep -H new\ SelectQuery {} \;|wc -l
>>546
>> 
>> Regards,
>> Tore Halset,
> 



Re: SelectQuery deprecation

2022-07-05 Thread Andrus Adamchik
Hi Tore,

Yeah, that's a big one to change. There's no script that I am aware of, and 
writing a generic one would probably require to work with the Java syntax AST. 
SelectQuery uses "Java Bean" style with "void" return type of most methods, 
while ObjectSelect returns "this" (so it can be changed), and most method names 
have different names. So you can't just "sed" the constructor.

At the same time, the benefit of the upgrade would be to clean up the code and 
start using the new style. So you might start by running search/replace on the 
constructor, and then clean up the rest by hand.

Andrus


> On Jul 4, 2022, at 11:15 PM, Tore Halset  wrote:
> 
> Hello.
> 
> I see that SelectQuery are deprecated and will be removed. I have searched 
> the mail archive and found the deprecation thread from 2019. Have you moved 
> away from it in a script based manner or have you re-written all the queries 
> by hand? We have a lot of them. This is in our biggest project.
> 
> % find . -type f -name \*java -exec grep -H new\ SelectQuery {} \;|wc -l
> 546
> 
> Regards,
> Tore Halset,



Re: Jetty container not starting

2022-07-04 Thread Andrus Adamchik
Hi Ali,

Thanks for sharing what you do with Cayenne. Yes, a pull request on GitHub 
would be appreciated.

Thanks,
Andrus

> On Jul 4, 2022, at 1:25 PM, Ali Baharev  wrote:
> 
> Dear Andrus,
> 
>> I think that we simply need to
>> remove the "Converting to Web Application" section, which is indeed dated.
> 
> Please don't!
> 
> I am teaching Java for absolute beginners, and Apache Cayenne and this
> tutorial is exactly what I have been looking for.
> 
> I think just pinning down the version numbers to something that we
> know for sure works would solve the issues. And fixing the bugs in the
> text of the tutorial on the website... There were a few of those.
> 
> If there is any interest, I am willing to submit a "patch" and then
> the tutorial will be OK.
> 
> Thanks for this Getting Started Guide, it really helps me giving the
> Java course.
> 
> Best wishes,
> 
> Ali



Re: Jetty container not starting

2022-07-04 Thread Andrus Adamchik
Glad that you were able to find the solution. Honestly, there's so many flavors 
of environments these days, that I think that we simply need to remove the 
"Converting to Web Application" section, which is indeed dated.

Andrus

> On Jul 4, 2022, at 9:57 AM, Ali Baharev  wrote:
> 
> Adding:
> 
>war
> 
> and
>
>org.eclipse.jetty
>jetty-maven-plugin
>9.4.25.v20191220
>
>   war
>   
> 
> seems to solve the problem. I seriously think that the Getting Started
> Guide should be updated on the website. I was not having fun fixing
> this issue.
> 
> Ali



Re: Missing Injector inconsistently

2022-06-24 Thread Andrus Adamchik
Hi Richard,

I assume the exception happens within BaseContext.attachToRuntimeIfNeeded(). 
This whole business of attaching to runtime is a hack for auto-deserialization 
of the context in certain environments. Tomcat does HttpSession serialization 
for the purpose of session clustering (and addressing restarts). Jetty does 
not. IMO clustering of Java sessions is a losing battle, and doesn't scale well 
anyways. I'd recommend to just turn it off [1].

There may be more steps to integrating Cayenne and Tapestry (such as 
implementing ValueEncoder), but not having to deal with serialized 
sessions is definitely step #1 :)

Andrus

[1] 
https://tomcat.apache.org/tomcat-8.5-doc/config/manager.html#Disable_Session_Persistence


> On Jun 23, 2022, at 11:41 PM, Richard Frovarp  wrote:
> 
> I'm using Cayenne 4.1 in the integration I took over to make it just work 
> with Apache Tapestry. I'm getting:
> 
> Can't attach to Cayenne runtime. Null injector returned from 
> CayenneRuntime.getThreadInjector()
> 
> The really confusing part is that it works just fine in Jetty, and it 
> sometimes works in Tomcat. With one project it usually doesn't work in 
> Tomcat, and in another it appears to work just fine.
> 
> So I'm really confused as to what is going on. Watching through an attached 
> debugger, I don't see why it is or isn't using a runtime that already has the 
> injector provided. The integration was created by more talented people than 
> me for Cayenne 3.0, and I see this injector stuff is starting from 3.1. So 
> I'm probably missing something.
> 
> I saw a previous post to the list talking about adding a filter, but that 
> doesn't seem to match what I need here. I probably do need to change the 
> service that is creating the contexts to always setup an injector??
> 
> Any pointers are appreciated.
> 
> Richard



[ANN] Release 4.2.RC1

2022-06-13 Thread Andrus Adamchik
Glad to announce Cayenne 4.2 release candidate. It fixes a few remaining JDK 17 
compatibility issues (Gradle, protostuff/ROP). Also a number of bug fixes. Very 
good chance the next 4.2 release will be "GA".

Full list of bug fixes:

CAY-2711 JDK 17 compatibility
CAY-2728 Add ExtendedType to generate user-friendly exceptions for internally 
used values
CAY-2630 Prefetched relationships not preserving pending changes
CAY-2697 Read-only cgen template creates mutator methods for to-many 
relationships
CAY-2724 Duplicating relationship after editing its name
CAY-2727 Modeler: cgen destDir Unix platform path separator
CAY-2729 Unable to use custom templates from a folder at upper level then 
datamap
CAY-2730 Duplicating lines in a cgen config saved to datamap.xml
CAY-2731 Exception when setting a CLOB on H2 v2.0.202
CAY-2733 Modeler can’t use custom templates set in a datamap
CAY-2734 Improve support for the DECIMAL type
CAY-2736 Can’t use function names as a path in a string-based expression

Cheers,
Andrus

Re: DI container has no binding for key

2022-03-29 Thread Andrus Adamchik
I think you are right. The ClassLoader is a likely culprit here. There's a 
simple way to set a ClassLoader for Cayenne runtime:

  Thread.currentThread().setContextClassLoader(..);

For something more advanced (e.g. to ensure it works across all threads), you 
might define a custom implementation of ClassLoaderManager
DI service [1].

Andrus

[1] https://cayenne.apache.org/docs/4.2/cayenne-guide/#customization-strategies


> On Mar 29, 2022, at 1:00 AM, Stefan Stegic  wrote:
> 
> I think I may have figured it out! I switched to MongoDB with Morphia ODM and 
> had the same problem: works when I run it through main, but throws a 
> ClassNotFound when ran by Spigot. Morphia couldn't locate my entity classes 
> package via its path and I solved it by supplying the class loader of the 
> calling class like so:
> 
> MapperOptions mapperOptions = 
> MapperOptions.builder().classLoader(this.getClass().getClassLoader()).build();
> datastore = Morphia.createDatastore(MongoClients.create(connectionUri), 
> dbName, mapperOptions);
> datastore.getMapper().mapPackage("path.to.my.models.package");
> 
> Could there be a similar problem with Cayenne? Is there a way to change the 
> class loader before initialization in a similar matter? 
> 
> On Wed, Mar 23, 2022 at 5:53 PM Stefan Stegic  <mailto:stefanste...@gmail.com>> wrote:
> Yup, it's in there:
> 
> ##
> #   Licensed to the Apache Software Foundation (ASF) under one
> #  or more contributor license agreements.  See the NOTICE file
> #  distributed with this work for additional information
> #  regarding copyright ownership.  The ASF licenses this file
> #  to you under the Apache License, Version 2.0 (the
> #  "License"); you may not use this file except in compliance
> #  with the License.  You may obtain a copy of the License at
> #
> #http://www.apache.org/licenses/LICENSE-2.0 
> <http://www.apache.org/licenses/LICENSE-2.0>
> #
> #  Unless required by applicable law or agreed to in writing,
> #  software distributed under the License is distributed on an
> #  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> #  KIND, either express or implied.  See the License for the
> #  specific language governing permissions and limitations
> #  under the License.
> ######
> 
> org.apache.cayenne.configuration.server.MainCayenneServerModuleProvider
> 
> On Wed, Mar 23, 2022 at 5:47 PM Andrus Adamchik  <mailto:aadamc...@gmail.com>> wrote:
> Ok, shading can be tricky. Do you have this file inside the shaded jar:
> 
> >> "META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider"
> 
> And if you do, can you check the contents of it? It is a simple text file, so 
> once you extract it form the  jar, you can check it in any text editor.
> 
> Andrus
> 
> 
> 
> > On Mar 23, 2022, at 5:26 PM, Stefan Stegic  > <mailto:stefanste...@gmail.com>> wrote:
> > 
> > Ok, just tried maven-shade-plugin, but no luck - still the same error... It
> > seems that the shading is working as expected: when I run maven package,
> > the output jar really has cayenne's stuff in there, but DI is still failing
> > when I copy the plugin into the server and start it.
> > 
> > Michael, in response to your question:
> > 
> >> Have you tried updating your "java -cp myPlugin.jar path.to.Main" command
> >> to have more classpaths?
> > 
> > 
> > When I run Main, it works, so that's not the problem. The problem arises
> > when my plugin is called by Spigot, the custom Minecraft server I'm writing
> > the plugin for.
> > 
> > On Wed, Mar 23, 2022 at 5:20 PM Stefan Stegic  > <mailto:stefanste...@gmail.com>>
> > wrote:
> > 
> >> Hi Michael,
> >> 
> >> Oh, I wasn't aware, thanks. Here's the screenshot from my last e-mail:
> >> https://imgur.com/QJoBGAV <https://imgur.com/QJoBGAV> .
> >> Right, I'll give maven-shade-plugin a try now and check if it works that
> >> way, thanks.
> >> 
> >> On Wed, Mar 23, 2022 at 5:18 PM Michael Gentry  >> <mailto:blackn...@gmail.com>>
> >> wrote:
> >> 
> >>> If you aren't using a shaded JAR (which merges all JARs into a single
> >>> JAR),
> >>> then you'll need more JARs listed on your Java command.
> >>> 
> >>> 
> >>> On Wed, Mar 23, 2022 at 12:16 PM Stefan Stegic  >>> <mailto:stefanste...@gmail.com>>
> >>> wrote:

Re: DI container has no binding for key

2022-03-23 Thread Andrus Adamchik
Ok, shading can be tricky. Do you have this file inside the shaded jar:

>> "META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider"

And if you do, can you check the contents of it? It is a simple text file, so 
once you extract it form the  jar, you can check it in any text editor.

Andrus



> On Mar 23, 2022, at 5:26 PM, Stefan Stegic  wrote:
> 
> Ok, just tried maven-shade-plugin, but no luck - still the same error... It
> seems that the shading is working as expected: when I run maven package,
> the output jar really has cayenne's stuff in there, but DI is still failing
> when I copy the plugin into the server and start it.
> 
> Michael, in response to your question:
> 
>> Have you tried updating your "java -cp myPlugin.jar path.to.Main" command
>> to have more classpaths?
> 
> 
> When I run Main, it works, so that's not the problem. The problem arises
> when my plugin is called by Spigot, the custom Minecraft server I'm writing
> the plugin for.
> 
> On Wed, Mar 23, 2022 at 5:20 PM Stefan Stegic 
> wrote:
> 
>> Hi Michael,
>> 
>> Oh, I wasn't aware, thanks. Here's the screenshot from my last e-mail:
>> https://imgur.com/QJoBGAV .
>> Right, I'll give maven-shade-plugin a try now and check if it works that
>> way, thanks.
>> 
>> On Wed, Mar 23, 2022 at 5:18 PM Michael Gentry 
>> wrote:
>> 
>>> If you aren't using a shaded JAR (which merges all JARs into a single
>>> JAR),
>>> then you'll need more JARs listed on your Java command.
>>> 
>>> 
>>> On Wed, Mar 23, 2022 at 12:16 PM Stefan Stegic 
>>> wrote:
>>> 
>>>> PS: I'm not using maven-shade (just opened the link you sent)
>>>> 
>>>> On Wed, Mar 23, 2022 at 5:10 PM Stefan Stegic 
>>>> wrote:
>>>> 
>>>>> My knowledge of Java is not so deep, so excuse stupid questions - if
>>> any.
>>>>> I believe I am using shading because I'm exporting dependencies into my
>>>>> JAR. IntelliJ does this for me in the build process by publishing the
>>> JAR
>>>>> as an artifact. All I did was specify which dependencies I want to
>>> package
>>>>> in there like this:
>>>>> 
>>>>> [image: image.png]
>>>>> 
>>>>> So, I build the project, grab the published JAR artifact and put the
>>> file
>>>>> in the plugins folder of the Spigot server. I then run the Server and
>>> it
>>>>> tries to load each plugin JAR that's in there. That's when each of the
>>>>> onEnable methods are called, including that of my plugin
>>>>> (FirstSpigotPlugin). The example code that creates the CayenneRuntime
>>> is in
>>>>> my onEnable method.
>>>>> 
>>>>> Should I be packaging these dependencies differently then?
>>>>> 
>>>>> On Wed, Mar 23, 2022 at 4:56 PM Andrus Adamchik 
>>>>> wrote:
>>>>> 
>>>>>> This is not a common problem with Cayenne. In fact this is the first
>>>>>> time I see it happen in any environment. So Spigot is special in this
>>>>>> respect. I found this link:
>>>>>> https://bukkit.fandom.com/wiki/Using_External_Libraries_with_Plugins
>>> <
>>>>>> https://bukkit.fandom.com/wiki/Using_External_Libraries_with_Plugins>
>>>>>> It doesn't answer the question, but provides some hints. So how do you
>>>>>> package your own code and third-party dependencies like Cayenne for
>>>>>> Spigot/Bukkit? Do you use "shading"?
>>>>>> 
>>>>>> Andrus
>>>>>> 
>>>>>>> On Mar 23, 2022, at 4:51 PM, Stefan Stegic 
>>>>>> wrote:
>>>>>>> 
>>>>>>> Hi,
>>>>>>> 
>>>>>>> Thanks for your quick responses! I'm using version 4.1.1.
>>>>>>> Right, so you're saying Spigot is somehow blocking the execution of
>>>>>> said
>>>>>>> code, or it's circumventing it somehow so that those steps of
>>>>>>> initialization are never actually executed? Also, you mean that
>>> it's a
>>>>>>> common problem with Cayenne or with Spigot and other jars?
>>>>>>> 
>>>>>>> How would we go about understanding how the Spigot classpath works?
>>> It
>>>>>>>

Re: DI container has no binding for key

2022-03-23 Thread Andrus Adamchik
This is not a common problem with Cayenne. In fact this is the first time I see 
it happen in any environment. So Spigot is special in this respect. I found 
this link: https://bukkit.fandom.com/wiki/Using_External_Libraries_with_Plugins 
<https://bukkit.fandom.com/wiki/Using_External_Libraries_with_Plugins>  It 
doesn't answer the question, but provides some hints. So how do you package 
your own code and third-party dependencies like Cayenne for Spigot/Bukkit? Do 
you use "shading"?

Andrus

> On Mar 23, 2022, at 4:51 PM, Stefan Stegic  wrote:
> 
> Hi,
> 
> Thanks for your quick responses! I'm using version 4.1.1.
> Right, so you're saying Spigot is somehow blocking the execution of said
> code, or it's circumventing it somehow so that those steps of
> initialization are never actually executed? Also, you mean that it's a
> common problem with Cayenne or with Spigot and other jars?
> 
> How would we go about understanding how the Spigot classpath works? It
> might help to know that the plugin API is called Bukkit, so Spigot is kind
> of the parent entity (it's a customized Minecraft server, while Bukkit is
> the interface for plugins, as I've come to understand). It's source code
> should be here:
> https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse .
> 
> On Wed, Mar 23, 2022 at 4:33 PM Andrus Adamchik  wrote:
> 
>> The bootstrap code is as vanilla as it can get:
>> 
>>>> ServerRuntime cayenneRuntime = ServerRuntime.builder()
>>>> .addConfig("cayenne-project.xml")
>>>> .build();
>> 
>> Missing ObjectContextFactory means ServerModule is not loaded in the
>> environment. Since 4.1 (BTW, which version of Cayenne are we talking
>> about?), ServerModule is loaded by processing
>> "META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider"
>> files from the classpath jars. So there's something about Spigot's
>> classpath that prevents this code in ModuleLoader from returning proper
>> resources:
>> 
>> for (ModuleProvider provider : ServiceLoader.load(providerClass)) { ... }
>> 
>> We need to understand how Spigot classpath works. Cursory Googling shows
>> that this is a common problem, just don't immediately see a solution.
>> 
>> Andrus
>> 
>> 
>>> On Mar 23, 2022, at 4:03 PM, Andrus Adamchik 
>> wrote:
>>> 
>>> Actually the stack shows that there's already an instance of Cayenne
>> runtime available to the code, but the runtime is in a bad state (not clear
>> why). So thread binding should not be required.
>>> 
>>> Andrus
>>> 
>>> 
>>>> On Mar 23, 2022, at 4:00 PM, John Huss  wrote:
>>>> 
>>>> You have to bind the DI injector to the thread (and unbind it later):
>>>> 
>>>> CayenneRuntime.*bindThreadInjector*(cayenneRuntime.getInjector());
>>>> 
>>>> If you are using servlets, then CayenneFilter will do this for you.
>>>> Otherwise you can bind it at the start of a request and unbind it at the
>>>> end.
>>>> 
>>>> On Wed, Mar 23, 2022 at 9:10 AM Stefan Stegic 
>>>> wrote:
>>>> 
>>>>> Hi Andrus,
>>>>> 
>>>>> Of course:
>>>>> 
>>>>> org.apache.cayenne.di.DIRuntimeException: DI container has no binding
>> for
>>>>> key 
>>>>>  at
>>>>> 
>>>>> 
>> org.apache.cayenne.di.spi.DefaultInjector.getProvider(DefaultInjector.java:158)
>>>>> ~[?:?]
>>>>>  at
>>>>> 
>>>>> 
>> org.apache.cayenne.di.spi.DefaultInjector.getProvider(DefaultInjector.java:144)
>>>>> ~[?:?]
>>>>>  at
>>>>> 
>>>>> 
>> org.apache.cayenne.di.spi.DefaultInjector.getInstance(DefaultInjector.java:134)
>>>>> ~[?:?]
>>>>>  at
>>>>> 
>>>>> 
>> org.apache.cayenne.configuration.CayenneRuntime.newContext(CayenneRuntime.java:124)
>>>>> ~[?:?]
>>>>>  at
>>>>> 
>>>>> 
>> io.github.phuskus.firstspigotplugin.StatisticsController.reportPlayerConnectionEvent(StatisticsController.java:20)
>>>>> ~[?:?]
>>>>>  at
>>>>> 
>>>>> 
>> io.github.phuskus.firstspigotplugin.FirstSpigotPlugin.onEnable(FirstSpigotPlugin.java:29)
>>>>> ~[?:?]
>>>>>  at
>>>>> org.bukkit.plugin.java.J

Re: DI container has no binding for key

2022-03-23 Thread Andrus Adamchik
The bootstrap code is as vanilla as it can get:

>> ServerRuntime cayenneRuntime = ServerRuntime.builder()
>>  .addConfig("cayenne-project.xml")
>>  .build();

Missing ObjectContextFactory means ServerModule is not loaded in the 
environment. Since 4.1 (BTW, which version of Cayenne are we talking about?), 
ServerModule is loaded by processing 
"META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider"
 files from the classpath jars. So there's something about Spigot's classpath 
that prevents this code in ModuleLoader from returning proper resources:

for (ModuleProvider provider : ServiceLoader.load(providerClass)) { ... }

We need to understand how Spigot classpath works. Cursory Googling shows that 
this is a common problem, just don't immediately see a solution.

Andrus


> On Mar 23, 2022, at 4:03 PM, Andrus Adamchik  wrote:
> 
> Actually the stack shows that there's already an instance of Cayenne runtime 
> available to the code, but the runtime is in a bad state (not clear why). So 
> thread binding should not be required.
> 
> Andrus
> 
> 
>> On Mar 23, 2022, at 4:00 PM, John Huss  wrote:
>> 
>> You have to bind the DI injector to the thread (and unbind it later):
>> 
>> CayenneRuntime.*bindThreadInjector*(cayenneRuntime.getInjector());
>> 
>> If you are using servlets, then CayenneFilter will do this for you.
>> Otherwise you can bind it at the start of a request and unbind it at the
>> end.
>> 
>> On Wed, Mar 23, 2022 at 9:10 AM Stefan Stegic 
>> wrote:
>> 
>>> Hi Andrus,
>>> 
>>> Of course:
>>> 
>>> org.apache.cayenne.di.DIRuntimeException: DI container has no binding for
>>> key 
>>>   at
>>> 
>>> org.apache.cayenne.di.spi.DefaultInjector.getProvider(DefaultInjector.java:158)
>>> ~[?:?]
>>>   at
>>> 
>>> org.apache.cayenne.di.spi.DefaultInjector.getProvider(DefaultInjector.java:144)
>>> ~[?:?]
>>>   at
>>> 
>>> org.apache.cayenne.di.spi.DefaultInjector.getInstance(DefaultInjector.java:134)
>>> ~[?:?]
>>>   at
>>> 
>>> org.apache.cayenne.configuration.CayenneRuntime.newContext(CayenneRuntime.java:124)
>>> ~[?:?]
>>>   at
>>> 
>>> io.github.phuskus.firstspigotplugin.StatisticsController.reportPlayerConnectionEvent(StatisticsController.java:20)
>>> ~[?:?]
>>>   at
>>> 
>>> io.github.phuskus.firstspigotplugin.FirstSpigotPlugin.onEnable(FirstSpigotPlugin.java:29)
>>> ~[?:?]
>>>   at
>>> org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:264)
>>> ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
>>>   at
>>> 
>>> org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:342)
>>> ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
>>>   at
>>> 
>>> org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:480)
>>> ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
>>>   at
>>> 
>>> org.bukkit.craftbukkit.v1_18_R1.CraftServer.enablePlugin(CraftServer.java:521)
>>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499]
>>>   at
>>> 
>>> org.bukkit.craftbukkit.v1_18_R1.CraftServer.enablePlugins(CraftServer.java:435)
>>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499]
>>>   at
>>> net.minecraft.server.MinecraftServer.loadWorld0(MinecraftServer.java:612)
>>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499]
>>>   at
>>> net.minecraft.server.MinecraftServer.loadLevel(MinecraftServer.java:414)
>>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499]
>>>   at
>>> net.minecraft.server.dedicated.DedicatedServer.e(DedicatedServer.java:262)
>>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499]
>>>   at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:994)
>>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499]
>>>   at
>>> net.minecraft.server.MinecraftServer.lambda$0(MinecraftServer.java:304)
>>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499]
>>>   at java.lang.Thread.run(Thread.java:833) [?:?]
>>> 
>>> On Wed, Mar 23, 2022 at 11:49 AM Andrus Adamchik 
>>> wrote:
>>> 
>>>> Hi Stefan,
>>>> 
>>>> Could you include a full stack trace please?
>>>> 
>>>> Thanks,
>>>> Andrus

Re: DI container has no binding for key

2022-03-23 Thread Andrus Adamchik
Actually the stack shows that there's already an instance of Cayenne runtime 
available to the code, but the runtime is in a bad state (not clear why). So 
thread binding should not be required.

Andrus


> On Mar 23, 2022, at 4:00 PM, John Huss  wrote:
> 
> You have to bind the DI injector to the thread (and unbind it later):
> 
> CayenneRuntime.*bindThreadInjector*(cayenneRuntime.getInjector());
> 
> If you are using servlets, then CayenneFilter will do this for you.
> Otherwise you can bind it at the start of a request and unbind it at the
> end.
> 
> On Wed, Mar 23, 2022 at 9:10 AM Stefan Stegic 
> wrote:
> 
>> Hi Andrus,
>> 
>> Of course:
>> 
>> org.apache.cayenne.di.DIRuntimeException: DI container has no binding for
>> key 
>>at
>> 
>> org.apache.cayenne.di.spi.DefaultInjector.getProvider(DefaultInjector.java:158)
>> ~[?:?]
>>at
>> 
>> org.apache.cayenne.di.spi.DefaultInjector.getProvider(DefaultInjector.java:144)
>> ~[?:?]
>>at
>> 
>> org.apache.cayenne.di.spi.DefaultInjector.getInstance(DefaultInjector.java:134)
>> ~[?:?]
>>at
>> 
>> org.apache.cayenne.configuration.CayenneRuntime.newContext(CayenneRuntime.java:124)
>> ~[?:?]
>>at
>> 
>> io.github.phuskus.firstspigotplugin.StatisticsController.reportPlayerConnectionEvent(StatisticsController.java:20)
>> ~[?:?]
>>at
>> 
>> io.github.phuskus.firstspigotplugin.FirstSpigotPlugin.onEnable(FirstSpigotPlugin.java:29)
>> ~[?:?]
>>at
>> org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:264)
>> ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
>>at
>> 
>> org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:342)
>> ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
>>at
>> 
>> org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:480)
>> ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
>>at
>> 
>> org.bukkit.craftbukkit.v1_18_R1.CraftServer.enablePlugin(CraftServer.java:521)
>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499]
>>at
>> 
>> org.bukkit.craftbukkit.v1_18_R1.CraftServer.enablePlugins(CraftServer.java:435)
>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499]
>>at
>> net.minecraft.server.MinecraftServer.loadWorld0(MinecraftServer.java:612)
>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499]
>>at
>> net.minecraft.server.MinecraftServer.loadLevel(MinecraftServer.java:414)
>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499]
>>at
>> net.minecraft.server.dedicated.DedicatedServer.e(DedicatedServer.java:262)
>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499]
>>    at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:994)
>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499]
>>at
>> net.minecraft.server.MinecraftServer.lambda$0(MinecraftServer.java:304)
>> ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3443-Spigot-699290c-2c1e499]
>>at java.lang.Thread.run(Thread.java:833) [?:?]
>> 
>> On Wed, Mar 23, 2022 at 11:49 AM Andrus Adamchik 
>> wrote:
>> 
>>> Hi Stefan,
>>> 
>>> Could you include a full stack trace please?
>>> 
>>> Thanks,
>>> Andrus
>>> 
>>>> On Mar 23, 2022, at 1:04 AM, Stefan Stegic 
>>> wrote:
>>>> 
>>>> Hi,
>>>> 
>>>> 
>>>> First some context: I'm working on a custom Minecraft server (Spigot)
>>>> plugin. It's just a JAR that you export and place somewhere in the
>>> server's
>>>> folder structure.
>>>> 
>>>> I wrote a simple insert query via Cayenne's API. It works when I run
>> the
>>>> example JAR directly via executing Main from the command line (java -cp
>>>> myPlugin.jar path.to.Main), but it fails with the following error when
>>>> executed by the server in my plugin's OnEnable lifecycle hook:
>>>> 
>>>> org.apache.cayenne.di.DIRuntimeException: DI container has no binding
>> for
>>>> key 
>>>> 
>>>> 
>>>> My initial theory was that it's being executed from a different thread,
>>> so
>>>> the DI system might not have access to that dependency for some reason,
>>> but
>>>> it seems like the server executes this lifecycle hook from the main
>>> thread
>>>> as well (though they've nam

Re: DI container has no binding for key

2022-03-23 Thread Andrus Adamchik
Hi Stefan,

Could you include a full stack trace please?

Thanks,
Andrus

> On Mar 23, 2022, at 1:04 AM, Stefan Stegic  wrote:
> 
> Hi,
> 
> 
> First some context: I'm working on a custom Minecraft server (Spigot)
> plugin. It's just a JAR that you export and place somewhere in the server's
> folder structure.
> 
> I wrote a simple insert query via Cayenne's API. It works when I run the
> example JAR directly via executing Main from the command line (java -cp
> myPlugin.jar path.to.Main), but it fails with the following error when
> executed by the server in my plugin's OnEnable lifecycle hook:
> 
> org.apache.cayenne.di.DIRuntimeException: DI container has no binding for
> key 
> 
> 
> My initial theory was that it's being executed from a different thread, so
> the DI system might not have access to that dependency for some reason, but
> it seems like the server executes this lifecycle hook from the main thread
> as well (though they've named the thread "Server thread", and I don't know
> how to check if it's the main thread for sure). Not sure if this is a
> promising direction to pursue, but I got the hunch by looking at the
> threadInjector bits of Cayenne's DI container docs.
> 
> My example looks like this:
> 
> ServerRuntime cayenneRuntime = ServerRuntime.builder()
>.addConfig("cayenne-project.xml")
>.build();ObjectContext ctx = cayenneRuntime.newContext();
> PlayerConnectionEvent newEvent =
> ctx.newObject(PlayerConnectionEvent.class);
> newEvent.setEventType(eType);
> newEvent.setPlayerName(playerName);
> newEvent.setIpAddress(ipAddress);
> newEvent.setTimestampUnixSeconds(unixSeconds);
> 
> ctx.commitChanges();
> 
> Some help would be greatly appreciated, thanks in advance!
> -- 
> S poštovanjem,
> *Stefan Stegić*



Re: Exception when setting a CLOB on H2 v2.0.202

2022-01-18 Thread Andrus Adamchik
Hi Nigel,

Thanks for pointing this out. What you are suggesting sounds like the right 
solution. And we'd gladly accept a PR at https://github.com/apache/cayenne 


Cheers,
Andrus


> On Jan 19, 2022, at 4:38 AM, Nigel Huband  wrote:
> 
> Hi everybody,
>  
> In Cayenne 4.1.1 (and probably other versions) when using CLOB's with H2 
> v2.0.202 an error occurs when attempting to save.
>  
> This is due to a change in behaviour in H2 (likely from 1.x) where a CLOB now 
> needs to be saved as a stream.
>  
> In Cayenne, the CharType() has following method which is executed when saving 
>  CLOB for an H2 DB:
>  
>   public void setJdbcObject(PreparedStatement st, String value, 
> int pos, int type, int scale) throws Exception {
>  
>  // if this is a CLOB column, set the value as 
> "String"
>  // instead. This should work with most drivers
>  if (type == Types.CLOB || type == Types.NCLOB) {
>st.setString(pos, value);
>  } else if (scale != -1) {
>st.setObject(pos, value, type, 
> scale);
>  } else {
>st.setObject(pos, value, type);
>  }
>   }
>  
> As the type is a CLOB, when the st.setString(pos, value) gets executed an 
> exception is thrown from H2 as you now need to set a stream as follows:
>  
> Clob clob = st.getConnection().createClob();
> clob.setString(1, val);
> st.setClob(pos, clob);
>  
> As a fix I'm thinking creating a H2CharType() which overrides the 
> setJdbcObject() similar to the OracleCharType() to contain this functionality.
>  
> I'm happy to submit a PR on GitHub with the solution, please advise?
>  
> Kind regards,
> Nigel.
>  
> 
> NIGEL HUBAND 
> TECHNICAL LEAD
> AVOKA APAC
>  
>  
> Level 2, 1a Rialto Lane, Manly
> New South Wales, Australia 2100
> 
>  
>    
>  
>   temenos.com 
> 
>  
>  
> 
> The information in this e-mail and any attachments is confidential and may be 
> legally privileged. It is intended solely for the addressee or addressees. 
> Any use or disclosure of the contents of this e-mail/attachments by a not 
> intended recipient is unauthorized and may be unlawful. If you have received 
> this e-mail in error please notify the sender. Please note that any views or 
> opinions presented in this e-mail are solely those of the author and do not 
> necessarily represent those of TEMENOS. We recommend that you check this 
> e-mail and any attachments against viruses. TEMENOS accepts no liability for 
> any damage caused by any malicious code or virus transmitted by this e-mail.



[ann] Cayenne 4.1.1 is released

2021-12-24 Thread Andrus Adamchik
We just posted a 4.1.1 maintenance release of Cayenne. It provides a few 
missing pieces related to Java 17 support (Modeler and Gradle), as well as a 
bunch of bug fixes. So if you are on 4.1, upgrade is highly recommended.

Happy holidays,
Andrus

[ANN] Cayenne 4.2 goes beta

2021-12-07 Thread Andrus Adamchik
Hi everyone, 

Happy to announce that Cayenne 4.2 just went Beta. The new 4.2.B1 release is 
available from the Cayenne website [1] and Maven Central. Since the last 
milestone we've implemented a couple of minor features and 19 bug fixes [2], 
the most notable being desktop Java 17 support for CayenneModeler.  

Beta means code freeze and a direct path to the GA release. Let me share the 
overall 4.2 improvements that make it a worthwhile upgrade:

* Lots of improvements to the Property, Query, Expression APIs (nested queries, 
type-specific Properties, etc)
* Ordering on aggregate functions and in-memory evaluation of aggregate 
expressions
* Support for JSON and geospatial value types
* Annotations for callback methods on entity classes
* Modeler support for downloading JDBC drivers from maven central
* Lots of internal runtime changes to address commit edge cases and simply make 
query to SQL translation more sane

Cheers,
Andrus

[1] https://cayenne.apache.org/download/
[2] https://github.com/apache/cayenne/blob/master/RELEASE-NOTES.txt

Re: Performance with quoteSqlIdentifiers

2021-11-23 Thread Andrus Adamchik
Hi Andrew,

DataMaps don't work as "layers" on top of each other, so the answer to #2 is 
no. For #1, I am not aware of any visible performance impact of quoting 
identifiers. So you can just use quoted identifiers everywhere.

Andrus


> On Nov 23, 2021, at 5:16 PM, Meeks, Andrew  wrote:
> 
> Hello,
> 
> My production database is Oracle but I do local testing with in-memory H2.  I 
> have been using two datamaps; "src/main/resources/datamap.map.xml", and 
> "src/test/resources/datamap.map.xml".  When I make an ORM change and it's 
> been a year or two, I eventually remember to copy the datamap from main to 
> test but I almost always forget that the test datamap has " name="quoteSqlIdentifiers" value="true"/>" because H2 has a different set of 
> reserved words than Oracle.
> 
> I have two questions:
> 
>  1.  Is there much of a performance issue in leaving quoteSqlIdentifiers set 
> to "true" even when it's not necessary in production?
>  2.  Is there a way the test datamap can reference and extend the main 
> datamap?  By that I mean, can the test datamap simply pull in the main 
> datamap and augment it with the quoteSqlIdentifiers property?  The 
> cayenne.xml is very different between production and test and the cayenne 
> configuration appears to expect the file with the prefix specified in " name="datamap"/>" is located in the same directory. That seems to necessitate 
> keeping separate copies of the nearly-identical datamap.map.xml.
> 
> Thank you,
> Andrew



Re: Questions about the modeler

2021-11-21 Thread Andrus Adamchik
Hi Tony,

We do not generate this SQL. Schema retrieval is abstracted by the JDBC API, so 
specifics are hidden within a given driver. All we do is this:

  DatabaseMetaData md = connection.getMetadata();
  md.getTables(..);
  md.getColumns(..);
  md.getImportedKeys(..);

Andrus


> On Nov 22, 2021, at 1:11 AM, Tony Giaccone  wrote:
> 
> 
> Two questions about reverse engineering.
> 
> Is there a setting that will cause the modeler to emit the SQL that is used 
> to read tables and schema information?
> 
> Second is where is it in the modeler that generates this sql?
> 
> 
> 
> Tony



Re: Problem with optional to-one deletion

2021-11-17 Thread Andrus Adamchik
Hi Mike,

Nikita mentioned a few hours ago that he was able to reproduce. Appears to be a 
bug in the 4.2 stack.

Andrus

> On Nov 17, 2021, at 7:44 PM, Michael Gentry  wrote:
> 
> Hi Lon,
> 
> I didn't have a lot of time to look into it, but I suspect it may be in
> your PK/FK mapping on the DbEntities.
> 
> For example, in order_header, you have order_header ->> order_detail_sales,
> but you've mapped that as To-Many AND To-Dependent PK, which doesn't make
> sense.
> 
> 
> On Tue, Nov 16, 2021 at 6:14 PM Lon Varscsak  wrote:
> 
>> I forgot to mention that I'm running 4.2.M4-SNAPSHOT (updated from github
>> as of an hour ago).
>> 
>> On Tue, Nov 16, 2021 at 4:06 PM Lon Varscsak 
>> wrote:
>> 
>>> Hey all,
>>> 
>>> I have a setup where I have an optional to-one relationship, but when I
>>> try to clear the relationship and commitChanges, I get a low-level
>> Cayenne
>>> error along with some in appropriate sql generated.
>>> 
>>> where it's doing an UPDATE to order_detail_costs should be a no-op,
>>> because the object was removed from it's parent (order_detail_sales) with
>>> setOrderDetailCost(null) along with a
>>> objectContext.deleteObject(orderDetailCost).  This is probably a problem
>>> for Nikita to look at, but I figured someone else may have run into this
>> as
>>> well.  It's unusual for me to have optional to-one relationships, but it
>>> does happen.
>>> 
>>> Here is a sample project (Debug As -> Java Application) to try (link to
>> my
>>> Synology):
>>> 
>> https://varscsak.synology.me:5001/d/s/mI7SBS6fApoUMNT1K5lfpaCXHKEkHkgd/jIy5Ug64Hjp2ieZzOceknc39sjBasJLE-T74gPgqKEgk
>>> 
>>> ...snip...
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT
>>> INTO "order_header"( "attribute_1", "attribute_2", "order_number")
>> VALUES(
>>> ?, ?, ?)
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
>>> 1->attribute_1:'TEST1', 2->attribute_2:1, 3->order_number:1]
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
>>> updated 1 row.
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT
>>> INTO "order_detail_sales"( "detail_attr_1", "detail_attr_2",
>>> "order_line_number", "order_number") VALUES( ?, ?, ?, ?)
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
>>> 1->detail_attr_1:'TEST1', 2->detail_attr_2:1, 3->order_line_number:1,
>>> 4->order_number:1]
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
>>> updated 1 row.
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - UPDATE
>>> "order_detail_costs" SET "order_number" = ?, "order_line_number" = ?
>> WHERE
>>> ( "order_line_number" = ? ) AND ( "order_number" = ? )
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ***
>> error.
>>> 
>>> java.lang.UnsupportedOperationException
>>> 
>>> at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
>>> 
>>> at org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)
>>> 
>>> at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
>>> UpdateBatchQuery.java:124)
>>> 
>>> at
>>> 
>> org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
>>> UpdateBatchTranslator.java:80)
>>> 
>>> at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
>>> BatchAction.java:191)
>>> 
>>> at org.apache.cayenne.access.jdbc.BatchAction.performAction(
>>> BatchAction.java:93)
>>> 
>>> at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
>>> DataNodeQueryAction.java:97)
>>> 
>>> at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
>>> 
>>> at
>>> 
>> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
>>> DefaultDataDomainFlushAction.java:177)
>>> 
>>> at java.util.HashMap.forEach(HashMap.java:1290)
>>> 
>>> at
>>> 
>> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
>>> DefaultDataDomainFlushAction.java:176)
>>> 
>>> at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
>>> DefaultDataDomainFlushAction.java:89)
>>> 
>>> at org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
>>> 
>>> at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
>>> DataDomain.java:609)
>>> 
>>> at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
>>> DataDomain.java:835)
>>> 
>>> at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
>>> TransactionFilter.java:61)
>>> 
>>> at
>>> 
>> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
>>> DefaultTransactionManager.java:180)
>>> 
>>> at
>>> 
>> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
>>> DefaultTransactionManager.java:152)
>>> 
>>> at
>>> 
>> org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
>>> DefaultTransactionManager.java:95)
>>> 
>>> at 

Re: Modeler Types

2021-11-05 Thread Andrus Adamchik
Hi Tony,

Support for non-standard SQL types was added in 4.2:

https://lists.apache.org/thread/66nhvkzt1mqoh2h53h2x6sbx968kt2fy

We are mapping those types on the DB side as JDBC type OTHER. On the Java type 
it is mapped as org.apache.cayenne.value.Json.

Andrus


> On Nov 4, 2021, at 6:34 PM, Tony Giaccone  wrote:
> 
> So Postgres supports a json type in their database.  Clearly this isn't a
> type that's generally available, but it would be nice if the modeler
> supported the ability to add types, so in this way you could support the
> unusual types, that sometimes need to be used. Clearly I have no idea how
> hard this would be to implement in the modeler, but it sure would be a nice
> feature.
> 
> 
> Tony Giaccone



Re: Ordering objects by primary keys

2021-10-28 Thread Andrus Adamchik
Yeah, the expressions chapter mentions it: 

http://cayenne.apache.org/docs/4.1/cayenne-guide/#expressions 



Andrus


> On Oct 28, 2021, at 9:38 AM, giulio.ces...@gmail.com wrote:
> 
> Is there any point in the documentation where this "db:" prefix has been
> documented?
> 
> Cheers,
> Giulio Cesare
> 
> On Wed, Oct 27, 2021 at 11:23 PM giulio.ces...@gmail.com <
> giulio.ces...@gmail.com> wrote:
> 
>> It did work! 朗
>> 
>> Thanks Nikita. 
>> 
>> Cheers,
>> 
>> Giulio Cesare
>> 
>> 
>> On Wed, Oct 27, 2021 at 7:46 PM Nikita Timofeev 
>> wrote:
>> 
>>> Hi!
>>> 
>>> You could try to add "db:" prefix to the primary key name.
>>> Something like this: orderBy("db:ARTIST_ID")
>>> 
>>> On Wed, Oct 27, 2021 at 8:14 PM giulio.ces...@gmail.com
>>>  wrote:
 
 Hello,
 
 I am try to run some BBD tests integrated with Cayenne (succesfully, so
 far).
 I am at the point where I can not fully specify the record/object to
>>> select
 in the test script, and so I am trying to select the latest object
 inserted, matching some lose criteria.
 
 Unfortunately, I don't have a generic "insertion date" in all my
>>> entities;
 so the next best think I could think of, is to use the value of the PK
 (generated using Postgres sequences) to sort the selected objects (DESC)
 and picking the first match.
 
 To achieve this, I have tried with this code:
 
 String dbEntityName =
 context.getEntityResolver().getObjEntity(entityName).getDbEntityName();
 ImmutableList orderBy =
 
>>> context.getEntityResolver().getDbEntity(dbEntityName).getPrimaryKeys().stream()
 .map(attribute -> new Ordering(attribute.getName(),
>>> SortOrder.DESCENDING))
 .collect(ImmutableList.toImmutableList())
 ;
 BaseDataObject latestInstance =
 ObjectSelect.query(clazz).orderBy(orderBy).selectFirst(context);
 
 but I get the following error:
 - Can't resolve path component: [{EntityName}.{primaryKeyFieldName}]
 
 I realize that {EntityName} and {primaryKeyFieldName} live in two
>>> separate
 contexts (Entities vs DB); but I have no more ideas on how to progress.
 
 Does anyone have any suggestions on how to do this stunt?
 
 Cheers,
 Giulio Cesare
>>> 
>>> 
>>> 
>>> --
>>> Best regards,
>>> Nikita Timofeev
>>> 
>> 



Re: Always getting distinct results in fetch?

2021-10-21 Thread Andrus Adamchik
Need to experiment with this one. Looks like it may need some adjustment.

> On Oct 20, 2021, at 9:29 PM, Nikita Timofeev  
> wrote:
> 
> Hi all,
> 
> This behavior is still in 4.2. To make it odder, selecting a single
> column would return all rows like with suppressDistinct() call.
> This is caused by the logic deep inside mapping result rows to objects
> [1], that came, I believe, from the EJBQL.
> Not sure I know why it's there, though.
> 
> [1] 
> https://github.com/apache/cayenne/blob/master/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java#L816
> 
> On Wed, Oct 20, 2021 at 8:28 AM Andrus Adamchik  wrote:
>> 
>> Yeah, this seems wrong. "Historically" distinct would be implicitly added 
>> (either to SQL or to the processed result) when a query condition contained 
>> to-many relationships. The goal was to preserve the abstraction of an 
>> "object" query, and return the same consistent result regardless of the SQL 
>> specifics.
>> 
>> This is not the case here, as the query is not object-based, neither there 
>> is a to-many relationship involved.
>> 
>> I recall we discussed it with Nikita long time ago, just don't remember what 
>> the outcome of that discussion was :) Maybe Nikita can shed some light?
>> 
>> Andrus
>> 
>>> On Oct 19, 2021, at 4:57 PM, Hugi Thordarson  wrote:
>>> 
>>> Followup—I added .suppressDistinct() to the ObjectSelect and that fixed my 
>>> problem, i.e. the list contained all 462.653 rows.
>>> 
>>> However, I'm still a bit flummoxed… I didn't realize the fetch was distinct 
>>> because the "distinct" keyword did not appear in the generated SQL. 
>>> However, the keyword *is* added to the SQL if I explicitly specify 
>>> distinct(). Somewhat odd.
>>> 
>>> Note that all of this is on Cayenne 4.1 and I haven't tried this on 4.2 
>>> (where everything is changed behind the scenes). Perhaps all of this is 
>>> different there and I should just keep silent for now? :)
>>> 
>>> Cheers,
>>> - hugi
>>> 
>>> 
>>> 
>>>> On 19 Oct 2021, at 13:45, Hugi Thordarson  wrote:
>>>> 
>>>> Hi all,
>>>> let's say I'm performing a simple single column fetch. Example:
>>>> 
>>>> --
>>>> List customers = ObjectSelect
>>>> .query( Customer.class )
>>>> .columns( Customer.CPRNR )
>>>> .select( oc );
>>>> 
>>>> System.out.println( "Customers: " + customers.size() );
>>>> --
>>>> 
>>>> This generates the following output:
>>>> 
>>>> --
>>>> - --- transaction started.
>>>> - SELECT "t0"."cprnr" FROM "nb_customer" "t0"
>>>> - === returned 462653 rows. - took 210 ms.
>>>> - +++ transaction committed.
>>>> Customers: 169770
>>>> --
>>>> 
>>>> As you can see, the fetch returns 462.653 rows which is the number of 
>>>> customers in the DB, and the number I expected.
>>>> However, the resulting list only contains 169.770 objects—the number of 
>>>> distinct values of CPRNR.
>>>> 
>>>> Why? It's not a distinct fetch. I'm feeling particularly stupid today, and 
>>>> I'm definitely missing something here, I just don't understand what :).
>>>> 
>>>> Cheers,
>>>> - hugi
>>> 
>> 
> 
> 
> -- 
> Best regards,
> Nikita Timofeev



Re: Always getting distinct results in fetch?

2021-10-19 Thread Andrus Adamchik
Yeah, this seems wrong. "Historically" distinct would be implicitly added 
(either to SQL or to the processed result) when a query condition contained 
to-many relationships. The goal was to preserve the abstraction of an "object" 
query, and return the same consistent result regardless of the SQL specifics. 

This is not the case here, as the query is not object-based, neither there is a 
to-many relationship involved. 

I recall we discussed it with Nikita long time ago, just don't remember what 
the outcome of that discussion was :) Maybe Nikita can shed some light?

Andrus

> On Oct 19, 2021, at 4:57 PM, Hugi Thordarson  wrote:
> 
> Followup—I added .suppressDistinct() to the ObjectSelect and that fixed my 
> problem, i.e. the list contained all 462.653 rows.
> 
> However, I'm still a bit flummoxed… I didn't realize the fetch was distinct 
> because the "distinct" keyword did not appear in the generated SQL. However, 
> the keyword *is* added to the SQL if I explicitly specify distinct(). 
> Somewhat odd.
> 
> Note that all of this is on Cayenne 4.1 and I haven't tried this on 4.2 
> (where everything is changed behind the scenes). Perhaps all of this is 
> different there and I should just keep silent for now? :)
> 
> Cheers,
> - hugi
> 
> 
> 
>> On 19 Oct 2021, at 13:45, Hugi Thordarson  wrote:
>> 
>> Hi all,
>> let's say I'm performing a simple single column fetch. Example:
>> 
>> --
>> List customers = ObjectSelect
>>  .query( Customer.class )
>>  .columns( Customer.CPRNR )
>>  .select( oc );
>> 
>> System.out.println( "Customers: " + customers.size() );
>> --
>> 
>> This generates the following output:
>> 
>> --
>> - --- transaction started.
>> - SELECT "t0"."cprnr" FROM "nb_customer" "t0" 
>> - === returned 462653 rows. - took 210 ms.
>> - +++ transaction committed.
>> Customers: 169770
>> --
>> 
>> As you can see, the fetch returns 462.653 rows which is the number of 
>> customers in the DB, and the number I expected.
>> However, the resulting list only contains 169.770 objects—the number of 
>> distinct values of CPRNR.
>> 
>> Why? It's not a distinct fetch. I'm feeling particularly stupid today, and 
>> I'm definitely missing something here, I just don't understand what :).
>> 
>> Cheers,
>> - hugi
> 



CayenneModeler on Java 17

2021-09-27 Thread Andrus Adamchik
Hi folks,

Wanted to mention that there's a known issue with CayenneModeler (all versions) 
and Java 17. We created a Jira [1] and will be working on a fix. Luckily there 
are workarounds (also described in the Jira) :

* You can use cross-platform Modeler
* On Mac you can launch the "native" Mac Modeler with an older JVM from the 
command line:

export CLASSPATH=`find ./CayenneModeler.app/Contents/Java -name '*.jar' \
   |perl -ne 'chomp; print "$_:"'`

java -Xmx500m -Dapple.laf.useScreenMenuBar=true -cp $CLASSPATH \
   org.apache.cayenne.modeler.osx.OSXMain

Andrus

[1] https://issues.apache.org/jira/browse/CAY-2721

Re: Cayenne Version 4.0 Logging

2021-09-08 Thread Andrus Adamchik
Hi Keena,

You are using DBCP2 DataSource [1] in your app, specifically an instance of 
BasicDataSource [2].

I haven't used it myself, but quick code/javadocs inspection shows it has 
methods like "getNumActive()", etc. that should allow you to check its state at 
any moment in time. Also it can be monitored via JMX. 

HTH,
Andrus


[1] https://commons.apache.org/proper/commons-dbcp/ 

[2] 
https://commons.apache.org/proper/commons-dbcp/apidocs/org/apache/commons/dbcp2/BasicDataSource.html


> On Sep 9, 2021, at 5:36 AM, Keena Grepo  wrote:
> 
> Hi,
> 
> Is there any documentation that may serve as a reference on how to log the 
> connection pool status/information for cayenne version 4.0?
> 
> Here are the only information that is being logged once the web application 
> has started to run on the server :
> 
> 2021-09-09 09:22:58.288  INFO 25112 --- [   main] 
> c.m.a.t.ServletInitializer   : Starting ServletInitializer 
> v2.1.1.3 on CAVLT018 with PID 25112 
> (C:\sts-bundle\pivotal-tc-server\instances\base-instance\wtpwebapps\MonitoringSystem\WEB-INF\classes
>  started by Dev.User in C:\sts-bundle\sts-3.9.9.RELEASE)
> 2021-09-09 09:22:58.294  INFO 25112 --- [   main] 
> c.m.a.t.ServletInitializer   : The following profiles are active: 
> default
> 2021-09-09 09:23:01.851  INFO 25112 --- [   main] 
> o.s.web.context.ContextLoader: Root WebApplicationContext: 
> initialization completed in 3351 ms
> 2021-09-09 09:23:03.651  INFO 25112 --- [   main] 
> o.a.c.c.XMLDataChannelDescriptorLoader   : Loading XML configuration resource 
> from 
> file:/C:/sts-bundle/pivotal-tc-server/instances/base-instance/wtpwebapps/MonitoringSystem/WEB-INF/classes/cayenne-project.xml
> 2021-09-09 09:23:03.682  INFO 25112 --- [   main] 
> o.a.c.c.XMLDataChannelDescriptorLoader   : Loading XML DataMap resource from 
> file:/C:/sts-bundle/pivotal-tc-server/instances/base-instance/wtpwebapps/MonitoringSystem/WEB-INF/classes/datamap.map.xml
> 2021-09-09 09:23:04.107  INFO 25112 --- [   main] 
> o.a.c.c.server.DataDomainProvider: setting DataNode 'datanode' as 
> default, used by all unlinked DataMaps
> 2021-09-09 09:23:10.374  INFO 25112 --- [   main] 
> org.apache.cayenne.log.JdbcEventLogger   : Detected and installed adapter: 
> org.apache.cayenne.dba.mysql.MySQLAdapter
> 
> Our goal is to get the number of active connections in the pool.
> 
> Btw, the applciation is using 
> factory="org.apache.cayenne.configuration.server.DBCPDataSourceFactory" in 
> the cayene-project.xml file.



Re: Suggested modeler change...

2021-07-16 Thread Andrus Adamchik
Yeah, the whole PK generation abstraction is somewhat leaky. It works, but is 
challenging to apply consistently across different DB engines and different 
generator strategies. And as a result is challenging to present to the end user 
in a sane fashion. Just recently had this discussion with Nikita (and we don't 
have a solution, just know that there's a problem).

Andrus 


> On Jun 15, 2021, at 12:08 PM, Tony Giaccone  wrote:
> 
> When using the modeler, you can choose to pick Custom Sequence as a choice
> for the primary key generation.  Provide the sequence name, and then
> there's this field in the modeler, "Cached PK Size".  It wasn't obvious to
> me, and it took a bit of sleuthing to find that this value should be the
> increment size of your sequence.
> 
> I suggest that there's text to that effect on that field.  either after the
> field or in a ? on the field. or just something that identifies that this
> should match with what's in your sequence.  The query I'm running takes a
> long d*** time, and fiddling with that value to try and understand how it
> works was kind of painful. A simple in modeler explanation would save a lot
> of developer time.
> 
> 
> 
> Tony



Re: Examples of Cayenne Tapestry apps

2021-05-12 Thread Andrus Adamchik
> 
> On May 12, 2021, at 1:50 PM, D Tim Cummings  
> wrote:
> 
> Does anyone know of any good open-source Cayenne Tapestry apps that show
> best practice and latest features for using these two frameworks
> together? Most of the Tapestry examples use Hibernate.
> 
> Tim

Hi Tim,

Not aware of any other than this ancient one [1] (I see your commits in there 
:)) . Also you probably know that Bootique supports Tapestry [2], and that's 
what we are on. As for the Tapestry part, we are using vanilla Tapestry 
functionality for the most part. Looking at my own (non-open source) Tapestry 
modules [3,4], the only Cayenne extension is encoders for Persistent and 
ObjectId [5], so that objects can be encoded/decoded to/from page URL 
parameters. So our entire integration can fit in an email message, and that's 
the beauty of it :)
 
Andrus

-

[1] https://github.com/andrus/wowodc13
[2] https://github.com/bootique/bootique-tapestry
[3] Bootique config:

TapestryModule.extend(binder).addTapestryModule(TapestryModule.class)
// this ensures that T5 JS/CSS only includes when the page or components 
explicitly import parts of
// the stack
.setSymbol(SymbolConstants.INCLUDE_CORE_STACK, "false")
// turn off Tapestry Bootstrap .. we don't have much choice in the matter 
of the root selection
// it has to be one of the standard T5 locations. "META-INF/asset" is the 
most neutral one..
.setSymbol(SymbolConstants.BOOTSTRAP_ROOT, "classpath:/META-INF/assets")
.setSymbol(SymbolConstants.OMIT_GENERATOR_META, "true");

[4] Tapestry module loaded via Bootique:

public class TapestryModule {

public void contributeValueEncoderSource(
MappedConfiguration configuration,
PersistentCoder persistentCoder, 
ObjectIdCoder objectIdCoder) {

configuration.add(Persistent.class, c -> persistentCoder);
configuration.add(ObjectId.class, c -> objectIdCoder);
}
}

[5] ID coders 

import org.apache.cayenne.ObjectId;
import org.apache.cayenne.lifecycle.id.IdCoder;
import org.apache.tapestry5.ValueEncoder;

public class ObjectIdCoder implements ValueEncoder {

private IdCoder idCoder;

public ObjectIdCoder(IdCoder idCoder) {
this.idCoder = idCoder;
}

@Override
public String toClient(ObjectId value) {
return idCoder.getStringId(value);
}

@Override
public ObjectId toValue(String clientValue) {
return idCoder.getObjectId(clientValue);
}
}

import org.apache.cayenne.Cayenne;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.Persistent;
import org.apache.cayenne.lifecycle.id.IdCoder;
import org.apache.tapestry5.ValueEncoder;

public class PersistentCoder implements ValueEncoder {

private IdCoder idCoder;
private Supplier contextSupplier;

public PersistentCoder(IdCoder idCoder, Supplier 
contextSupplier) {
this.idCoder = idCoder;
this.contextSupplier = contextSupplier;
}

@Override
public String toClient(Persistent value) {
return idCoder.getStringId(value);
}

@Override
public Persistent toValue(String clientValue) {

// TODO: should we be using ObjectIdQuery with caching?

return (Persistent) Cayenne.objectForPK(
contextSupplier.get(),
idCoder.getObjectId(clientValue));
}
}






Re: Modeler Question....

2021-04-30 Thread Andrus Adamchik
Hi Tony,

Yeah I remember how slow Oracle tests always were due to the schema operations. 
And I've also observed your problem even on databases with much faster metadata 
retrieval. So I agree that DB import process should attempt to apply DB-side 
metadata filtering to the maximum extent possible. JDBC spec does not allow the 
degree of filtering that Cayenne DB import does, but we can still trim the 
scope of retrieved metadata significantly. We discussed it with Nikita some 
time back, and we'll need to revisit. 

Andrus


> On Apr 29, 2021, at 10:37 AM, Tony Giaccone  wrote:
> 
> So here's a response to my own question. This process in the Oracle
> database takes so long because there are 15 different schemas each with
> potentially dozens and in some cases over 100 tables.  The result is an
> import which just takes a long long time. It might be nice if it were
> possible to limit the scope of the data import to the schema defined in the
> left panel.  That would give an easy way to keep the scope of what's going
> on down to something more manageable.  If there were no schema's defined
> there, then fine pull everything.  Just a thought.
> 
> 
> Tony
> 
> On Wed, Apr 28, 2021 at 12:47 PM Tony Giaccone  wrote:
> 
>> 
>> 
>> I'm trying to re-engineer a schema. I got through the process for a
>> postgres database and it works like a charm. Create the datamap, configure
>> the connection, refresh the db schema, and up pops the tables from the
>> database, just as you would expect.
>> 
>> I follow up with a similar task only this time trying to connect to an
>> Oracle DB and the process seems to be working up to the point where the
>> database schema should reflect the tables in the database, and there
>> nothing happens. The "Refresh DB Schema" button stays dim and inactive
>> almost as if it was stuck trying to pull back the schema. Now this is a
>> large db with a lot of tables and a lot of data in the tables (not that it
>> should matter, but...).  I've used the test button on the edit data source
>> preferences and it responds with a successful connection mesg.
>> 
>> I thought maybe it was just taking a long time, but i've waited 5 minutes
>> and nothing happens. Is there anyway to increase the logging level on the
>> modeler so that I can see what if anything is happening as it tries to load
>> up the schemal from this oracle db?
>> 
>> 
>> 
>> Tony
>> 



Re: Configuring multiple DataNodes

2021-04-23 Thread Andrus Adamchik
also per-node connection params can be passed as properties:

https://cayenne.apache.org/docs/4.1/cayenne-guide/#appendix-a-configuration-properties
 




> On Apr 23, 2021, at 10:58 AM, John Huss  wrote:
> 
> When you create your ServerRuntime you need to supply a custom DI module to
> pass the DB connection parameters, something like this:
> 
> *import* org.apache.cayenne.configuration.Constants;
> 
> *import* org.apache.cayenne.di.Binder;
> 
> *import* org.apache.cayenne.di.MapBuilder;
> 
> *import* org.apache.cayenne.di.Module;
> 
> 
> *public* *class* MyModule *implements* Module {
> 
> *public* *void* configure(Binder binder) {
> 
> MapBuilder mapBuilder = binder.bindMap(String.*class*, Constants.
> *PROPERTIES_MAP*);
> 
> mapBuilder.put(Constants.*JDBC_URL_PROPERTY* +
> ".YourDataDomainName.YourDataNodeName", System.*getenv*("url"));
> 
> ...
> 
> }
> 
> }
> 
> On Fri, Apr 23, 2021 at 9:32 AM Tony Giaccone  wrote:
> 
>> I have a datadomain with two datamaps, and two datasource each talking to a
>> different database.
>> 
>> Right now, I have had the datasource configured in the config file, but I
>> need to remove that and set it programmatically, from an environment
>> variable.  Simple enough to do with a defauldata source, unclear how to do
>> when you have multiple data sources and data nodes.
>> 
>> After browsing through the code and the app as it's running, it's unclear
>> to me how to do this.
>> 
>> Does anyone know the secret sauce?
>> 
>> 
>> 
>> Tony
>> 



Re: Cayenne-Generated PK (NULL not allowed for column "ID")

2021-04-23 Thread Andrus Adamchik
Sorry, this fell through the cracks. Yeah, there's API to reset PK generator 
(unfortunately the only piece of the stack that is not managed via DI):

  ServerRuntime runtime = ...;
  runtime.getDataDomain().getDataNode("mynode").getAdapter().setPkGenerator(new 
JdbcPkGenerator());

Andrus

> On Mar 30, 2021, at 7:56 AM, Gilberto Caetano de Andrade 
>  wrote:
> 
> 
> 
> On 2021/03/30 06:10:45, Andrus Adamchik  wrote: 
>> Yeah, schema handling for PK support objects is limited. So you adding it 
>> manually to the script was a good idea.
>> 
>>>> I choose JdbcAdapter because I want the Cayenne-Generated PK option
>> 
>> From the exception stack trace, your DB is "h2", so try using the H2 Adapter 
>> (org.apache.cayenne.dba.h2.H2Adapter) when doing DB generation.
>> 
> Andrus, as I've said I don't want the database specific pk management, I do 
> want  the cayenne one since I think is the easiest one to add new table.
> 
> Today, testing it again it throw the h2 sequence exception:
> 
> Caused by: org.apache.cayenne.CayenneRuntimeException: [v.4.1 Jul 14 2020 
> 10:26:08] Commit Exception
>   at 
> org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:774)
>   at 
> org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:691)
>   at 
> com.gilbertoca.corretagem.dao.NotaCayenneDao.create(NotaCayenneDao.java:59)
>   at 
> com.gilbertoca.corretagem.view.NotaController.salvar(NotaController.java:159)
>   ... 58 more
> Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Sequence "PK_NOTA" not 
> found; SQL statement:
> SELECT NEXT VALUE FOR corretagem.pk_nota [90036-200]
>   at org.h2.message.DbException.getJdbcSQLException(DbException.java:576)
>   at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
>   at org.h2.message.DbException.get(DbException.java:205)
>   at org.h2.message.DbException.get(DbException.java:181)
>   at org.h2.schema.Schema.getSequence(Schema.java:585)
> 
> Can I set it programmatically, the Cayenne one?
> Thank you!
> 
> Gilberto
> 
> 
>> 
>> 
>>> On Mar 29, 2021, at 10:12 PM, Gilberto Caetano de Andrade 
>>>  wrote:
>>> 
>>> The image: 
>>> https://www.dropbox.com/s/t3swzbn4fzrfyqb/CayenneModelerPkGeneration.png?dl=0
>>> 
>>> On 2021/03/29 19:08:11, Gilberto Caetano de Andrade  
>>> wrote: 
>>>> Hello,
>>>> 
>>>> Finally I could start personal project which I can use cayenne again after 
>>>> good time. I'm using the version 4.1 and every table/class were setup 
>>>> through Cayenne-Modeler, the PK generation strategy is the default one. At 
>>>> the db generate schema dialog I choose JdbcAdapter because I want the 
>>>> Cayenne-Generated PK option (image)
>>>> As you can see in the image, Cayenne-Modeler doesn't create the sql 
>>>> correctly for table auto_pk_support, missis the schema.
>>>> I discovery this on the first time I've tried to insert in the table and 
>>>> Cayenne gave an exception about sequence PK_NOTA existence, despite 
>>>> choosing the default option.
>>>> After that I've copied that generated sql, put the schema (corretagem) and 
>>>> update the database. I'm stoped again, on insert, this time because 
>>>> Cayenne have not set the ID, throuwing a commit exception:
>>>> 
>>>> Caused by: java.lang.reflect.InvocationTargetException
>>>>at 
>>>> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 
>>>> Method)
>>>>at 
>>>> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>>>>at 
>>>> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>>at java.base/java.lang.reflect.Method.invoke(Method.java:566)
>>>>at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
>>>>at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
>>>>at 
>>>> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>>at java.base/java.lang.reflect.Method.invoke(Method.java:566)
>>>>at 
>>>> javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
>>>>at 
>>>> javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
>>>>at 
>>>> javafx.fxml/java

Re: PK Generation and FrontBase

2021-04-20 Thread Andrus Adamchik



> On Apr 20, 2021, at 7:40 AM, Jérémy DE ROYER  
> wrote:
> 
> I remember this library at Frankfurt but I though it was mainly for 
> statistics purposes.

For me it has become a "Swiss Army knife" for any kind of data manipulation. It 
treats data as, well "data", not imposing any other abstraction. This makes it 
simple, yet powerful. Some use cases include recombining data from different 
otherwise incompatible data sources, moving data from one data source to 
another. And yes, data analytics as well. All my company internal ETL is done 
with DFLib, and business analytics - with DFLib and Jupyter.

Andrus



Re: PK Generation and FrontBase

2021-04-20 Thread Andrus Adamchik
va:36)
> at com.nhl.dflib.jdbc.connector.tx.Tx.call(Tx.java:56)
> at 
> com.nhl.dflib.jdbc.connector.saver.TableSaveStrategy.save(TableSaveStrategy.java:36)
> at com.nhl.dflib.jdbc.connector.TableSaver.save(TableSaver.java:89)
> at 
> your.app.SellAndPepperDatabaseMigration.main(SellAndPepperDatabaseMigration.java:78)
> 
> 
> FBJInputStream.read()
> ==
> 
> public int read() throws IOException {
> if (this.available <= 0L) {
> return -1;
> } else {
> if (this.buffer == null) {
> this.initBuffer();
> }
> 
> if (this.read == 0) {
> try {
> this.loadBuffer(this.nextOffset);
> } catch (Exception var2) {
> throw new IOException(var2.getMessage());
> }
> }
> 
> --this.read;
> --this.available;
> return this.buffer[this.position++] & 255;
> }
> }
> 
> 
> Le 19 avr. 2021 à 22:57, Andrus Adamchik 
> mailto:aadamc...@gmail.com>> a écrit :
> 
> The "power of DFLib" should help with this too :) Its main focus is 
> manipulating data in DataFrame columns after all, so you can adapt the data 
> you got from FB into something that can be saved to PG. E.g. [1]:
> 
> data = data.convertColumn("col_name", (Clob c) -> convertClob(c));
> 
> // implement this function
> String convertClob(Clob c) { ... }
> 
> Andrus
> 
> [1] https://nhl.github.io/dflib-docs/#changing-column-type
> 
> 
> 
> On Apr 19, 2021, at 4:37 PM, Jérémy DE ROYER 
> mailto:jeremy.dero...@ingencys.net>> wrote:
> 
> Hi Andrus,
> 
> I was just testing the schema migration script so why not testing ?
> 
> After editing the transfer line as
> 
> pg.tableSaver(table).mergeByPk().save(data);
> 
> to avoid duplication as explained in your doc...
> 
> It works really great 
> 
> The only one problem (there is always a problem) occured when conserting BLOB 
> (FrontBaseSQL) to TEXT (PostgresSQL). It outputs the error above.
> 
> Any simple idea ?
> 
> Jérémy
> 
> java.lang.RuntimeException: java.lang.RuntimeException: Error updating data 
> in DB: Impossible de convertir une instance de type 
> com.frontbase.jdbc.FBJClob vers le type String
> at com.nhl.dflib.jdbc.connector.tx.Tx.call(Tx.java:63)
> at 
> com.nhl.dflib.jdbc.connector.saver.TableSaveStrategy.save(TableSaveStrategy.java:36)
> at com.nhl.dflib.jdbc.connector.TableSaver.save(TableSaver.java:89)
> at 
> your.app.SellAndPepperDatabaseMigration.main(SellAndPepperDatabaseMigration.java:57)
> Caused by: java.lang.RuntimeException: Error updating data in DB: Impossible 
> de convertir une instance de type com.frontbase.jdbc.FBJClob vers le type 
> String
> at 
> com.nhl.dflib.jdbc.connector.StatementBuilder.update(StatementBuilder.java:110)
> at 
> com.nhl.dflib.jdbc.connector.saver.SaveViaInsert.doSave(SaveViaInsert.java:39)
> at 
> com.nhl.dflib.jdbc.connector.saver.SaveViaUpsert.insert(SaveViaUpsert.java:105)
> at 
> com.nhl.dflib.jdbc.connector.saver.SaveViaUpsert.doSave(SaveViaUpsert.java:52)
> at 
> com.nhl.dflib.jdbc.connector.saver.SaveViaUpsert.doSave(SaveViaUpsert.java:37)
> at 
> com.nhl.dflib.jdbc.connector.saver.TableSaveStrategy.lambda$save$1(TableSaveStrategy.java:36)
> at com.nhl.dflib.jdbc.connector.tx.Tx.call(Tx.java:56)
> ... 3 more
> Caused by: org.postgresql.util.PSQLException: Impossible de convertir une 
> instance de type com.frontbase.jdbc.FBJClob vers le type String
> at 
> org.postgresql.jdbc.PgPreparedStatement.cannotCastException(PgPreparedStatement.java:929)
> at 
> org.postgresql.jdbc.PgPreparedStatement.castToString(PgPreparedStatement.java:918)
> at 
> org.postgresql.jdbc.PgPreparedStatement.setObject(PgPreparedStatement.java:574)
> at 
> org.postgresql.jdbc.PgPreparedStatement.setObject(PgPreparedStatement.java:935)
> at 
> com.nhl.dflib.jdbc.connector.statement.DefaultColumnBinder.bind(DefaultColumnBinder.java:37)
> at 
> com.nhl.dflib.jdbc.connector.statement.StatementBinder.bind(StatementBinder.java:38)
> at 
> com.nhl.dflib.jdbc.connector.statement.UpdateStatementBatch.update(UpdateStatementBatch.java:40)
> at 
> com.nhl.dflib.jdbc.connector.StatementBuilder.update(StatementBuilder.java:108)
> ... 9 more
> Caused by: java.sql.SQLException
> at com.frontbase.jdbc.FBJConnection.readLOB(Unknown Source)
> at com.frontbase.jdbc.FBJClob.getSubString(Unknown Source)
> at 
> org.postgresql.jdbc.PgPreparedStatement.asString(PgPreparedStatement.java:738)
> at 
> org.postgresql.jdbc.PgPreparedStatement.castToString(PgPreparedStatement.java:912)
> ... 15 more
> 
> 
> 
> 
> Le 19 avr. 2021 à 20:20, Andrus Adamchik 
> mailto:aadamc...@gmail.com><mailto:aadamc...@gmail.com>> 
> a écrit :
> 
> LinkMove will definitely work, but is targeti

Re: PK Generation and FrontBase

2021-04-19 Thread Andrus Adamchik
The "power of DFLib" should help with this too :) Its main focus is 
manipulating data in DataFrame columns after all, so you can adapt the data you 
got from FB into something that can be saved to PG. E.g. [1]:

  data = data.convertColumn("col_name", (Clob c) -> convertClob(c));

  // implement this function
  String convertClob(Clob c) { ... }

Andrus

[1] https://nhl.github.io/dflib-docs/#changing-column-type



> On Apr 19, 2021, at 4:37 PM, Jérémy DE ROYER  
> wrote:
> 
> Hi Andrus,
> 
> I was just testing the schema migration script so why not testing ?
> 
> After editing the transfer line as
> 
> pg.tableSaver(table).mergeByPk().save(data);
> 
> to avoid duplication as explained in your doc...
> 
> It works really great 
> 
> The only one problem (there is always a problem) occured when conserting BLOB 
> (FrontBaseSQL) to TEXT (PostgresSQL). It outputs the error above.
> 
> Any simple idea ?
> 
> Jérémy
> 
> java.lang.RuntimeException: java.lang.RuntimeException: Error updating data 
> in DB: Impossible de convertir une instance de type 
> com.frontbase.jdbc.FBJClob vers le type String
> at com.nhl.dflib.jdbc.connector.tx.Tx.call(Tx.java:63)
> at 
> com.nhl.dflib.jdbc.connector.saver.TableSaveStrategy.save(TableSaveStrategy.java:36)
> at com.nhl.dflib.jdbc.connector.TableSaver.save(TableSaver.java:89)
> at 
> your.app.SellAndPepperDatabaseMigration.main(SellAndPepperDatabaseMigration.java:57)
> Caused by: java.lang.RuntimeException: Error updating data in DB: Impossible 
> de convertir une instance de type com.frontbase.jdbc.FBJClob vers le type 
> String
> at 
> com.nhl.dflib.jdbc.connector.StatementBuilder.update(StatementBuilder.java:110)
> at 
> com.nhl.dflib.jdbc.connector.saver.SaveViaInsert.doSave(SaveViaInsert.java:39)
> at 
> com.nhl.dflib.jdbc.connector.saver.SaveViaUpsert.insert(SaveViaUpsert.java:105)
> at 
> com.nhl.dflib.jdbc.connector.saver.SaveViaUpsert.doSave(SaveViaUpsert.java:52)
> at 
> com.nhl.dflib.jdbc.connector.saver.SaveViaUpsert.doSave(SaveViaUpsert.java:37)
> at 
> com.nhl.dflib.jdbc.connector.saver.TableSaveStrategy.lambda$save$1(TableSaveStrategy.java:36)
> at com.nhl.dflib.jdbc.connector.tx.Tx.call(Tx.java:56)
> ... 3 more
> Caused by: org.postgresql.util.PSQLException: Impossible de convertir une 
> instance de type com.frontbase.jdbc.FBJClob vers le type String
> at 
> org.postgresql.jdbc.PgPreparedStatement.cannotCastException(PgPreparedStatement.java:929)
> at 
> org.postgresql.jdbc.PgPreparedStatement.castToString(PgPreparedStatement.java:918)
> at 
> org.postgresql.jdbc.PgPreparedStatement.setObject(PgPreparedStatement.java:574)
> at 
> org.postgresql.jdbc.PgPreparedStatement.setObject(PgPreparedStatement.java:935)
> at 
> com.nhl.dflib.jdbc.connector.statement.DefaultColumnBinder.bind(DefaultColumnBinder.java:37)
> at 
> com.nhl.dflib.jdbc.connector.statement.StatementBinder.bind(StatementBinder.java:38)
> at 
> com.nhl.dflib.jdbc.connector.statement.UpdateStatementBatch.update(UpdateStatementBatch.java:40)
> at 
> com.nhl.dflib.jdbc.connector.StatementBuilder.update(StatementBuilder.java:108)
> ... 9 more
> Caused by: java.sql.SQLException
> at com.frontbase.jdbc.FBJConnection.readLOB(Unknown Source)
> at com.frontbase.jdbc.FBJClob.getSubString(Unknown Source)
> at 
> org.postgresql.jdbc.PgPreparedStatement.asString(PgPreparedStatement.java:738)
> at 
> org.postgresql.jdbc.PgPreparedStatement.castToString(PgPreparedStatement.java:912)
> ... 15 more
> 
> 
> 
> 
> Le 19 avr. 2021 à 20:20, Andrus Adamchik 
> mailto:aadamc...@gmail.com>> a écrit :
> 
> LinkMove will definitely work, but is targeting ongoing DB synchronization 
> instead of a one-off migration. I would personally deal with it in a more 
> low-tech way. Since you only need to do it once, the simplest tool is the 
> best. I would use DFLib library [1] to read data from one DB and write to 
> another. It was also presented in Frankfurt, and has evolved a lot since 
> then. Here is an example:
> 
> JdbcConnector fb = 
> Jdbc.connector("frontbase_url").username(..).password(..).build();
> JdbcConnector pg = Jdbc.connector("pg_url").username(..).password(..).build();
> 
> for(String table : tables) {
> DataFrame data = fb.tableLoader(table).load();
> pg.tableSaver(table).save(data);
> }
> As you see it can literally be done in a few lines of code and requires no 
> model.
> Andrus
> [1] https://nhl.github.io/dflib-docs/#jdbc
> 
> On Apr 16, 2021, at 6:00 AM, Michael Gentry 
> mailto:blackn...@gmail.com>> wrote:
> 
> Hi Jérémy,
> 
> I've never used it, but Andrus (and others) have a project called LinkMove
> which may work

Re: PK Generation and FrontBase

2021-04-19 Thread Andrus Adamchik
LinkMove will definitely work, but is targeting ongoing DB synchronization 
instead of a one-off migration. I would personally deal with it in a more 
low-tech way. Since you only need to do it once, the simplest tool is the best. 
I would use DFLib library [1] to read data from one DB and write to another. It 
was also presented in Frankfurt, and has evolved a lot since then. Here is an 
example:

JdbcConnector fb = 
Jdbc.connector("frontbase_url").username(..).password(..).build();
JdbcConnector pg = Jdbc.connector("pg_url").username(..).password(..).build();

for(String table : tables) {
DataFrame data = fb.tableLoader(table).load();
pg.tableSaver(table).save(data);
}
As you see it can literally be done in a few lines of code and requires no 
model. 
Andrus
[1] https://nhl.github.io/dflib-docs/#jdbc

> On Apr 16, 2021, at 6:00 AM, Michael Gentry  wrote:
> 
> Hi Jérémy,
> 
> I've never used it, but Andrus (and others) have a project called LinkMove
> which may work:
> 
> https://github.com/nhl/link-move
> 
> I don't see a way to re-use a Cayenne model as the source AND the target,
> but perhaps that is also an option (instead of the XML source), too.
> 
> 
> On Fri, Apr 16, 2021 at 4:14 AM Jérémy DE ROYER 
> wrote:
> 
>> Sorry, please read
>> 
>> « Migrate from FrontbaseSQL to PostgreSQL »  
>> 
>> Jérémy
>> 
>>> Le 16 avr. 2021 à 10:04, Jérémy DE ROYER 
>> a écrit :
>>> 
>>> Hi Hugi,
>>> 
>>> Unfortunately, I think you’re right.
>>> 
>>> I wanted to leave FrontbaseSQL too but as Andrus say, the meeting in
>> Frankfurt help me to resolve some cases and finally we keep our softwares
>> using FrontbaseSQL.
>>> 
>>> According to your experience, is there an easy way to migrate/transfert
>> from PostgreSQL to FrontBaseSQL ?
>>> 
>>> It could respond to the request from developers to have access to
>> programming tools with the database, not offered by FrontbaseSQL.
>>> 
>>> Thank’s for this highlight,
>>> 
>>> Jérémy
>>> 
 Le 16 avr. 2021 à 09:53, Hugi Thordarson  a écrit :
 
 Hi Jérémy,
 
 I believe you hit a bug in the FrontBase JDBC driver:
 https://issues.apache.org/jira/browse/CAY-2574 <
>> https://issues.apache.org/jira/browse/CAY-2574>
 
 Andrus wrote to FrontBase about this after our Frankfurt meetup:
 
>> https://mail-archives.apache.org/mod_mbox/cayenne-dev/201905.mbox/%3C52EC2486-4736-4854-AE49-A7CF77904E52%40objectstyle.org%3E
>> >> 
 
 I haven't seen anything from FB about this since this thread, perhaps
>> you should give their support a check?
 I also wrote to them last year about their JDBC driver not working on
>> more recent Java versions, but don't think they've fixed it. I ended up
>> migrating that one last FrontBase app to Postgres.
 
 Cheers,
 - hugi
 
 
 
> On 15 Apr 2021, at 20:59, Jérémy DE ROYER 
>> wrote:
> 
> Hi John,
> 
> I know that FrontbaseSQL is not commonly used but our all apps are
>> based on.
> 
> I’ve just :
> - created the model explained on the doc
>> https://cayenne.apache.org/docs/3.0/modeling-single-table-inheritance.html
> - wrote the code below inside the ‘Application’ class of a simple woapp
> 
> But yes, maybe Cayenne is not done to work with FrontbaseSQL… as it
>> works well with PostregSQL.
> 
> Thank’s for your answer and have a nice day,
> 
> Jérémy
> 
> Le 15 avr. 2021 à 22:50, John Huss > johnth...@gmail.com>> a écrit :
> 
> I don't think FrontBase is very commonly used. I would recommend
>> submitting
> a minimal example of the problem and someone should be able to fix the
> issue then.
> 
> On Thu, Apr 15, 2021 at 3:44 PM Jérémy DE ROYER <
>> jeremy.dero...@ingencys.net>
> wrote:
> 
> Hello,
> 
> I switched my model from FrontBase to PostgreSQL and it works great.
> 
> Does someone use Cayenne 4.1 with FrontbaseSQL successfully ?
> 
> Is there something specific to know ?
> 
> Thank’s for any tip,
> 
> Jérémy
> 
> Le 14 avr. 2021 à 23:05, Jérémy DE ROYER > >
> a écrit :
> 
> Hi all,
> 
> I’m trying to find a solution for the (temporary ?) lack of horizontal
> inheritance so I did model vertical inheritance following :
> 
> https://cayenne.apache.org/docs/3.0/modeling-vertical-inheritance.html
> 
> using a Frontbase database.
> 
> I did :
> - create the model,
> - generate the database,
> - fix lack of jars and other things like username, password, jdbc
>> driver
> 
> The demo code below starts well and connects to database...
> 
> try {
> ServerRuntime cayenneRuntime = ServerRuntime.builder()
> .addConfig("cayenne-CayenneTest.xml")
> .build();
> 
> ObjectContext context = 

Re: CayenneModeler crash

2021-04-19 Thread Andrus Adamchik
Hmm.. Don't have an M1 to test. Also weird that there's a difference between 
command line and GUI launch.

Andrus

> On Apr 19, 2021, at 2:31 AM, Lon Varscsak  wrote:
> 
> Hey all,
> 
> For some reason the recent version of CayenneModeler (4.2.M4-SNAPSHOT)
> crashes on launch.  The only thing I did was upgrade packages in HomeBrew.
> I'm running on an M1 MacBook Air.   I recompiled it and no luck.  If I run
> from the command line, it works fine though. 樂
> 
> Here's the console for the launch:
> 
> Apr 18 23:10:45 horcrux com.apple.xpc.launchd[1]: Coalition Cache Hit:
> app [750]
> Apr 18 23:10:47 horcrux java[1867]: getattrlist failed for
> /System/Library/Frameworks/OpenGL.framework/Resources//GLRendererFloat.bundle/GLRendererFloat:
> #2: No such file or directory
> Apr 18 23:10:49 horcrux com.apple.xpc.launchd[1]
> (application.CayenneModeler.5409263.1458111[1867]): Service exited with
> abnormal code: 1
> 
> Any ideas?
> 
> Thanks,
> 
> Lon



Re: Cayenne-Generated PK (NULL not allowed for column "ID")

2021-03-30 Thread Andrus Adamchik
Yeah, schema handling for PK support objects is limited. So you adding it 
manually to the script was a good idea.

>> I choose JdbcAdapter because I want the Cayenne-Generated PK option

From the exception stack trace, your DB is "h2", so try using the H2 Adapter 
(org.apache.cayenne.dba.h2.H2Adapter) when doing DB generation.

Andrus


> On Mar 29, 2021, at 10:12 PM, Gilberto Caetano de Andrade 
>  wrote:
> 
> The image: 
> https://www.dropbox.com/s/t3swzbn4fzrfyqb/CayenneModelerPkGeneration.png?dl=0
> 
> On 2021/03/29 19:08:11, Gilberto Caetano de Andrade  
> wrote: 
>> Hello,
>> 
>> Finally I could start personal project which I can use cayenne again after 
>> good time. I'm using the version 4.1 and every table/class were setup 
>> through Cayenne-Modeler, the PK generation strategy is the default one. At 
>> the db generate schema dialog I choose JdbcAdapter because I want the 
>> Cayenne-Generated PK option (image)
>> As you can see in the image, Cayenne-Modeler doesn't create the sql 
>> correctly for table auto_pk_support, missis the schema.
>> I discovery this on the first time I've tried to insert in the table and 
>> Cayenne gave an exception about sequence PK_NOTA existence, despite choosing 
>> the default option.
>> After that I've copied that generated sql, put the schema (corretagem) and 
>> update the database. I'm stoped again, on insert, this time because Cayenne 
>> have not set the ID, throuwing a commit exception:
>> 
>> Caused by: java.lang.reflect.InvocationTargetException
>>  at 
>> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 
>> Method)
>>  at 
>> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>>  at 
>> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>  at java.base/java.lang.reflect.Method.invoke(Method.java:566)
>>  at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
>>  at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
>>  at 
>> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>  at java.base/java.lang.reflect.Method.invoke(Method.java:566)
>>  at 
>> javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
>>  at 
>> javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
>>  at 
>> javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1782)
>>  ... 47 more
>> Caused by: org.apache.cayenne.CayenneRuntimeException: [v.4.1 Jul 14 2020 
>> 10:26:08] Commit Exception
>>  at 
>> org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:774)
>>  at 
>> org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:691)
>>  at 
>> com.gilbertoca.corretagem.dao.NotaCayenneDao.create(NotaCayenneDao.java:59)
>>  at 
>> com.gilbertoca.corretagem.view.NotaController.salvar(NotaController.java:142)
>>  ... 58 more
>> Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: NULL 
>> not allowed for column "ID"; SQL statement:
>> INSERT INTO corretagem.nota (agente_id, corretagem, dt_pregao, emolumentos, 
>> horario, irpf_operacao_base, iss, nr_nota, tx_ana, tx_liquidacao, 
>> tx_registro, tx_termo_opcao_futuro) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 
>> ?) [23502-200]
>>  at org.h2.message.DbException.getJdbcSQLException(DbException.java:459)
>>  at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
>>  at org.h2.message.DbException.get(DbException.java:205)
>>  at org.h2.message.DbException.get(DbException.java:181)
>>  at org.h2.table.Column.validateConvertUpdateSequence(Column.java:374)
>>  at org.h2.table.Table.validateConvertUpdateSequence(Table.java:845)
>>  at org.h2.command.dml.Insert.insertRows(Insert.java:187)
>>  at org.h2.command.dml.Insert.update(Insert.java:151)
>>  at 
>> org.h2.command.CommandContainer.executeUpdateWithGeneratedKeys(CommandContainer.java:272)
>>  at org.h2.command.CommandContainer.update(CommandContainer.java:191)
>>  at org.h2.command.Command.executeUpdate(Command.java:251)
>>  at 
>> org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:191)
>>  at 
>> org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:152)
>>  at 
>> org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(BatchAction.java:171)
>>  at 
>> org.apache.cayenne.access.jdbc.BatchAction.performAction(BatchAction.java:90)
>>  at 
>> org.apache.cayenne.access.DataNodeQueryAction.runQuery(DataNodeQueryAction.java:97)
>>  at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
>>  at 
>> org.apache.cayenne.access.DataDomainFlushAction.runQueries(DataDomainFlushAction.java:233)
>>  at 
>> 

[ANN] Cayenne 4.2.M3 released

2021-03-23 Thread Andrus Adamchik
I am glad to announce a release of Cayenne 4.2.M3. The release is stabilizing, 
so there are only a few new features. 

A notable one is support for annotated callback methods on entity classes 
(mapping those in the Modeler is annoying). Though we are still working out the 
performance aspects of it. So consider it "preview", and I'd advise to wait 
till the next release before going all in with annotations.

The most important part of the release is bug fixes though. I had a couple of 
personal blockers that prevented me from switching to 4.2 previously, such as 
incorrect SQL identifier quotation [1], MySQL 8 date time handling [2] (!! this 
may be a breaking change if you already used 4.2 with MySQL 8), precision of 
reverse-engineered dat/time types [3] and a few more. 

So I am looking forward to using M3 myself, and recommend an upgrade to all the 
current 4.2 users.

Andrus


[1] https://issues.apache.org/jira/browse/CAY-2686
[2] https://issues.apache.org/jira/browse/CAY-2691
[3] https://issues.apache.org/jira/browse/CAY-2694

Re: cdbimport for SQLite

2021-02-07 Thread Andrus Adamchik
Hi Maria,

CAY-2600 is a related, but separate issue. Here is the one that matches your 
problem: https://issues.apache.org/jira/browse/CAY-2695 
 . I just updated it with your 
description. I hope we can fix this specific problem as I mentioned in the 
Jira. But IIRC SQLite driver had deeper issues with DB metadata, so I suspect 
it may fail at some other step.

@Nikita - do you remember what other limitations we had with SQLite? Or does it 
finally start to work?

Andrus



> On Feb 6, 2021, at 10:52 PM, Maria Huber  wrote:
> 
> Hey all,
> this time my problem is related to the cdbimport feature (maven or modeller) 
> in combination with SQLite.
> SQLite does not support schema, so it's currently not possible to use the 
> reverse engineering feature.
> 
> The error you get with Xerial-JDBC driver is:
> 
> [WARNING] Error loading db schema
> Error loading db schema
> 
> java.sql.SQLFeatureNotSupportedException
>at org.sqlite.jdbc4.JDBC4DatabaseMetaData.getSchemas 
> (JDBC4DatabaseMetaData.java:32)
>at 
> org.apache.cayenne.modeler.editor.dbimport.DatabaseSchemaLoader.processSchemas
>  (DatabaseSchemaLoader.java:101)
>at 
> org.apache.cayenne.modeler.editor.dbimport.DatabaseSchemaLoader.processCatalogs
>  (DatabaseSchemaLoader.java:92)
>at org.apache.cayenne.modeler.editor.dbimport.DatabaseSchemaLoader.load 
> (DatabaseSchemaLoader.java:58)
>at org.apache.cayenne.modeler.action.LoadDbSchemaAction.loadDataBase 
> (LoadDbSchemaAction.java:116)
>at 
> org.apache.cayenne.modeler.action.LoadDbSchemaAction.lambda$performAction$0 
> (LoadDbSchemaAction.java:96)
>at java.lang.Thread.run (Thread.java:844)
> 
> or
> 
> [INFO] Exception on reverse engineering
> java.sql.SQLFeatureNotSupportedException
>at org.sqlite.jdbc4.JDBC4DatabaseMetaData.getSchemas 
> (JDBC4DatabaseMetaData.java:32)
>at 
> org.apache.cayenne.dbsync.reverse.filters.FiltersConfigBuilder.processSchemas 
> (FiltersConfigBuilder.java:117)
>at 
> org.apache.cayenne.dbsync.reverse.filters.FiltersConfigBuilder.processCatalogs
>  (FiltersConfigBuilder.java:107)
>at 
> org.apache.cayenne.dbsync.reverse.filters.FiltersConfigBuilder.preBuildFilters
>  (FiltersConfigBuilder.java:87)
> 
> getSchemas() throws this exception.
> 
> This error could be related to https://issues.apache.org/jira/browse/CAY-2600
> Any idea how to use cdbimport without schema?
> 
> Kind regards,
> Maria



Re: cayenne-maven-plugin and its executions environment

2021-02-03 Thread Andrus Adamchik
You have explicit execution ids (which is correct), while "default-cli" 
mentioned in the previous log, refers to the default execution (not either of 
the executions below). So yours are not called for some reason. 

Try adding "generate-sources" to each execution. 

Andrus


> On Feb 3, 2021, at 3:45 PM, Maria Huber  wrote:
> 
> 
> Hey Andrus,
> this is the relevant piece of code:
> 
> 
>
>
>org.apache.cayenne.plugins
>cayenne-maven-plugin
>${cayenne.version}
> 
>
>  
> cgen1
> 
>   
> ${project.basedir}/src/main/resources/mapA.map.xml
> 
> 
>   cgen
> 
>   
>   
> cgen2
> 
>   
> ${project.basedir}/src/main/resources/mapB.map.xml
> 
> 
>   cgen
> 
>   
> 
> 
>
>  ...
> 
> 
> Thanks for your great support.
> Maria
> 
> On 2021/02/03 10:34:01, Andrus Adamchik  wrote:
>>> Maybe that why the mentioned error "The parameters 'map' for goal 
>>> org.apache.cayenne.plugins:cayenne-maven-plugin:4.2.M2:cgen are missing or 
>>> invalid" occurs.>
>> 
>> Exactly. The question is why it is missing. Could you post the piece of your 
>> pom with two executions?>
>> 
>> Andrus >
>> 
>> 
>>> On Feb 3, 2021, at 10:41 AM, Maria Huber  wrote:>
>>>> 
>>> Hey Andrus,>
>>> I added two execution tags within the execution environment. According to 
>>> maven's '-X' output, the loaded configuration looks like this:>
>>>> 
>>> ">
>>> [DEBUG] Goal:  
>>> org.apache.cayenne.plugins:cayenne-maven-plugin:4.2.M2:cgen (default-cli)>
>>> [DEBUG] Style: Regular>
>>> [DEBUG] Configuration: >
>>> >
>>>   >
>>>   ${force}>
>>> >
>>> [DEBUG] 
>>> ===>
>>> ">
>>>> 
>>> So the map information is missing. Maybe that why the mentioned error "The 
>>> parameters 'map' for goal 
>>> org.apache.cayenne.plugins:cayenne-maven-plugin:4.2.M2:cgen are missing or 
>>> invalid" occurs.>
>>> Is there any Maven settings to change this import behavior?>
>>>> 
>>> Kind regards, Maria>
>>>> 
>>>> 
>>>> 
>>> On 2021/02/02 07:21:48, Andrus Adamchik  wrote:>
>>>> Defining two "" tags with different map names should be the 
>>>> solution to that. And this should work. After all global and per-execution 
>>>> config merging is a feature of the Maven engine, and Cayenne does not mess 
>>>> with it. Try running mvn with the "-X" option. It will print the actual 
>>>> merged configurations for each plugin invocation and will help to debug 
>>>> the issue.>>
>>>>> 
>>>> Andrus>>
>>>>> 
>>>>> 
>>>>> On Feb 1, 2021, at 11:14 PM, Maria Huber  wrote:>>
>>>>>>> 
>>>>> Hey Andrus,>>
>>>>> thanks for the help. Unfortunately this typing error doesn't solve my 
>>>>> problem.>>
>>>>> I want to define two different map-files and run for both the cgen 
>>>>> command. If possible this should work without running the modeler.>>
>>>>> Is there any solution to realize this in version 4.2.M2 (except the 
>>>>> execution environment)?>>
>>>>> The config outside configuration solution allows only to define one map.>>
>>>>>>> 
>>>>> Kind regards,>>
>>>>> Maria>>
>>>>>>> 
>>>>>>> 
>>>>> On 2021/02/01 05:53:27, Andrus Adamchik  wrote:>>
>>>>>> Hi Maria,>>>
>>>>>>>> 
>>>>>> This may be just a typo in your POM:>>>
>>>>>>>> 
>>>>>>> ${project.basedir}/src/main/resources/scenario/my.map.xml>>>
>>>>>>>> 
>>>>>> vs>>>
>>>>>>>> 
>>>>>>> ${project.basedir}/src/main/resources/

Re: cayenne-maven-plugin and its executions environment

2021-02-03 Thread Andrus Adamchik
> Maybe that why the mentioned error "The parameters 'map' for goal 
> org.apache.cayenne.plugins:cayenne-maven-plugin:4.2.M2:cgen are missing or 
> invalid" occurs.

Exactly. The question is why it is missing. Could you post the piece of your 
pom with two executions?

Andrus 


> On Feb 3, 2021, at 10:41 AM, Maria Huber  wrote:
> 
> Hey Andrus,
> I added two execution tags within the execution environment. According to 
> maven's '-X' output, the loaded configuration looks like this:
> 
> "
> [DEBUG] Goal:  
> org.apache.cayenne.plugins:cayenne-maven-plugin:4.2.M2:cgen (default-cli)
> [DEBUG] Style: Regular
> [DEBUG] Configuration: 
> 
>  
>  ${force}
> 
> [DEBUG] 
> ===
> "
> 
> So the map information is missing. Maybe that why the mentioned error "The 
> parameters 'map' for goal 
> org.apache.cayenne.plugins:cayenne-maven-plugin:4.2.M2:cgen are missing or 
> invalid" occurs.
> Is there any Maven settings to change this import behavior?
> 
> Kind regards, Maria
> 
> 
> 
> On 2021/02/02 07:21:48, Andrus Adamchik  wrote:
>> Defining two "" tags with different map names should be the 
>> solution to that. And this should work. After all global and per-execution 
>> config merging is a feature of the Maven engine, and Cayenne does not mess 
>> with it. Try running mvn with the "-X" option. It will print the actual 
>> merged configurations for each plugin invocation and will help to debug the 
>> issue.>
>> 
>> Andrus>
>> 
>> 
>>> On Feb 1, 2021, at 11:14 PM, Maria Huber  wrote:>
>>>> 
>>> Hey Andrus,>
>>> thanks for the help. Unfortunately this typing error doesn't solve my 
>>> problem.>
>>> I want to define two different map-files and run for both the cgen command. 
>>> If possible this should work without running the modeler.>
>>> Is there any solution to realize this in version 4.2.M2 (except the 
>>> execution environment)?>
>>> The config outside configuration solution allows only to define one map.>
>>>> 
>>> Kind regards,>
>>> Maria>
>>>> 
>>>> 
>>> On 2021/02/01 05:53:27, Andrus Adamchik  wrote:>
>>>> Hi Maria,>>
>>>>> 
>>>> This may be just a typo in your POM:>>
>>>>> 
>>>>> ${project.basedir}/src/main/resources/scenario/my.map.xml>>
>>>>> 
>>>> vs>>
>>>>> 
>>>>> ${project.basedir}/src/main/resources/my.map.xml>>
>>>>> 
>>>>> 
>>>> ("scenario" folder is missing in the last case)>>
>>>>> 
>>>> As an aside, since 4.1 CayenneModeler started to save your class 
>>>> generation settings in .map.xml in a portable way, so our default advice 
>>>> became to use CayenneModeler instead of Maven cgen for class generation. 
>>>> (But of course you can keep using Maven if that better fits your 
>>>> workflow).>>
>>>>> 
>>>> Andrus>>
>>>>> 
>>>>> 
>>>>> On Jan 31, 2021, at 7:36 PM, Maria Huber  wrote:>>
>>>>>>> 
>>>>> Hey,>>
>>>>> after spending quite some time, I still can't get the 
>>>>> cayenne-maven-plugin (4.4.M2) running as described in the latest 
>>>>> "Cayenne-Guide".>>
>>>>> The problem is related to the execution environment.>>
>>>>> This setting works just fine:>>
>>>>>>> 
>>>>> >>
>>>>>   org.apache.cayenne.plugins>>
>>>>>   cayenne-maven-plugin>>
>>>>>   ${cayenne.version}>>
>>>>>   >>
>>>>>   
>>>>> ${project.basedir}/src/main/resources/scenario/my.map.xml>>
>>>>>   >>
>>>>>   >>
>>>>>   >>
>>>>>   >>
>>>>>   cgen>>
>>>>>   >>
>>>>>   >>
>>>>>   >>
>>>>> >>
>>>>>>> 
>>>>> But if I put the configuration inside the execution tag (as described in 
>>>>> the Cayenne Guide), Maven can't find the map property.>>
>>>>>>> 
>>>>> >>
>>>>>   org.apache.cayenne.plugins>>
>>>>>   cayenne-maven-plugin>>
>>>>>   ${cayenne.version}>>
>>>>>   >>
>>>>>   >>
>>>>>   execution1>>
>>>>>   >>
>>>>>   
>>>>> ${project.basedir}/src/main/resources/my.map.xml>>
>>>>>   >>
>>>>>   >>
>>>>>   cgen>>
>>>>>   >>
>>>>>   >>
>>>>>   >>
>>>>> >>
>>>>>>> 
>>>>> This is the error message:>>
>>>>> "Failed to execute goal 
>>>>> org.apache.cayenne.plugins:cayenne-maven-plugin:4.2.M2:cgen (default-cli) 
>>>>> on project my-cayenne: The parameters 'map' for goal 
>>>>> org.apache.cayenne.plugins:cayenne-maven-plugin:4.2.M2:cgen are missing 
>>>>> or invalid">>
>>>>>>> 
>>>>> According to Stackoverflow, Maven handles the config-tag like this:>>
>>>>> 1. If the  is outside the  , it is the 
>>>>> configuration for the plugin to be used no matter what the life-cycle 
>>>>> phase is.>>
>>>>> 2. If the  is inside the , it is the 
>>>>> configuration to be used in certain life-cycle phase.>>
>>>>>>> 
>>>>> What could be the reason for this strange behavior?>>
>>>>>>> 
>>>>> Kind regards>>
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>> 
>>>>> 
>>>> 
>> 
>> 
> 



Re: SQLTemplate date types

2021-02-02 Thread Andrus Adamchik
Not currently, but I think we must implement it in some way. I can't imagine 
anyone still wanting to deal with java.sql.Timestamp.

Andrus

> On Feb 3, 2021, at 9:04 AM, Lon Varscsak  wrote:
> 
> Is there any way to change the default date types that get returned by
> SQLTemplate queries to use java.time classes instead of Date?
> 
> I know I can specify it for specific queries (#result), but I want to
> change them for the whole application.
> 
> Thanks,
> 
> Lon



Re: cayenne-maven-plugin and its executions environment

2021-02-01 Thread Andrus Adamchik
Defining two "" tags with different map names should be the solution 
to that. And this should work. After all global and per-execution config 
merging is a feature of the Maven engine, and Cayenne does not mess with it. 
Try running mvn with the "-X" option. It will print the actual merged 
configurations for each plugin invocation and will help to debug the issue.

Andrus


> On Feb 1, 2021, at 11:14 PM, Maria Huber  wrote:
> 
> Hey Andrus,
> thanks for the help. Unfortunately this typing error doesn't solve my problem.
> I want to define two different map-files and run for both the cgen command. 
> If possible this should work without running the modeler.
> Is there any solution to realize this in version 4.2.M2 (except the execution 
> environment)?
> The config outside configuration solution allows only to define one map.
> 
> Kind regards,
> Maria
> 
> 
> On 2021/02/01 05:53:27, Andrus Adamchik  wrote:
>> Hi Maria,>
>> 
>> This may be just a typo in your POM:>
>> 
>>> ${project.basedir}/src/main/resources/scenario/my.map.xml>
>> 
>> vs>
>> 
>>> ${project.basedir}/src/main/resources/my.map.xml>
>> 
>> 
>> ("scenario" folder is missing in the last case)>
>> 
>> As an aside, since 4.1 CayenneModeler started to save your class generation 
>> settings in .map.xml in a portable way, so our default advice became to use 
>> CayenneModeler instead of Maven cgen for class generation. (But of course 
>> you can keep using Maven if that better fits your workflow).>
>> 
>> Andrus>
>> 
>> 
>>> On Jan 31, 2021, at 7:36 PM, Maria Huber  wrote:>
>>>> 
>>> Hey,>
>>> after spending quite some time, I still can't get the cayenne-maven-plugin 
>>> (4.4.M2) running as described in the latest "Cayenne-Guide".>
>>> The problem is related to the execution environment.>
>>> This setting works just fine:>
>>>> 
>>> >
>>>org.apache.cayenne.plugins>
>>>cayenne-maven-plugin>
>>>${cayenne.version}>
>>>>
>>>
>>> ${project.basedir}/src/main/resources/scenario/my.map.xml>
>>>>
>>>>
>>>>
>>>>
>>>cgen>
>>>>
>>>>
>>>>
>>> >
>>>> 
>>> But if I put the configuration inside the execution tag (as described in 
>>> the Cayenne Guide), Maven can't find the map property.>
>>>> 
>>> >
>>>org.apache.cayenne.plugins>
>>>cayenne-maven-plugin>
>>>${cayenne.version}>
>>>>
>>>>
>>>execution1>
>>>>
>>>
>>> ${project.basedir}/src/main/resources/my.map.xml>
>>>>
>>>>
>>>cgen>
>>>>
>>>>
>>>>
>>> >
>>>> 
>>> This is the error message:>
>>> "Failed to execute goal 
>>> org.apache.cayenne.plugins:cayenne-maven-plugin:4.2.M2:cgen (default-cli) 
>>> on project my-cayenne: The parameters 'map' for goal 
>>> org.apache.cayenne.plugins:cayenne-maven-plugin:4.2.M2:cgen are missing or 
>>> invalid">
>>>> 
>>> According to Stackoverflow, Maven handles the config-tag like this:>
>>> 1. If the  is outside the  , it is the 
>>> configuration for the plugin to be used no matter what the life-cycle phase 
>>> is.>
>>> 2. If the  is inside the , it is the 
>>> configuration to be used in certain life-cycle phase.>
>>>> 
>>> What could be the reason for this strange behavior?>
>>>> 
>>> Kind regards>
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>> 
>> 
> 



Re: Spatialite Integration in Cayenne

2021-01-26 Thread Andrus Adamchik
We could switch all processors to the TypeAwareSQLTreeProcessor, there
> shouldn't be any issues.
> It's all about some free time to do it :)

Awesome! I am +1 to do it when we have a chance.

And eager to hear from Max on how it ultimately worked with SQLite. Hoping 
we'll be able to integrate the full solution in Cayenne.

Andrus



> On Jan 26, 2021, at 1:57 PM, Nikita Timofeev  
> wrote:
> 
> Hi Inayah,
> 
> You could wrap the SRID value to ValueNode in order for the SQL
> translator to generate a binding for the prepared statement.
> It would look something like this if you are using TypeAwareSQLTreeProcessor:
> 
> registerValueProcessor(Wkt.class, (parent, child, i) -> {
>Node geomFromText = FunctionNode.wrap(child, "GeomFromText");
>geomFromText.addChild(new ValueNode(SRID, false, null));
>return Optional.of(geomFromText);
> }
> 
> @Andrus
> We could switch all processors to the TypeAwareSQLTreeProcessor, there
> shouldn't be any issues.
> It's all about some free time to do it :)
> 
> On Mon, Jan 25, 2021 at 6:40 PM Inayah Max  wrote:
>> 
>> Hi Andrus,
>> thanks for your help. I made some progress by adding an own 
>> SpatialiteProcessor. But now a new challenge is coming up.
>> Spatialite forces to define a SRID within a GeomFromText-Functioncall.
>> 
>> 
>> The current wrapInFunction-method is implemented like this:
>> 
>> "INSERT INTO tabname (geom) VALUES (GeomFromText (?))";
>> 
>> To put the SRID inside the WRT-String is not working since the SQL engine is 
>> unaware that we intend using a SQL function.
>> Consequently it will handle the corresponding argument just as a plain text 
>> string.
>> Next an example insert query (SRID = 4236) that should work:
>> 
>> "INSERT INTO tabname (geom) VALUES (GeomFromText (?,4236))";
>> "INSERT INTO tabname (geom) VALUES (GeomFromText (?, ?),4236)"
>> 
>> 
>> Is it possible to add a second numeric parameter to the prepared statement?
>> 
>> Kind regards,
>> Max
>> 
>> 
>> Gesendet: Sonntag, 24. Januar 2021 um 08:17 Uhr
>> Von: "Andrus Adamchik" 
>> An: user@cayenne.apache.org
>> Betreff: Re: Spatialite Integration in Cayenne
>> Hi Inayah,
>> 
>> As you noticed, spatial features are still new in Cayenne, and we will need 
>> to fill more than a few gaps. So thanks for your feedback. This will help us 
>> to prioritize our effort in this area.
>> 
>>> WKT wrapper were added to the MySQLTreeProcessor and 
>>> PostgreSQLTreeProcessor. Both Processors extend a TypeAwareSQLTreeProcessor 
>>> and and add the "ST_"-Convert commands as required. In contrast the current 
>>> SQLiteTreeProcessor extends BaseSQLTreeProcessor.
>> 
>> Good point.
>> 
>> @Nikita: Is there a reason not to use TypeAwareSQLTreeProcessor as a 
>> superclass in all adapters? IIRC there's a minor performance hit, but looks 
>> like still worth it.
>> 
>> Andrus
>> 
>>> On Jan 23, 2021, at 11:18 PM, Inayah Max  wrote:
>>> 
>>> Hi all,
>>> my issue is related to the recently added support for geospatial types in 
>>> Cayenne. As I understand it, Mysql and Postgres spatial extensions are 
>>> already integrated in 4.2M2.
>>> This is great but doesn't fit to my tech stack. My lightweighted 
>>> application has to use a filebased database (spatialite) and can't rely on 
>>> a server based solution.
>>> Spatialite is an SQlite extention that adds spatial functionality to SQLite 
>>> in the same way like Postgis is doing for Postgres.
>>> My current progress is that Cayenne can use connect to a spatialite 
>>> database via JDBC (using jdbcUrl: 
>>> jdbc:sqlite:file.db?enable_load_extension=true and 
>>> SQLSelect.dataRowQuery("SELECT 
>>> load_extension('mod_spatialite');").select(context);). But all queries fail 
>>> since the ST-Functions are not implemented yet.
>>> 
>>> When looking at Cayenne spatial implementation, WKT wrapper were added to 
>>> the MySQLTreeProcessor and PostgreSQLTreeProcessor.
>>> Both Processors extend a TypeAwareSQLTreeProcessor and and add the 
>>> "ST_"-Convert commands as required.
>>> In contrast the current SQLiteTreeProcessor extends BaseSQLTreeProcessor. 
>>> Having no registerColumnProcess, the WKT convert can't take place in the 
>>> same way like before.
>>> Let me know if someone has an idea how to overcome this problem.
>>> Thanks.
>> 
> 
> 
> 
> -- 
> Best regards,
> Nikita Timofeev



Re: Storing a column containing a JSON-object before save

2021-01-04 Thread Andrus Adamchik
Hi Hugi,

FWIW, we are in the process of solving this exact problem of detecting changes 
in a complex value object for Cayenne's own JSON type available since 4.2:

https://github.com/apache/cayenne/pull/443 


In our case we had to do something even worse - parse a serialized JSON String 
to JSON to do semantic comparison to detect all possible invariants.

In your case a custom ValueObjectType is the way to go. You can simply 
implement a proper "equals" method in your object, and provide a 
ValueObjectType that will do (de)serialization. It will only be called when and 
if needed (i.e. when a change is detected by the "equals" method). This is 
actually a good solution that is going to perform faster than the above.

Andrus


> On Jan 3, 2021, at 10:32 PM, Hugi Thordarson  wrote:
> 
> Hi all,
> I've got a text column containing an object (or rather; an object structure) 
> that's been serialized to a JSON string. I'm currently just re-serializing 
> every time I change something—not very nice— so I'd like to do 
> something…nicer. I.e. preferably, cayenne would know that something within 
> the structure has changed, and take care of re-serializing for me (or let me 
> know I need to re-serialize before commit).
> I could re-serialize everything before every commit, but for performance 
> reasons I'd prefer to perform re-serialization only if the structure has 
> actually changed.
> 
> First thought was creating a custom ValueObjectType and just model the type 
> directly, but it seems like a bit of an overkill. Or perhaps it's not?
> 
> Grateful for any suggestions.
> 
> Cheers,
> - hugi
> 



Re: use Date values in ExpressionFactory.exp

2021-01-02 Thread Andrus Adamchik
> On Jan 2, 2021, at 3:45 PM, Mike Kienenberger  wrote:
> 
> Date date = new GregorianCalendar(2003, Calendar.JULY,17).getTime() ;
> Expression matchDateGreaterThanDate1 = 
> ExpressionFactory.greaterExp("MODIFIED_DATE", date);

As Mike said, the above should work, but if you are building an expression from 
String (instead of creating all clauses via the API), using parameters is the 
way to go as mentioned by John. Regarding the syntax... Cayenne supports named 
and positional parameters. The String syntax is the same for both ("$varname" 
for the param), but binding happens differently [1]:

// 1. Named params:
Map params = Collections.singletonMap("a", date);
Expression e = ExpressioFactory.exp("a > $a").params(params);

// 2. Positional params. Var name is ignored. Only its position is relevant, 
//and is matched with vararg position in the method:
Expression e = ExpressioFactory.exp("a > $a").paramsArray(date);

// 3. A shorter form of positional params:
Expression e = ExpressioFactory.exp("a > $a", date);

I personally use option #3 whenever I can, as it has the least amount of 
boilerplate.

Andrus


[1] 
https://cayenne.apache.org/docs/4.1/cayenne-guide/#creating-expressions-from-strings


> On Jan 2, 2021, at 5:48 PM, John Huss  wrote:
> 
> I think the string value would be $0 or $1. Or you can use .params with a
> map to do by name and use $date or whatever you want to name it.
> 
> On Sat, Jan 2, 2021 at 8:18 AM Andrea Biasillo  wrote:
> 
>> Yes, there is, but how will be the syntax?
>> 
>> 
>> 
>> On 2021/01/02 14:07:55, John Huss  wrote:
>> 
>>> Isn’t there a version of .exp that takes args? You can pass a date object
>> 
>>> directly there without worrying about formatting.
>> 
>>> 
>> 
>>> On Sat, Jan 2, 2021 at 7:49 AM Andrea Biasillo  wrote:
>> 
>>> 
>> 
 Hi Mike!
>> 
 
>> 
 
>> 
 
>> 
 I have tried with:
>> 
 
>> 
 
>> 
 
>> 
 Expression expDate = ExpressionFactory.exp("modifiedDate>
>> 
 TO_DATE('2003-07-17','-mm-dd')");
>> 
 
>> 
 
>> 
 
>> 
 but I get this exception:
>> 
 
>> 
 
>> 
 
>> 
 Caused by: org.apache.cayenne.exp.ExpressionException: [v.4.2.M1 Nov 26
>> 
 2020 09:20:26] Encountered " "(" "( "" at line 1, column 22.
>> 
 
>> 
 Was expecting one of:
>> 
 
>> 

>> 
 
>> 
"or" ...
>> 
 
>> 
"and" ...
>> 
 
>> 
"|" ...
>> 
 
>> 
"^" ...
>> 
 
>> 
"&" ...
>> 
 
>> 
"<<" ...
>> 
 
>> 
">>" ...
>> 
 
>> 
"+" ...
>> 
 
>> 
"-" ...
>> 
 
>> 
"/" ...
>> 
 
>> 
"*" ...
>> 
 
>> 
 
>> 
 
>> 
 and I really would want to have all my expression in one string,
>> without
>> 
 use greaterExp.
>> 
 
>> 
 Like this:
>> 
 
>> 
 
>> 
 
>> 
 Expression exp = ExpressionFactory.exp("businessPartnerName='andrea'
>> and
>> 
 businessPartnerCode!='rossi' or ((businessPartnerCode!='bianchi' and
>> 
 maxAdvancePaymentPercent>9) or businessPartnerCode!='pippo' or
>> 
 (maxAdvancePaymentPercent>100 or maxAdvancePaymentPercent<10)) and
>> 
 modifiedDate> TO_DATE('2003-07-17','-mm-dd')");
>> 
 
>> 
 
>> 
 
>> 
 But maybe it is not possible.
>> 
 
>> 
 
>> 
 
>> 
 Andrea
>> 
 
>> 
 
>> 
 
>> 
 On 2021/01/02 12:45:49, Mike Kienenberger  wrote:
>> 
 
>> 
> Oracle expects SQL like the following to compare dates.
>> 
 
>> 
> 
>> 
 
>> 
>   MODIFIED_DATE > TO_DATE('2003-07-17','-mm-dd')
>> 
 
>> 
> 
>> 
 
>> 
> You either need to use that in your exp() method, or use
>> greaterExp(),
>> 
 
>> 
> which can automatically generate the needed sql for the current
>> database.
>> 
 
>> 
> 
>> 
 
>> 
>Date date = new GregorianCalendar(2003, Calendar.JULY,
>> 
 
>> 
> 17).getTime() ;
>> 
 
>> 
>Expression matchDateGreaterThanDate1 =
>> 
 
>> 
> ExpressionFactory.greaterExp("MODIFIED_DATE", date);
>> 
 
>> 
> 
>> 
 
>> 
> 
>> 
 
>> 
> 
>> 
 
>> 
> 
>> 
 
>> 
> On Sat, Jan 2, 2021 at 3:45 AM Andrea Biasillo 
>> wrote:
>> 
 
>> 
> 
>> 
 
>> 
>> Hi!
>> 
 
>> 
>> 
>> 
 
>> 
>> Is it possible to use Date values in ExpressionFactory.exp?
>> 
 
>> 
>> 
>> 
 
>> 
>> This works very well:
>> 
 
>> 
>> 
>> 
 
>> 
>> Expression exp =
>> ExpressionFactory.exp("businessPartnerName='andrea'
>> 
 and
>> 
 
>> 
>> businessPartnerCode!='rossi' or ((businessPartnerCode!='bianchi'
>> and
>> 
 
>> 
>> maxAdvancePaymentPercent>9) or businessPartnerCode!='pippo' or
>> 
 
>> 
>> (maxAdvancePaymentPercent>100 or maxAdvancePaymentPercent<10))");
>> 
 
>> 
>> 
>> 
 
>> 
>> but if I use a Date value like this:
>> 
 
>> 
>> 
>> 
 
>> 
>> 

Re: Bug in DataRowsUtils

2020-11-20 Thread Andrus Adamchik
Case-sensitivity and default case conversions of DB names depend on the type of 
DB and even on DB configuration, making any assumptions highly unreliable. The 
solution to this issue between case interpretation between Cayenne model and DB 
is to use quotations. around identifiers Quotations make names case-sensitive 
on all databases. Just check "Quote SQL Identifiers" checkbox in the modeler 
next to a DataMap, and use quoted identifiers in your SQL.

FWIW, for the past 2-3 years I switched to this approach everywhere and no 
longer need to guess what capitalization to use.

Andrus


> On Nov 11, 2020, at 4:45 PM, Mark Stobbe  wrote:
> 
> Nice, exactly the solution that I also implemented!!
> 
> On Wed, Nov 11, 2020 at 2:16 PM John Huss  wrote:
> 
>> I also dislike this behavior, but I think it is intentional.
>> 
>> As I workaround I lowercase all the DbAttribute names in my DataMap at
>> startup and make sure all my MappedSelects use lowercase names.
>> 
>> On Wed, Nov 11, 2020 at 3:38 AM Mark Stobbe 
>> wrote:
>> 
>>> Hi all,
>>> 
>>> 
>>> 
>>> I was using MappedSelect to query for objects and I was surprised to see
>> I
>>> 
>>> was returned a HOLLOW object. After some investigation I found that
>>> 
>>> in DataRowUtils.refreshObjectWithSnapshot there is a check if we
>>> 
>>> fetched the whole object using a map.
>>> 
>>> 
>>> 
>>> However, the check ("snapshot.containsKey(dbAttrPath)") does not take
>> into
>>> 
>>> account the casing difference between database and datamap. This does
>> work
>>> 
>>> in the rest of Cayenne, but not here.
>>> 
>>> 
>>> 
>>> Mark
>>> 
>>> 
>> 



Re: ObjectSelect to select uncommitted objects

2020-11-17 Thread Andrus Adamchik
FWIW, there were requests for this functionality previously, but it was hard to 
achieve full feature parity between in-memory and DB evaluation, so we didn't 
do it yet. Perhaps we should do it incrementally over time, addressing various 
edge cases as we uncover them.

Andrus


> On Nov 16, 2020, at 11:29 PM, giulio.ces...@gmail.com wrote:
> 
> Thanks!!
> 
> I need to look carefully into this code, but it looks very promising.
> 
> Cheers,
> 
> Giulio Cesare
> 
> 
> On Mon, Nov 16, 2020 at 7:53 PM John Huss  wrote:
> 
>> There isn't anything built-in. I use this method in my own DataContext
>> subclass to do it. Use at your own risk, etc.
>> 
>> *public*  List
>> selectIncludingPendingChanges(ObjectSelect query) {
>> 
>> Set newAndModified = *new* HashSet<>(newObjects());
>> 
>> newAndModified.addAll(modifiedObjects());
>> 
>> Set inMemoryResults = newAndModified.stream()
>> 
>> .filter(o -> o.getClass().equals(query.getEntityType()))
>> 
>> .filter(o -> query.getWhere().match(o))
>> 
>> .map(o -> (T)o)
>> 
>> .collect(Collectors.*toSet*());
>> 
>> List dbResults = select(query);
>> 
>> dbResults.removeAll(newAndModified); // these have already been checked
>> 
>> dbResults.removeAll(deletedObjects());
>> 
>> *if* (inMemoryResults.isEmpty()) {
>> 
>> *return* dbResults; // performance optimization
>> 
>> }
>> 
>> inMemoryResults.addAll(dbResults); // combines and removes duplicates
>> 
>> List results = *new* ArrayList<>(inMemoryResults);
>> 
>> *if* (query.getOrderings() != *null* && !query.getOrderings().isEmpty()) {
>> 
>> Ordering.*orderList*(results, *new* ArrayList<>(query.getOrderings()));
>> 
>> }
>> 
>> *if* (query.getLimit() > 0) {
>> 
>> results = results.subList(0, query.getLimit());
>> 
>> }
>> 
>> *return* (List) results;
>> 
>> }
>> 
>> 
>> *public* *static* *class* Factory *extends* DataContextFactory {
>> 
>> @Override
>> 
>> *protected* MyDataContext newInstance(DataChannel parent, ObjectStore
>> objectStore) {
>> 
>> *return* *new* MyDataContext(parent, objectStore);
>> 
>> }
>> 
>> }
>> 
>> 
>> *public* *static* *final* Module *MODULE* = binder ->
>> 
>> 
>> binder.bind(ObjectContextFactory.*class*).to(MyDataContext.Factory.*class*);
>> 
>> 
>> 
>> On Sat, Nov 14, 2020 at 10:20 AM giulio.ces...@gmail.com <
>> giulio.ces...@gmail.com> wrote:
>> 
>>> Hello,
>>> 
>>> I have multiple places where I have to search data either on the current
>>> ObjectStore (newly inserted or modified objects) or directly in the DB.
>>> 
>>> At the moment I have two distinct blocks of code, one expressed as a
>>> Predicate (used inside a stream filter) and the other with an
>> ObjectSelect
>>> (on which I call its select method).
>>> 
>>> As both structure encode the same "logic" criteria, it would be nice to
>> be
>>> able to derive one from the other.
>>> 
>>> One way to solve this would be to be able to transform on ObjectSelect
>>> instance into a Predicate instance.
>>> Or, the ability to run an ObjectSelect not only on the DB, but also into
>>> the uncommitted objects in the ObjectContext.
>>> 
>>> Is there anything I am missing that could help me dealing with this need?
>>> 
>>> Cheers,
>>> 
>>> Giulio Cesare
>>> 
>> 



Re: When 4.2.M3 will be avaiabøe?

2020-11-13 Thread Andrus Adamchik
Hopefully soon. A few more things to finish before the release.


> On Nov 13, 2020, at 11:26 AM, Andrea Biasillo  wrote:
> 
> Hi!
> 
> When 4.2.M3 will be available?  I really need this:
> 
> https://issues.apache.org/jira/browse/CAY-2683?jql=project%20%3D%20CAY%20AND%20text%20~%20%22distinct%22
> 
> DISTINCT is overkilling some of my queries.
> 
> Many regards,
> Andrea



Re: about mysql support

2020-11-11 Thread Andrus Adamchik
I second that. MySQL 8 is supported.

I am only aware of one issue specific to MySQL 8 driver: timezone offset 
handling. It is similar to this: https://github.com/nhl/dflib/issues/113 . And 
it actually works in Cayenne, just that the data stored in DB is incompatible 
with the earlier versions of MySQL. And we are going to address this soon to 
restore compatibility.

Andrus



> On Nov 11, 2020, at 4:07 PM, John Huss  wrote:
> 
> Yes, all common DBs that have a JDBC driver are supported.
> 
> On Wed, Nov 11, 2020 at 3:11 AM 郑岩  wrote:
> 
>> Hello , I want to know if the Cayenne4 can support mysql8.0 Database?



Re: Issue java.io.StreamCorruptedException

2020-11-03 Thread Andrus Adamchik
Hi there,

I suspect this has nothing to do with CLOB and String. It may be other 
attributes. So a few questions:

1. What version of Cayenne is this?
2. Do you have a longer stack trace? 
3. Could you check the logs preceding the exception for messages like "Haven't 
found suitable ExtendedType for class..."

Andrus

> On Oct 31, 2020, at 5:51 PM, Giuseppe De Rosa  wrote:
> 
> I'm trying to make a simple select query but receive this error:
> 
> java.io.StreamCorruptedException: invalid stream header: 78780A1F 
> at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:857)
> 
> In datamap I have a db-attribute of type CLOB that I want read as a simple 
> String.
> 
> 
> length="7"/>
> isMandatory="true"/>
>
>
>
>ORACLE
>DISC_SEQ
>1
>
> 
> 
> db-attribute-path="DATE"/>
> db-attribute-path="ID"/>
> db-attribute-path="FLAG"/>
> db-attribute-path="REQUEST"/>
> 
> 
> I think that CLOB cannot map to java.lang.String but how can I read it?



Re: Spinning up Cayenne in a unit test.

2020-10-29 Thread Andrus Adamchik
> Because it's included in a bootique app, we can't use Bootique to do the
> testing here. 

You'd be adding Bootique dependencies to the test scope only, so none of it 
should leak to the modules that include your .jar. But there is a Bootique-free 
solution as well. See below.

> So any ideas about what might be going wrong here?


>> runtime = ServerRuntime.builder()
>>  .addConfig("cayenne-CohortManager.xml")
>>  .addModule(binder -> {
>>  ServerModule.contributeProperties(binder)
>>  .put("cayenne.jdbc.driver", "org.h2.Driver")
>>  .put("cayenne.jdbc.url", "jdbc:h2:mem:CohortDB");
>>  })
>>  .build();

Overriding connection properties affects a pre-existing DataNode. It won't 
create a new one. But using explicit ServerRuntimeBuilder API would result in 
creation of a so-called "synthetic" DataNode behind the scenes. So rewrite the 
above as follows:

runtime = ServerRuntime.builder()
 .addConfig("cayenne-CohortManager.xml")
 .jdbcDriver("org.h2.Driver")
 .url("jdbc:h2:mem:CohortDB")
 .build();

and this should produce a working stack.

Andrus


> On Oct 29, 2020, at 5:50 PM, Tony Giaccone  wrote:
> 
> Andrus, we're using Bootique, but this portion of the code is in it's own
> jar file, it's just the model and some basic services on the objects.
> Because it's included in a bootique app, we can't use Bootique to do the
> testing here. It needs to be just Cayenne. So any ideas about what might be
> going wrong here?
> 
> 
> Tony
> 
> On Thu, Oct 29, 2020 at 1:56 AM Andrus Adamchik 
> wrote:
> 
>> And while we are at it, I absolutely must plug a mention of Bootique 2.0 /
>> JUnit 5 testing facilities :)
>> 
>> https://bootique.io/docs/2.x/bootique-docs/#_testing
>> https://bootique.io/docs/2.x/bootique-jdbc-docs/#jdbc-testing
>> 
>> They are on a totally different level:
>> 
>> * Support for Docker/Testcontainers, so you'd test against a real DB, not
>> Derby or H2
>> * Liquibase migrations in tests, so you can use a real up-to-date schema
>> * "Global" scope for test databases and "apps", so you can share them
>> across test classes, improving performance
>> * Improved "Table" API for datatsets preparation and data assertions
>> 
>> Andrus
>> 
>> 
>>> On Oct 29, 2020, at 8:48 AM, Andrus Adamchik 
>> wrote:
>>> 
>>> You can still start a BQRuntime in tests, even if the module doesn't use
>> Bootique. Then you'd define a DataSource within BQRuntime, and
>> "bootique-cayenne" would create a DataNode for it automatically and
>> transparently. YMMV with older Bootique versions. E.g. Agrest (that has no
>> Bootique dependency itself) is using Bootique for tests.
>>> 
>>> Andrus
>>> 
>>>> On Oct 29, 2020, at 7:27 AM, Tony Giaccone  wrote:
>>>> 
>>>> This is what I have now for the spin up:
>>>> 
>>>> runtime = ServerRuntime.builder()
>>>>  .addConfig("cayenne-PriceIncrease.xml")
>>>>  .addModule(binder -> {
>>>>  ServerModule.contributeProperties(binder)
>>>>  .put("cayenne.jdbc.driver", "org.h2.Driver")
>>>>  .put("cayenne.jdbc.url", "jdbc:h2:mem:CohortDB");
>>>>  })
>>>>  .build();
>>>> DataNode node = new DataNode("testNode");
>>>> runtime.getDataDomain().setDefaultNode(node);
>>>> 
>>>> 
>>>> And now on commit changes I get this:
>>>> 
>>>> 
>>>> Caused by: java.lang.NullPointerException
>>>> at
>>>> 
>> org.apache.cayenne.access.DataDomainInsertBucket.createPermIds(DataDomainInsertBucket.java:103)
>>>> at
>>>> 
>> org.apache.cayenne.access.DataDomainInsertBucket.appendQueriesInternal(DataDomainInsertBucket.java:73)
>>>> 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)
>>>> 
>>>> 
>>>> 
>>>> On Wed, Oct 28, 2020 at 4:08 PM John Huss  wrote:
>>>> 
>>>>> You coul

Re: Spinning up Cayenne in a unit test.

2020-10-28 Thread Andrus Adamchik
And while we are at it, I absolutely must plug a mention of Bootique 2.0 / 
JUnit 5 testing facilities :) 

https://bootique.io/docs/2.x/bootique-docs/#_testing
https://bootique.io/docs/2.x/bootique-jdbc-docs/#jdbc-testing

They are on a totally different level:

* Support for Docker/Testcontainers, so you'd test against a real DB, not Derby 
or H2
* Liquibase migrations in tests, so you can use a real up-to-date schema
* "Global" scope for test databases and "apps", so you can share them across 
test classes, improving performance
* Improved "Table" API for datatsets preparation and data assertions

Andrus


> On Oct 29, 2020, at 8:48 AM, Andrus Adamchik  wrote:
> 
> You can still start a BQRuntime in tests, even if the module doesn't use 
> Bootique. Then you'd define a DataSource within BQRuntime, and 
> "bootique-cayenne" would create a DataNode for it automatically and 
> transparently. YMMV with older Bootique versions. E.g. Agrest (that has no 
> Bootique dependency itself) is using Bootique for tests. 
> 
> Andrus
> 
>> On Oct 29, 2020, at 7:27 AM, Tony Giaccone  wrote:
>> 
>> This is what I have now for the spin up:
>> 
>> runtime = ServerRuntime.builder()
>>   .addConfig("cayenne-PriceIncrease.xml")
>>   .addModule(binder -> {
>>   ServerModule.contributeProperties(binder)
>>   .put("cayenne.jdbc.driver", "org.h2.Driver")
>>   .put("cayenne.jdbc.url", "jdbc:h2:mem:CohortDB");
>>   })
>>   .build();
>> DataNode node = new DataNode("testNode");
>> runtime.getDataDomain().setDefaultNode(node);
>> 
>> 
>> And now on commit changes I get this:
>> 
>> 
>> Caused by: java.lang.NullPointerException
>> at
>> org.apache.cayenne.access.DataDomainInsertBucket.createPermIds(DataDomainInsertBucket.java:103)
>> at
>> org.apache.cayenne.access.DataDomainInsertBucket.appendQueriesInternal(DataDomainInsertBucket.java:73)
>> 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)
>> 
>> 
>> 
>> On Wed, Oct 28, 2020 at 4:08 PM John Huss  wrote:
>> 
>>> You could add a node at runtime:
>>> 
>>> DataNode node = *new* DataNode("node");
>>> 
>>> ... // configure node
>>> 
>>> runtime.getDataDomain().addNode(node);
>>> 
>>> runtime.getDataDomain().setDefaultNode(node);
>>> 
>>> On Wed, Oct 28, 2020 at 2:52 PM Tony Giaccone  wrote:
>>> 
>>>> So I have a project which is running in Bootique, but the data model is
>>>> used in several different apps. To facilitate this, we created a jar file
>>>> that includes the generated classes, and the code and the
>>>> cayenne-project.xml file in one jar file.  The result of this is tests
>>> run
>>>> for this jar, don't have access to the bootique runtime, as they are part
>>>> of a jar that's going to be included in other apps.
>>>> 
>>>> We're using an older version of Bootique and so the version of Cayenne is
>>>> 4.0.B2
>>>> 
>>>> The cayenne project, only has a datamap there is no datanode defined in
>>> the
>>>> xml.
>>>> 
>>>> So I'm trying to spin up a cayenne runtime, using this code.
>>>> 
>>>> runtime = ServerRuntime.builder()
>>>>   .addConfig("cayenne-CohortManager.xml")
>>>>   .addModule(binder -> {
>>>>   ServerModule.contributeProperties(binder)
>>>>   .put("cayenne.jdbc.driver", "org.h2.Driver")
>>>>   .put("cayenne.jdbc.url", "jdbc:h2:mem:CohortDB");
>>>>   })
>>>>   .build();
>>>> 
>>>> 
>>>> The problem is that later, when I try to commit changes, I get this
>>> error:
>>>> 
>>>> org.apache.cayenne.CayenneRuntimeException: [v.4.0.B2 Sep 26 2017
>>>> 10:05:06] No DataNode configured for DataMap 'datamap' and no default
>>>> DataNode set
>>>> 
>>>> I'm successfully able to run other tests, because they never do a
>>>> commitobjects.
>>>> 
>>>> 
>>>> Any suggestions on how to resolve my problem.
>>>> 
>>> 
> 



Re: Spinning up Cayenne in a unit test.

2020-10-28 Thread Andrus Adamchik
You can still start a BQRuntime in tests, even if the module doesn't use 
Bootique. Then you'd define a DataSource within BQRuntime, and 
"bootique-cayenne" would create a DataNode for it automatically and 
transparently. YMMV with older Bootique versions. E.g. Agrest (that has no 
Bootique dependency itself) is using Bootique for tests. 

Andrus

> On Oct 29, 2020, at 7:27 AM, Tony Giaccone  wrote:
> 
> This is what I have now for the spin up:
> 
> runtime = ServerRuntime.builder()
>.addConfig("cayenne-PriceIncrease.xml")
>.addModule(binder -> {
>ServerModule.contributeProperties(binder)
>.put("cayenne.jdbc.driver", "org.h2.Driver")
>.put("cayenne.jdbc.url", "jdbc:h2:mem:CohortDB");
>})
>.build();
> DataNode node = new DataNode("testNode");
> runtime.getDataDomain().setDefaultNode(node);
> 
> 
> And now on commit changes I get this:
> 
> 
> Caused by: java.lang.NullPointerException
> at
> org.apache.cayenne.access.DataDomainInsertBucket.createPermIds(DataDomainInsertBucket.java:103)
> at
> org.apache.cayenne.access.DataDomainInsertBucket.appendQueriesInternal(DataDomainInsertBucket.java:73)
> 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)
> 
> 
> 
> On Wed, Oct 28, 2020 at 4:08 PM John Huss  wrote:
> 
>> You could add a node at runtime:
>> 
>> DataNode node = *new* DataNode("node");
>> 
>> ... // configure node
>> 
>> runtime.getDataDomain().addNode(node);
>> 
>> runtime.getDataDomain().setDefaultNode(node);
>> 
>> On Wed, Oct 28, 2020 at 2:52 PM Tony Giaccone  wrote:
>> 
>>> So I have a project which is running in Bootique, but the data model is
>>> used in several different apps. To facilitate this, we created a jar file
>>> that includes the generated classes, and the code and the
>>> cayenne-project.xml file in one jar file.  The result of this is tests
>> run
>>> for this jar, don't have access to the bootique runtime, as they are part
>>> of a jar that's going to be included in other apps.
>>> 
>>> We're using an older version of Bootique and so the version of Cayenne is
>>> 4.0.B2
>>> 
>>> The cayenne project, only has a datamap there is no datanode defined in
>> the
>>> xml.
>>> 
>>> So I'm trying to spin up a cayenne runtime, using this code.
>>> 
>>> runtime = ServerRuntime.builder()
>>>.addConfig("cayenne-CohortManager.xml")
>>>.addModule(binder -> {
>>>ServerModule.contributeProperties(binder)
>>>.put("cayenne.jdbc.driver", "org.h2.Driver")
>>>.put("cayenne.jdbc.url", "jdbc:h2:mem:CohortDB");
>>>})
>>>.build();
>>> 
>>> 
>>> The problem is that later, when I try to commit changes, I get this
>> error:
>>> 
>>> org.apache.cayenne.CayenneRuntimeException: [v.4.0.B2 Sep 26 2017
>>> 10:05:06] No DataNode configured for DataMap 'datamap' and no default
>>> DataNode set
>>> 
>>> I'm successfully able to run other tests, because they never do a
>>> commitobjects.
>>> 
>>> 
>>> Any suggestions on how to resolve my problem.
>>> 
>> 



Re: Issue with FrontBase PK generation in Cayenne 4.1

2020-10-18 Thread Andrus Adamchik
Yes, SQLTemplate is processed via a different JDBC call in 4.1.

> On Oct 18, 2020, at 7:57 PM, Amedeo Mantica  
> wrote:
> 
> btw I have no issues using Cayenne 4.0.2, the issue happens only in 4.1
> 
>> On 18 Oct 2020, at 09:36, Andrus Adamchik  wrote:
>> 
>> Hi Amedeo,
>> 
>> You hit this issue: https://issues.apache.org/jira/browse/CAY-2574 
>> <https://issues.apache.org/jira/browse/CAY-2574> . This is a bug in 
>> FrontBase driver. We started a conversation with FrontBase folks a year and 
>> a half ago, and even made some progress. But it died down and we are where 
>> we are. I suppose we are back to Plan B - fixing the driver bug on Cayenne 
>> end in the FrontBaseAdapter (e.g. by skipping SQLTemplate and using raw 
>> JDBC). 
>> 
>> Andrus
>> 
>> P.S. How many FrontBase users are still out there? We are having a hard time 
>> testing Cayenne against FB because of the various issues in the driver. We 
>> may use some help from someone motivated to maintain the adapter, or it is 
>> going to deteriorate even further. 
>> 
>> 
>>> On Oct 17, 2020, at 2:20 PM, Amedeo Mantica  
>>> wrote:
>>> 
>>> Hi,
>>> 
>>> I have noticed an NPE in PrimaryKey generation when using Frointbase 
>>> database
>>> 
>>> Cayenne version 4.0.2 works fine, but in Cayenne 4.1 there is an issue in 
>>> SQLTemplateAction
>>> 
>>> the line
>>> 
>>> PreparedStatement statement = 
>>> connection.prepareStatement(compiled.getSql());
>>> 
>>> returns a null statement, causing NPE in statement.close(), even if the 
>>> compiled SQL is valid.
>>> 
>>> Thoughts ?
>>> 
>>> Thank you
>>> Amedeo
>> 
> 



Re: Issue with FrontBase PK generation in Cayenne 4.1

2020-10-18 Thread Andrus Adamchik
Hi Amedeo,

You hit this issue: https://issues.apache.org/jira/browse/CAY-2574 
 . This is a bug in FrontBase 
driver. We started a conversation with FrontBase folks a year and a half ago, 
and even made some progress. But it died down and we are where we are. I 
suppose we are back to Plan B - fixing the driver bug on Cayenne end in the 
FrontBaseAdapter (e.g. by skipping SQLTemplate and using raw JDBC). 

Andrus

P.S. How many FrontBase users are still out there? We are having a hard time 
testing Cayenne against FB because of the various issues in the driver. We may 
use some help from someone motivated to maintain the adapter, or it is going to 
deteriorate even further. 


> On Oct 17, 2020, at 2:20 PM, Amedeo Mantica  
> wrote:
> 
> Hi,
> 
> I have noticed an NPE in PrimaryKey generation when using Frointbase database
> 
> Cayenne version 4.0.2 works fine, but in Cayenne 4.1 there is an issue in 
> SQLTemplateAction
> 
> the line
> 
> PreparedStatement statement = connection.prepareStatement(compiled.getSql());
> 
> returns a null statement, causing NPE in statement.close(), even if the 
> compiled SQL is valid.
> 
> Thoughts ?
> 
> Thank you
> Amedeo



Re: Resetting an object back to committed state (including relationships)

2020-10-18 Thread Andrus Adamchik
"invalidateObjects" should invalidate relationships too. IIRC this worked 
exactly as you'd expect in a root context. I don't use nested contexts. Wonder 
if a bug crept in there?

Andrus


> On Oct 18, 2020, at 2:53 AM, Lon Varscsak  wrote:
> 
> I have a situation where I need to invalidate an object and have it go
> back to it's committed state (whether that's from the db or a parent
> context).  If I invalidate the object, it's attributes seem to do what I'm
> expecting, but it appears that it leaves relationships alone.  I need a way
> to invalidate all of it's relationships, restore those objects back to
> their committed state (maybe they've been deleted or modified...as well as
> get rid of any newly created objects).  How would I accomplish this?  A
> child context doesn't work in my case...because the user has already
> "saved" to the parent...it's that a later behavior triggers them to say,
> nah, never mind...I want the original object back.
> 
> Note: I'm pretty sure in EOF I just called invalidate objects on the main
> object and everything else was taken care of...not positive though.
> 
> Thanks in advance for the help!
> 
> -Lon



Re: [ANN] Cayenne 4.2.M2 release

2020-10-13 Thread Andrus Adamchik
To expand a bit, Cayenne basically provides a way to map DB-specific JSON 
columns to "org.apache.cayenne.value.Json". This gives a (hopefully) smooth 
experience reading and writing such values. How to use it:

1. Ensure your DB supports native JSON type (e.g. Postgres)
2. Map your DbAttribute as type "OTHER" 
3. Map your ObjAttribute as "org.apache.cayenne.value.Json"

2 & 3 would happen automatically on reverse-engineering if you are using 
DB-first flow. "org.apache.cayenne.value.Json" is simply a String wrapper. It 
intentionally doesn't have any parsing logic. Its purpose is to be a performant 
dependency-free container to pass JSON payload between the app and DB. If you 
need JSON as a tree, you may take a few more steps:

4. Pick a JSON parser such as Jackson.
5. Map ObjAttribute as a type supported by that parser (e.g. JsonNode in 
Jackson)
6. Write and register a custom "ValueObjectType" [1]
7. There is even a way to use DB-specific functions to query JSON [2] 

@Nikita: is it possible to apply custom functions in the WHERE clause as well?

Andrus

[1] https://cayenne.apache.org/docs/4.2/cayenne-guide/#value-object-type 
<https://cayenne.apache.org/docs/4.2/cayenne-guide/#value-object-type>
[2] 
https://github.com/apache/cayenne-examples/blob/master/cayenne-jdbc-type-other/src/main/java/org/apache/cayenne/demo/JsonTestCommand.java#L59



> On Oct 13, 2020, at 11:07 AM, Nikita Timofeev  
> wrote:
> 
> Hi Markus,
> 
> No docs for that yet, but here's an example of new types usage:
> 
> https://github.com/apache/cayenne-examples/tree/master/cayenne-jdbc-type-other
> 
> On Tue, Oct 13, 2020 at 10:41 AM Markus Reich  wrote:
>> 
>> Hi Andrus,
>> 
>> is there an example or doc for the support of JSON types?
>> 
>> regards
>> Meex
>> 
>> Am Di., 13. Okt. 2020 um 08:48 Uhr schrieb Andrus Adamchik <
>> and...@objectstyle.org>:
>> 
>>> 4.2.M2 release is out [1]. A few cool things in this release:
>>> 
>>> * Support for JSON and geospatial value types.
>>> * Ordering on aggregate functions and in-memory evaluation of aggregate
>>> expressions.
>>> * Modeler support for downloading JDBC drivers from maven central.
>>> * Runtime changes that may be less obvious to the end user, but allow to
>>> handle a variety of edge cases.
>>> * Bug fixes
>>> 
>>> Also looks like we are pretty close to beta freeze. The main scope of 4.2
>>> is done, though of course improvement ideas keep popping up all the time,
>>> especially now that the new stack significantly expanded our SQL vocabulary
>>> and JDBC capabilities. E.g. one such idea is using EXISTS instead of JOIN +
>>> DISTINCT for to-many conditions [2].
>>> 
>>> Enjoy M2!
>>> 
>>> Andrus
>>> 
>>> [1] https://cayenne.apache.org/2020/10/cayenne-42m2-released/
>>> [2] https://issues.apache.org/jira/browse/CAY-2684
>> 
>> 
>> 
>> --
>> *Markus Reich*
>> Waldweg 62
>> 6393 St. Ulrich am Pillersee
>> www.markusreich.at / www.meeximum.at
>> markus.re...@markusreich.at
> 
> 
> 
> -- 
> Best regards,
> Nikita Timofeev



Re: [ANN] Cayenne 4.2.M2 release

2020-10-13 Thread Andrus Adamchik
Hi Jeremy, 

Not in 4.2 unfortunately, but all these stack changes take us closer to 
supporting horizontal inheritance. I am pretty optimistic horizontal will be 
implemented in 5.0 (and vertical - made much less annoying). 

> If the Cayenne team need helpers / testers / others, just tell me 

Much appreciated!

Andrus

> On Oct 13, 2020, at 9:58 AM, Jérémy DE ROYER  
> wrote:
> 
> Hello Andrus,
> 
> Is there any plan for horizontal inheritance ? Unfortunately it is a must 
> have for us.
> 
> If the Cayenne team need helpers / testers / others, just tell me 
> 
> Many thank's
> 
> Jérémy
> 
>> Le 13 oct. 2020 à 08:48, Andrus Adamchik  a écrit :
>> 
>> 4.2.M2 release is out [1]. A few cool things in this release:
>> 
>> * Support for JSON and geospatial value types.
>> * Ordering on aggregate functions and in-memory evaluation of aggregate 
>> expressions.
>> * Modeler support for downloading JDBC drivers from maven central.
>> * Runtime changes that may be less obvious to the end user, but allow to 
>> handle a variety of edge cases.
>> * Bug fixes
>> 
>> Also looks like we are pretty close to beta freeze. The main scope of 4.2 is 
>> done, though of course improvement ideas keep popping up all the time, 
>> especially now that the new stack significantly expanded our SQL vocabulary 
>> and JDBC capabilities. E.g. one such idea is using EXISTS instead of JOIN + 
>> DISTINCT for to-many conditions [2].
>> 
>> Enjoy M2!
>> 
>> Andrus
>> 
>> [1] https://cayenne.apache.org/2020/10/cayenne-42m2-released/
>> [2] https://issues.apache.org/jira/browse/CAY-2684
> 



[ANN] Cayenne 4.2.M2 release

2020-10-13 Thread Andrus Adamchik
4.2.M2 release is out [1]. A few cool things in this release:

* Support for JSON and geospatial value types.
* Ordering on aggregate functions and in-memory evaluation of aggregate 
expressions.
* Modeler support for downloading JDBC drivers from maven central.
* Runtime changes that may be less obvious to the end user, but allow to handle 
a variety of edge cases.
* Bug fixes

Also looks like we are pretty close to beta freeze. The main scope of 4.2 is 
done, though of course improvement ideas keep popping up all the time, 
especially now that the new stack significantly expanded our SQL vocabulary and 
JDBC capabilities. E.g. one such idea is using EXISTS instead of JOIN + 
DISTINCT for to-many conditions [2].

Enjoy M2!

Andrus

[1] https://cayenne.apache.org/2020/10/cayenne-42m2-released/
[2] https://issues.apache.org/jira/browse/CAY-2684

Re: Cayenne 4.2—Modifying SQL generation to always use COALESCE when updating a certain column

2020-09-11 Thread Andrus Adamchik
4.2 for the first time exposes generated SQL as an AST, so tweaking it has 
become much easier. This is the feature that made possible to support 
geospatial and JSON types.

Nikita, please correct me if I am wrong with the following instructions (as 
this API is still in flux). So.. To customize produced SQL, you will need to 
register a custom DbAdapter that returns a custom SQLTreeProcessor.  
SQLTreeProcessor is a SQL tree walking callback that can change the default 
tree structure. Your own processor can extend TypeAwareSQLTreeProcessor. See 
for instance PostgreSQLTreeProcessor for how to change the default behavior.

Andrus


> On Sep 8, 2020, at 11:12 PM, Hugi Thordarson  wrote:
> 
> Working with old DB designs really results in the weirdest questions…
> 
> So… I've been working around a design problem in a customer DB by using my 
> own BatchTranslatorFactory. The functionality was that if a column is called 
> "company", every update wraps the column's new value in a coalesce function 
> to ensure that it's never set to null (for… reasons). This has worked great 
> as a workaround for our problem.
> 
> However, SQL generation in Cayenne 4.2 is all new so my current solution ( 
> https://gist.github.com/hugith/a33a20fc7da7fd8f709f59ce3a30a96a 
>  ) doesn't 
> really port.
> Before I start considering migration to 4.2, is this possible to do there? Or 
> should I just bite the bullet and start fixing up that bloody DB before 
> upgrading?
> 
> Cheers,
> - hugi



Re: DomainStoppedException: Domain project was shutdown...

2020-09-08 Thread Andrus Adamchik
Hi,

This indicates that Cayenne was accessed after the stack shutdown. The only 
place that may happen in Bootique is when the entire app is stopped and 
ShutdownManager is called [1]. Also this should be an unrecoverable error, so 
after you see it once, all subsequent Cayenne operations would keep throwing 
it. So it appears that you start and stop the app every time the job is run 
(which is fine of course)? And the reason for the error may be that the app is 
shutdown while the job is still in progress. So how does the app command line 
look like?

(Also this message came to the list through moderation, meaning you are not 
subscribed and may miss some replies. Make sure to check the list archives for 
other replies).

Andrus

[1] 
https://github.com/bootique/bootique-cayenne/blob/d2630f3e1ff3a76f1f46a694fdefd8286a2d90fb/bootique-cayenne/src/main/java/io/bootique/cayenne/CayenneModule.java#L102


> On Sep 8, 2020, at 12:17 PM, Alexander Zapasnik  
> wrote:
> 
> Hello everyone.
> 
> I have a bootique application which uses a 5 minute cron job to update DB
> via some rules.
> I've noticed that sometimes it throws DomainStoppedException.
> It is hard to reproduce it as it happens just a few times per day.
> 
> I can't get why this might happen. Any thoughts?
> 
> org.apache.cayenne.access.DomainStoppedException: [v.4.0 Aug 06 2018
>> 12:11:43] Domain project was shutdown and can no longer be used to access
>> the database
>>at
>> org.apache.cayenne.access.DataDomain.checkStopped(DataDomain.java:181)
>> ~[cayenne-server-4.0.jar:4.0]
>>at
>> org.apache.cayenne.access.DataDomain.onQuery(DataDomain.java:554)
>> ~[cayenne-server-4.0.jar:4.0]
>>at
>> org.apache.cayenne.util.ObjectContextQueryAction.runQuery(ObjectContextQueryAction.java:406)
>> ~[cayenne-server-4.0.jar:4.0]
>>at
>> org.apache.cayenne.util.ObjectContextQueryAction.executePostCache(ObjectContextQueryAction.java:107)
>> ~[cayenne-server-4.0.jar:4.0]
>>at
>> org.apache.cayenne.util.ObjectContextQueryAction.execute(ObjectContextQueryAction.java:94)
>> ~[cayenne-server-4.0.jar:4.0]
>>at
>> org.apache.cayenne.access.DataContext.onQuery(DataContext.java:965)
>> ~[cayenne-server-4.0.jar:4.0]
>>at
>> org.apache.cayenne.access.DataContext.performQuery(DataContext.java:954)
>> ~[cayenne-server-4.0.jar:4.0]
>>at
>> org.apache.cayenne.access.ToOneFault.doResolveFault(ToOneFault.java:81)
>> ~[cayenne-server-4.0.jar:4.0]
>>at
>> org.apache.cayenne.access.ToOneFault.resolveFault(ToOneFault.java:54)
>> ~[cayenne-server-4.0.jar:4.0]
>>at
>> org.apache.cayenne.CayenneDataObject.readProperty(CayenneDataObject.java:180)
>> ~[cayenne-server-4.0.jar:4.0]
>>at
>> org.apache.cayenne.CayenneDataObject.setToOneTarget(CayenneDataObject.java:357)
>> ~[cayenne-server-4.0.jar:4.0]
>> 



Re: VARCHAR vs LONGVARCHAR vs CLOB

2020-09-08 Thread Andrus Adamchik
> should I just define everything as VARCHAR and forget about it?

Yes. CLOBs have some special handling, which is irrelevant for Postgres. 


> On Sep 7, 2020, at 5:43 PM, Hugi Thordarson  wrote:
> 
> Hi all,
> while looking further into migration to 4.2 I noticed my model has several 
> DbAttributes defined as CLOBs, leftovers from our previous database 
> (Informix).
> 
> Since we have migrated to Postgres and these columns are now just regular 
> varchar/text columns, I'm going to redefine them in the model as such. So I'm 
> wondering, mainly out of curiosity; is there any difference in how fields of 
> type VARCHAR and LONGVARCHAR are handled WRT Cayenne or should I just define 
> everything as VARCHAR and forget about it?
> 
> Cheers,
> - hugi



Re: Programmatically adding (db/obj) attributes to a model and saving

2020-09-08 Thread Andrus Adamchik
Yeah, that's as good as it gets. ProjectLoader/Saver deal with multi-file 
projects. If you need to modidy a single existing DataMap, XMLEncoder is what 
you need.

Andrus

> On Sep 6, 2020, at 12:25 PM, Hugi Thordarson  wrote:
> 
> Well that's no fun when you have this nice purpose-build API right at your 
> hands :).
> I ended up doping the encodeAsXML-thing. It worked well enough that it only 
> took a couple of seconds to fix up the resulting XML file, et voila — 250 new 
> attributes in 50 entities :).
> 
> Cheers,
> - hugi
> 
> 
>> On 5 Sep 2020, at 14:11, Michael Gentry  wrote:
>> 
>> I'm naive enough that I'd just use a macro in Emacs to modify the mapping...
>> 
>> 
>> On Sat, Sep 5, 2020 at 5:14 AM Hugi Thordarson  wrote:
>> 
>>> Hi all,
>>> I'm adding some standard attributes to a few dozen tables. Since they all
>>> look more or less the same, I'd like to do it programmatically.
>>> That's easy enough, but I'm wondering what the best way would be for me to
>>> write out the project after adding the attributes.
>>> 
>>> I've currently got something like:
>>> 
>>> XMLEncoder encoder = new XMLEncoder( new PrintWriter( new File(
>>> "new.map.xml" ) ) );
>>> map.encodeAsXML( encoder, new EmptyConfigurationNodeVisitor() );
>>> 
>>> …which works kinda-sorta. But I imagine there's a better or more idiomatic
>>> way using something like ProjectLoader or ProjectSaver?
>>> 
>>> Cheers,
>>> - hugi
> 



Re: SQLSelect and Prefetching (cayenne 4.1)

2020-07-30 Thread Andrus Adamchik

> It can theoretically support DISJOINT_BY_ID, but IIRC it does not.

Actually I was wrong about this one. DISJOINT_BY_ID works just fine with 
SQLSelect, and will save you a lot of trouble mapping SQL:
List result = SQLSelect.query(Artist.class, "SELECT "
+ "#result('ARTIST_NAME' 'String'), "
+ "#result('DATE_OF_BIRTH' 'java.util.Date'), "
+ "#result('t0.ARTIST_ID' 'int' '' 'ARTIST_ID') "
+ "FROM ARTIST t0")
.addPrefetch(Artist.PAINTINGS.disjointById())
.select(context);
I'll make sure we update the docs.

Andrus

> On Jul 30, 2020, at 9:11 AM, Andrus Adamchik  wrote:
> 
> Hi,
> 
> We may need to make it more obvious in the API, but SQLSelect only supports 
> JOINT prefetching [1]. It can't support disjoint, as Cayenne has no way of 
> building the right WHERE clause for prefetch queries. It can theoretically 
> support DISJOINT_BY_ID, but IIRC it does not. 
> 
> So let's focus on JOINT... Unlike ObjectSelect that does all the prefetch SQL 
> building for you transparently, SQLSelect can't, so it is your responsibility 
> to include all the columns from the main and related entities in your result 
> set, and also (and this is important) to label all these columns properly, so 
> that Cayenne could figure out which objects they belong to. Here is an 
> example:
> 
> List objects = SQLSelect.query(Artist.class, "SELECT "
>+ "#result('ESTIMATED_PRICE' 'BigDecimal' '' 
> 'paintings.ESTIMATED_PRICE'), "
>+ "#result('PAINTING_TITLE' 'String' '' 'paintings.PAINTING_TITLE'), "
>+ "#result('GALLERY_ID' 'int' '' 'paintings.GALLERY_ID'), "
>+ "#result('PAINTING_ID' 'int' '' 'paintings.PAINTING_ID'), "
>+ "#result('ARTIST_NAME' 'String'), "
>+ "#result('DATE_OF_BIRTH' 'java.util.Date'), "
>+ "#result('t0.ARTIST_ID' 'int' '' 'ARTIST_ID') "
>+ "FROM ARTIST t0, PAINTING t1 "
>+ "WHERE t0.ARTIST_ID = t1.ARTIST_ID")
>.addPrefetch(Artist.PAINTINGS.joint())
>.select(context);
> Here the result includes all the Artist columns (root entity), and all the 
> Painting columns (prefetched entity). Painting columns are labeled in the 
> format "[dbrelationship].[columnName]" (e.g. "paintings.ESTIMATED_PRICE").
> 
> HTH,
> Andrus
> 
> 
> [1] https://cayenne.apache.org/docs/4.1/cayenne-guide/#prefetching-semantics
> 
>> On Jul 22, 2020, at 11:28 PM, Jorge Gonçalves 
>>  wrote:
>> 
>> Hello,
>> 
>> I have to do some complex queries to data base and to do that on I'm writing 
>> them in SQL.
>> 
>> It works great with SQLSelect but when I need to prefetch something ( to 
>> avoid hundreds of queries when showing data in a tableView) it does not work,
>> 
>> from javaDoc it seems that prefetching with SQLSelect is possible but I have 
>> not found any info or example.
>> 
>> for example if i do:
>> 
>>   SelectQuery query = new SelectQuery<>(Servico.class);
>> 
>>query.addPrefetch("table1");
>>query.addPrefetch("table3");
>>query.addPrefetch("table4");
>> 
>>getContext().performQuery(query);
>> 
>> cayenne makes 4 queries and all data is displayed on table.
>> 
>> but if I run:
>> 
>>   SQLSelect query = new SQLSelect<>(Servico.class, "select * from 
>> servico;");
>> 
>>query.addPrefetch("table1", PrefetchTreeNode.UNDEFINED_SEMANTICS);
>>query.addPrefetch("table3", PrefetchTreeNode.UNDEFINED_SEMANTICS);
>>query.addPrefetch("table4", PrefetchTreeNode.UNDEFINED_SEMANTICS);
>> 
>>getContext().performQuery(query);
>> 
>> it makes hundreds of queries when trying to show data on table (like if no 
>> prefetch was made), I've tried to make a join but does not work either.
>> 
> 



Re: SQLSelect and Prefetching (cayenne 4.1)

2020-07-30 Thread Andrus Adamchik
Hi,

We may need to make it more obvious in the API, but SQLSelect only supports 
JOINT prefetching [1]. It can't support disjoint, as Cayenne has no way of 
building the right WHERE clause for prefetch queries. It can theoretically 
support DISJOINT_BY_ID, but IIRC it does not. 

So let's focus on JOINT... Unlike ObjectSelect that does all the prefetch SQL 
building for you transparently, SQLSelect can't, so it is your responsibility 
to include all the columns from the main and related entities in your result 
set, and also (and this is important) to label all these columns properly, so 
that Cayenne could figure out which objects they belong to. Here is an example:

List objects = SQLSelect.query(Artist.class, "SELECT "
+ "#result('ESTIMATED_PRICE' 'BigDecimal' '' 
'paintings.ESTIMATED_PRICE'), "
+ "#result('PAINTING_TITLE' 'String' '' 'paintings.PAINTING_TITLE'), "
+ "#result('GALLERY_ID' 'int' '' 'paintings.GALLERY_ID'), "
+ "#result('PAINTING_ID' 'int' '' 'paintings.PAINTING_ID'), "
+ "#result('ARTIST_NAME' 'String'), "
+ "#result('DATE_OF_BIRTH' 'java.util.Date'), "
+ "#result('t0.ARTIST_ID' 'int' '' 'ARTIST_ID') "
+ "FROM ARTIST t0, PAINTING t1 "
+ "WHERE t0.ARTIST_ID = t1.ARTIST_ID")
.addPrefetch(Artist.PAINTINGS.joint())
.select(context);
Here the result includes all the Artist columns (root entity), and all the 
Painting columns (prefetched entity). Painting columns are labeled in the 
format "[dbrelationship].[columnName]" (e.g. "paintings.ESTIMATED_PRICE").

HTH,
Andrus


[1] https://cayenne.apache.org/docs/4.1/cayenne-guide/#prefetching-semantics

> On Jul 22, 2020, at 11:28 PM, Jorge Gonçalves 
>  wrote:
> 
> Hello,
> 
> I have to do some complex queries to data base and to do that on I'm writing 
> them in SQL.
> 
> It works great with SQLSelect but when I need to prefetch something ( to 
> avoid hundreds of queries when showing data in a tableView) it does not work,
> 
> from javaDoc it seems that prefetching with SQLSelect is possible but I have 
> not found any info or example.
> 
> for example if i do:
> 
>SelectQuery query = new SelectQuery<>(Servico.class);
> 
> query.addPrefetch("table1");
> query.addPrefetch("table3");
> query.addPrefetch("table4");
> 
> getContext().performQuery(query);
> 
> cayenne makes 4 queries and all data is displayed on table.
> 
> but if I run:
> 
>SQLSelect query = new SQLSelect<>(Servico.class, "select * from 
> servico;");
> 
> query.addPrefetch("table1", PrefetchTreeNode.UNDEFINED_SEMANTICS);
> query.addPrefetch("table3", PrefetchTreeNode.UNDEFINED_SEMANTICS);
> query.addPrefetch("table4", PrefetchTreeNode.UNDEFINED_SEMANTICS);
> 
> getContext().performQuery(query);
> 
> it makes hundreds of queries when trying to show data on table (like if no 
> prefetch was made), I've tried to make a join but does not work either.
> 



Re: springboot and cayenne

2020-07-29 Thread Andrus Adamchik
Hi Tony,

I haven't used Cayenne with SpringBoot for obvious reasons, but it should be no 
different from using it in any other env:

* Create a ServerRuntime singleton
* Get ObjectContext from it when you need it.

Andrus

> On Jul 29, 2020, at 5:33 PM, Tony Giaccone  wrote:
> 
> I see there's a cayenne spring boot starter project, has anyone used this?
> What's the state of using Cayenne with springboot?
> 
> 
> 
> Tony Giaccone



Re: [ANN] Cayenne 4.1 goes final

2020-07-27 Thread Andrus Adamchik
Here it is:

https://search.maven.org/artifact/org.apache.cayenne/cayenne-server/4.1/jar


> On Jul 27, 2020, at 4:21 PM, Andrew Willerding  
> wrote:
> 
> This is great news!  Hmmm.  I can't seem to find it on Maven central yet.
> 
> On 2020-07-24 1:52 a.m., Andrus Adamchik wrote:
>> Very excited to announce the final / GA release of Apache Cayenne 4.1! It is 
>> available on Maven central and as a download on cayenne.apache.org.
>> 
>> For the 4.0 users this is an exciting upgrade, offering an immediate and 
>> tangible performance boost (field-based data objects) and a new easy 
>> automated ORM workflow (modeler-based DB import). See this short video [1] 
>> for details. And here is a website announcement [2].
>> 
>> It's been "only" 2 years since 4.0 went final. Our GA cycles are shortening, 
>> and will hopefully shorten even further with 4.2.
>> 
>> Thanks to everyone who made it happen - developers, users, testers. We have 
>> an amazing community that sustained this project over the years! Looking 
>> forward to the new things that are happening in 4.2, and the plans beyond 
>> that.
>> 
>> Andrus
>> 
>> 
>> [1] https://www.youtube.com/watch?v=GW3l7bAJgKg
>> [2] https://cayenne.apache.org/2020/07/cayenne-41-final-released/
>> [3] Bug fixes since 4.1.RC2:
>> 
>> CAY-2642 EhCache memory leak due to misconfiguration
>> CAY-2643 ObjectSelect.prefetch(name, semantics) method creates a phantom node
>> CAY-2646 Wrong target path selection logic in cgen config
>> CAY-2647 Modeler: project upgrade from 4.0.B2 to 4.1.RC2 failure
>> CAY-2653 No methods for queries with qualifier parameters generated
>> CAY-2654 Exception in dbimport when relationships should be imported, but no 
>> explicit configuration exists



[ANN] Cayenne 4.1 goes final

2020-07-23 Thread Andrus Adamchik
Very excited to announce the final / GA release of Apache Cayenne 4.1! It is 
available on Maven central and as a download on cayenne.apache.org.

For the 4.0 users this is an exciting upgrade, offering an immediate and 
tangible performance boost (field-based data objects) and a new easy automated 
ORM workflow (modeler-based DB import). See this short video [1] for details. 
And here is a website announcement [2]. 

It's been "only" 2 years since 4.0 went final. Our GA cycles are shortening, 
and will hopefully shorten even further with 4.2.

Thanks to everyone who made it happen - developers, users, testers. We have an 
amazing community that sustained this project over the years! Looking forward 
to the new things that are happening in 4.2, and the plans beyond that.

Andrus


[1] https://www.youtube.com/watch?v=GW3l7bAJgKg
[2] https://cayenne.apache.org/2020/07/cayenne-41-final-released/
[3] Bug fixes since 4.1.RC2:

CAY-2642 EhCache memory leak due to misconfiguration
CAY-2643 ObjectSelect.prefetch(name, semantics) method creates a phantom node
CAY-2646 Wrong target path selection logic in cgen config
CAY-2647 Modeler: project upgrade from 4.0.B2 to 4.1.RC2 failure
CAY-2653 No methods for queries with qualifier parameters generated
CAY-2654 Exception in dbimport when relationships should be imported, but no 
explicit configuration exists

Re: [OT] I demand change

2020-07-13 Thread Andrus Adamchik
Haha... I think "download Cayenne" is the only search that doesn't offer me a 
Porsche picture :)

Andrus

> On Jul 13, 2020, at 12:16 PM, Hugi Thordarson  wrote:
> 
> That's it. I'm sick and tired of Porsche polluting my search results.
> 
> http://chng.it/ySkvT5DK7z 
> 
> Cheers,
> - hugi



Re: Automatically deleting objects from a to-many relationship when removed?

2020-07-13 Thread Andrus Adamchik
Hi Faizel,

The answer is no. Unsetting a relationship will never delete its target object. 
So you'll need to do it explicitly. 

There are "delete rules" for relationships, but those require the source object 
to be deleted to trigger nullify/cascade/deny action. So that's different.

Andrus


> On Jul 13, 2020, at 12:35 AM, Faizel Dakri  wrote:
> 
> Is there a facility in Cayenne to automatically delete an object when it is 
> removed from an “owning” object’s to-many relationship (and not added to 
> another owning object)? 
> 
> I’m migrating a project from EOF to Cayenne. In the EOF world, there was the 
> concept of a relationship owning its destination, meaning that removing a 
> destination object from that relationship in the source object would also 
> cause that destination object to be deleted from the database on commit 
> without having to explicitly call deleteObject() on it (provided it wasn’t 
> subsequently added to another source object). This automatic deletion would 
> happen during saveChanges() on the editing context.
> 
> Maybe it’s just too obvious and I haven’t been able to recognize it, but I 
> have not been able to find anything similar in Cayenne. Is there such a 
> feature? 
> 
> Thanks,
> 
> F
> 
> -- 
> Faizel Dakri
> 
> 



Re: Apache Cayenne ROP - Error Connect

2020-07-04 Thread Andrus Adamchik
Hi Dayvyd,

Which version of Cayenne is this and how is the server setup?

Andrus

> On Jul 2, 2020, at 12:20 AM, Dayvyd .  wrote:
> 
> Hi,
> 
> Has anyone encountered this error when running Main.java using BASIC
> authentication? Without authentication it works normally!
> 
> Error: org.apache.cayenne.rop.HttpClientConnection - unknown code for
> readObject at 0x3c (<); nested exception is:
> 
> ---
> public class Main {
> 
> public static void main(String[] args) {
> 
> Map properties = new HashMap<>();
> properties.put(ClientConstants.ROP_SERVICE_URL_PROPERTY, "
> http://localhost:8080/saudeplusserver;);
> properties.put(ClientConstants.ROP_SERVICE_USERNAME_PROPERTY, "saudeplus");
> properties.put(ClientConstants.ROP_SERVICE_PASSWORD_PROPERTY, "dna1614");
> properties.put(ClientConstants.ROP_SERVICE_REALM_PROPERTY, "Cayenne Realm");
> 
> ClientRuntime runtime = ClientRuntime.builder()
>.properties(properties)
>.build();
> ObjectContext context = runtime.newContext();
> 
> inserirCardapio(context);
> runtime.shutdown();
> }
> ---
> [main] INFO org.eclipse.jetty.util.log - Logging initialized @1527ms to
> org.eclipse.jetty.util.log.Slf4jLog
> [main] INFO org.apache.cayenne.rop.http.JettyHttpROPConnector - Adding
> authentication
> User: saudeplus
> Realm: Cayenne Realm
> [main] INFO org.apache.cayenne.rop.http.JettyHttpROPConnector - Connecting
> to [saudeplus:***@http://localhost:8080/saudeplusserver] - dedicated
> session.
> [main] INFO org.apache.cayenne.rop.HttpClientConnection - unknown code for
> readObject at 0x3c (<); nested exception is:
> com.caucho.hessian.io.HessianProtocolException: unknown code for readObject
> at 0x3c (<)
> java.rmi.RemoteException: unknown code for readObject at 0x3c (<); nested
> exception is:
> com.caucho.hessian.io.HessianProtocolException: unknown code for readObject
> at 0x3c (<)
> at
> org.apache.cayenne.rop.ProxyRemoteService.establishSession(ProxyRemoteService.java:46)
> at
> org.apache.cayenne.rop.HttpClientConnection.connect(HttpClientConnection.java:93)
> at
> org.apache.cayenne.rop.HttpClientConnection.getServerEventBridge(HttpClientConnection.java:71)
> at
> org.apache.cayenne.remote.ClientChannel.setupRemoteChannelListener(ClientChannel.java:279)
> at org.apache.cayenne.remote.ClientChannel.(ClientChannel.java:77)
> at
> org.apache.cayenne.configuration.rop.client.ClientChannelProvider.get(ClientChannelProvider.java:45)
> at
> org.apache.cayenne.configuration.rop.client.ClientChannelProvider.get(ClientChannelProvider.java:30)
> at
> org.apache.cayenne.di.spi.CustomProvidersProvider.get(CustomProvidersProvider.java:39)
> at
> org.apache.cayenne.di.spi.FieldInjectingProvider.get(FieldInjectingProvider.java:43)
> at
> org.apache.cayenne.di.spi.DefaultScopeProvider.get(DefaultScopeProvider.java:50)
> at
> org.apache.cayenne.di.spi.DefaultInjector.getInstance(DefaultInjector.java:139)
> at
> org.apache.cayenne.di.spi.FieldInjectingProvider.value(FieldInjectingProvider.java:103)
> at
> org.apache.cayenne.di.spi.FieldInjectingProvider.injectMember(FieldInjectingProvider.java:68)
> at
> org.apache.cayenne.di.spi.FieldInjectingProvider.injectMembers(FieldInjectingProvider.java:59)
> at
> org.apache.cayenne.di.spi.FieldInjectingProvider.get(FieldInjectingProvider.java:44)
> at
> org.apache.cayenne.di.spi.DefaultScopeProvider.get(DefaultScopeProvider.java:50)
> at
> org.apache.cayenne.di.spi.DefaultInjector.getInstance(DefaultInjector.java:134)
> at
> org.apache.cayenne.configuration.CayenneRuntime.newContext(CayenneRuntime.java:124)
> at br.com.saudeplus.model.client.Main.main(Main.java:25)
> Caused by: com.caucho.hessian.io.HessianProtocolException: unknown code for
> readObject at 0x3c (<)
> at com.caucho.hessian.io.HessianInput.error(HessianInput.java:1697)
> at com.caucho.hessian.io.HessianInput.readObject(HessianInput.java:1177)
> at
> org.apache.cayenne.rop.HessianROPSerializationService.deserialize(HessianROPSerializationService.java:67)
> at
> org.apache.cayenne.rop.ProxyRemoteService.establishSession(ProxyRemoteService.java:44)
> ... 18 more
> Exception in thread "main" org.apache.cayenne.CayenneRuntimeException:
> [v.4.2.M1 Apr 15 2020 09:23:45] unknown code for readObject at 0x3c (<);
> nested exception is:
> com.caucho.hessian.io.HessianProtocolException: unknown code for readObject
> at 0x3c (<)
> at
> org.apache.cayenne.rop.HttpClientConnection.connect(HttpClientConnection.java:97)
> at
> 

Re: problem with ExtendedType in Cayenne 4.2

2020-06-29 Thread Andrus Adamchik
Could you send a Cayenne query example where this happens? 

Andrus


> On Jun 29, 2020, at 12:20 PM, Andrea Biasillo  wrote:
> 
> Hi Andrus!
> 
> I think our DataloyOracleAdapter  is in use, at startup in the Wildfly log we 
> get this:
> 
> [org.apache.cayenne.log.JdbcEventLogger] (ServerService Thread Pool -- 87) 
> Detected and installed adapter: com.dataloy.platform.DataloyOracleAdapter
> 
> Also another thing is the the method setJdbcObject is invoked, but not 
> materializeObject
> 
> Regards,
> Andrea
> 
> On 2020/06/29 08:35:05, Andrus Adamchik  wrote: 
>> Here is another random idea - could you verify that your adapter is in use? 
>> 
>> Andrus
>> 
>>> On Jun 29, 2020, at 11:27 AM, Andrea Biasillo  wrote:
>>> 
>>> Hi Andrus and thank you!
>>> 
>>> I tried to override configureExtendedTypes but still the method 
>>> materializeObject is not inoked.
>>> 
>>> Regards,
>>> Andrea
>>> 
>>> On 2020/06/29 08:19:15, Andrus Adamchik  wrote: 
>>>> Hi Andrea,
>>>> 
>>>> "materializeObject" method should still be called of course. When 
>>>> registering custom types within the adapter, I'd usually override 
>>>> "configureExtendedTypes":
>>>> 
>>>> @Override
>>>> protected void configureExtendedTypes(ExtendedTypeMap map) {
>>>>   super.configureExtendedTypes(map);
>>>>   map.registerType(new SourceIdType());
>>>> }
>>>> 
>>>> I suspect it might make a difference, considering somewhat complicated 
>>>> type override rules in the adapter.
>>>> 
>>>> Andrus
>>>> 
>>>> 
>>>>> On Jun 29, 2020, at 11:04 AM, Andrea Biasillo  wrote:
>>>>> 
>>>>> Hi!
>>>>> 
>>>>> We are migrating from 4.0.2 to 4.2. We have a class that implements 
>>>>> ExtendedType. 
>>>>> In 4.0.2 the method:
>>>>> 
>>>>> public SourceId materializeObject(ResultSet rs, int index, int type) 
>>>>> throws Exception 
>>>>> 
>>>>> was invoked, but not in 4.2.
>>>>> 
>>>>> We register our class in this way:
>>>>> 
>>>>> public class DataloyOracleAdapter extends OracleAdapter {
>>>>> 
>>>>>   public DataloyOracleAdapter(@Inject RuntimeProperties 
>>>>> runtimeProperties, 
>>>>>   @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) 
>>>>> List defaultExtendedTypes,
>>>>>   @Inject(Constants.SERVER_USER_TYPES_LIST) 
>>>>> List userExtendedTypes, 
>>>>>   @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) 
>>>>> List extendedTypeFactories,
>>>>>   @Inject(Constants.SERVER_RESOURCE_LOCATOR) 
>>>>> ResourceLocator resourceLocator, 
>>>>>   @Inject ValueObjectTypeRegistry 
>>>>> valueObjectTypeRegistry) {
>>>>>   super(runtimeProperties, defaultExtendedTypes, 
>>>>> userExtendedTypes, extendedTypeFactories, resourceLocator,
>>>>>   valueObjectTypeRegistry);
>>>>>   setSupportsGeneratedKeys(false);
>>>>>   //super.setPkGenerator(new DataloyPkGenerator());
>>>>>   
>>>>>   setSupportsBatchUpdates(false);
>>>>>   this.extendedTypes.registerType(new SourceIdType());
>>>>>   }
>>>>> 
>>>>> 
>>>>> }
>>>>> 
>>>>> 
>>>>> What is wrong? What should be changed?
>>>>> 
>>>>> Many regards,
>>>>> Andrea
>>>> 
>>>> 
>> 
>> 



Re: problem with ExtendedType in Cayenne 4.2

2020-06-29 Thread Andrus Adamchik
Here is another random idea - could you verify that your adapter is in use? 

Andrus

> On Jun 29, 2020, at 11:27 AM, Andrea Biasillo  wrote:
> 
> Hi Andrus and thank you!
> 
> I tried to override configureExtendedTypes but still the method 
> materializeObject is not inoked.
> 
> Regards,
> Andrea
> 
> On 2020/06/29 08:19:15, Andrus Adamchik  wrote: 
>> Hi Andrea,
>> 
>> "materializeObject" method should still be called of course. When 
>> registering custom types within the adapter, I'd usually override 
>> "configureExtendedTypes":
>> 
>> @Override
>> protected void configureExtendedTypes(ExtendedTypeMap map) {
>>super.configureExtendedTypes(map);
>>map.registerType(new SourceIdType());
>> }
>> 
>> I suspect it might make a difference, considering somewhat complicated type 
>> override rules in the adapter.
>> 
>> Andrus
>> 
>> 
>>> On Jun 29, 2020, at 11:04 AM, Andrea Biasillo  wrote:
>>> 
>>> Hi!
>>> 
>>> We are migrating from 4.0.2 to 4.2. We have a class that implements 
>>> ExtendedType. 
>>> In 4.0.2 the method:
>>> 
>>> public SourceId materializeObject(ResultSet rs, int index, int type) throws 
>>> Exception 
>>> 
>>> was invoked, but not in 4.2.
>>> 
>>> We register our class in this way:
>>> 
>>> public class DataloyOracleAdapter extends OracleAdapter {
>>> 
>>> public DataloyOracleAdapter(@Inject RuntimeProperties 
>>> runtimeProperties, 
>>> @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) 
>>> List defaultExtendedTypes,
>>> @Inject(Constants.SERVER_USER_TYPES_LIST) 
>>> List userExtendedTypes, 
>>> @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) 
>>> List extendedTypeFactories,
>>> @Inject(Constants.SERVER_RESOURCE_LOCATOR) 
>>> ResourceLocator resourceLocator, 
>>> @Inject ValueObjectTypeRegistry 
>>> valueObjectTypeRegistry) {
>>> super(runtimeProperties, defaultExtendedTypes, 
>>> userExtendedTypes, extendedTypeFactories, resourceLocator,
>>> valueObjectTypeRegistry);
>>> setSupportsGeneratedKeys(false);
>>> //super.setPkGenerator(new DataloyPkGenerator());
>>> 
>>> setSupportsBatchUpdates(false);
>>> this.extendedTypes.registerType(new SourceIdType());
>>> }
>>> 
>>> 
>>> }
>>> 
>>> 
>>> What is wrong? What should be changed?
>>> 
>>> Many regards,
>>> Andrea
>> 
>> 



Re: problem with ExtendedType in Cayenne 4.2

2020-06-29 Thread Andrus Adamchik
Hi Andrea,

"materializeObject" method should still be called of course. When registering 
custom types within the adapter, I'd usually override "configureExtendedTypes":

@Override
protected void configureExtendedTypes(ExtendedTypeMap map) {
super.configureExtendedTypes(map);
map.registerType(new SourceIdType());
}

I suspect it might make a difference, considering somewhat complicated type 
override rules in the adapter.

Andrus


> On Jun 29, 2020, at 11:04 AM, Andrea Biasillo  wrote:
> 
> Hi!
> 
> We are migrating from 4.0.2 to 4.2. We have a class that implements 
> ExtendedType. 
> In 4.0.2 the method:
> 
> public SourceId materializeObject(ResultSet rs, int index, int type) throws 
> Exception 
> 
> was invoked, but not in 4.2.
> 
> We register our class in this way:
> 
> public class DataloyOracleAdapter extends OracleAdapter {
> 
>   public DataloyOracleAdapter(@Inject RuntimeProperties 
> runtimeProperties, 
>   @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) 
> List defaultExtendedTypes,
>   @Inject(Constants.SERVER_USER_TYPES_LIST) 
> List userExtendedTypes, 
>   @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) 
> List extendedTypeFactories,
>   @Inject(Constants.SERVER_RESOURCE_LOCATOR) 
> ResourceLocator resourceLocator, 
>   @Inject ValueObjectTypeRegistry 
> valueObjectTypeRegistry) {
>   super(runtimeProperties, defaultExtendedTypes, 
> userExtendedTypes, extendedTypeFactories, resourceLocator,
>   valueObjectTypeRegistry);
>   setSupportsGeneratedKeys(false);
>   //super.setPkGenerator(new DataloyPkGenerator());
>   
>   setSupportsBatchUpdates(false);
>   this.extendedTypes.registerType(new SourceIdType());
>   }
> 
> 
> }
> 
> 
> What is wrong? What should be changed?
> 
> Many regards,
> Andrea



  1   2   3   4   5   6   7   8   9   10   >