Hi Sergey,
I have made some further changes to my POC at github, including more classes from CXF and adding a specific test case in attempting to replicate your original issue.

The additional test case is

https://github.com/ilgrosso/cxf-openjpa-poc/blob/master/src/test/java/net/tirasa/ilgrosso/cxfopenjpapoc/entity/BaseTest.java#L75

where, as you can see, I am removing first c1 then c2, with no issues.
I am not sure, though, if the various UserSubject instances involved are created by the test case in the way which resemble the real OAuth 2 interaction or not.

Also, consider that I had to change the last lines of addClient (now provider.setClient returns the entity after merge).

Please note that I had to rework a bit with cascades and merges, maybe it is necessary to review your original merge order strategy.

Finally, I have tried to report the main entities involved in the following diagram:

https://drive.google.com/file/d/0B54ZHVmTeFXTeXBTX2plQlVVMjQ/view?usp=sharing

AFAICT, the relationships between BearerAccessToken and UserSubject are quite involved, especially when it comes to CASCADE, which might trigger some unwanted interactions.

HTH
Regards.

On 27/04/2016 18:25, Sergey Beryozkin wrote:
I haven't made any progress today so I'll do something else for the next few days to make me feel I can still do something and then return to this issue :-)

Thanks, Sergey
On 27/04/16 10:39, Sergey Beryozkin wrote:
Hi Francesco

many thanks, I'm sorry for involving you into this project :-), but it
is much appreciated you trying to help. I also hope my query is not off
topic for this list - as there might be some OpenJPA issue hiding there
(though the high chance is it is the way I misconfigured JPA mappings
that causes it).

I've experimented for few days by trying to emulate this issue locally
in CXF JPAOAuthDataProviderTest/JPACodeDataProviderTest, but could not.
Perhaps your project will make it easier as it is closer to the real
deployment case.

FYI, this test fails:

https://github.com/apache/cxf-fediz/blob/master/systests/oidc/src/test/java/org/apache/cxf/fediz/systests/oidc/OIDCTest.java#L412


This test preloads a packaged Fediz OIDC war and sends actions to it
remotely.

Disabling all other tests and running only this test does the following
(which is what I described earlier) :
- create client1 and client2, get a code for Client 2 and exchange for a
token (i.e BearerAccessToken with a link to Client2 is saved), finally
start deleting clients starting from Client 1 and it fails
(DELETE triggers an insert)

This is reproducible against the embedded Tomcat and a standalone Tomcat
though when I try to repeat the same sequence manually it is all OK.

So I will spend some time on trying to narrow it down further. and
update you and what I have found.

Many thanks for trying to help and sorry in advance for the noise (when
I report later it proved to be the misconfiguration :-))

Sergey


On 27/04/16 08:24, Francesco Chicchiriccò wrote:
Hi Sergey,
I have created a (kind of) nailed-down version of your application at

https://github.com/ilgrosso/cxf-openjpa-poc

Essentially, I have grabbed few classes from CXF's
cxf-rt-rs-security-oauth2 and injected in my own OpenJPA template
project: as you can see, this imply using Spring and build-time
enhancement.

When you run 'mvn -Psqlgen' on it, you will get the full SQL schema
under target/database.sql

When you run 'mvn clean test' on it, you will get

https://github.com/ilgrosso/cxf-openjpa-poc/blob/master/src/test/java/net/tirasa/ilgrosso/cxfopenjpapoc/entity/BaseTest.java



executed, where I have grabbed some methods from CXF's
JPAOAuthDataProviderTest

As you can see, at the moment the only test case available works fine:
please add another one which shows the problem you are experiencing,
thanks.

Regards.

On 26/04/2016 17:33, Sergey Beryozkin wrote:
Hi Francesco, thanks, so this is what I get.

I see Client references being removed first from various tables (Client
has @ElementCollection Lists of String for properties like
allowedGrantTypes, etc):

31896  testUnitOpenJPA  TRACE  [http-bio-50025-exec-5]
openjpa.jdbc.SQL - <t 593160440, conn 570232632> executing prepstmnt
969065640
DELETE FROM Client_allowedGrantTypes WHERE CLIENT_CLIENTID = ?
[params=?]
......
omitting few ones...
31897  testUnitOpenJPA  TRACE  [http-bio-50025-exec-5]
openjpa.jdbc.SQL - <t 593160440, conn 570232632> executing prepstmnt
583592238
DELETE FROM Client_registeredAudiences WHERE CLIENT_CLIENTID = ?
[params=?]

*And Finally* DELETE from the Client table itself, which triggers that
INSERT:


31898  testUnitOpenJPA  TRACE  [http-bio-50025-exec-5]
openjpa.jdbc.SQL - <t 593160440, conn 570232632> executing prepstmnt
2036246172
DELETE FROM Client
    WHERE clientId = ?
[params=?]
31898  testUnitOpenJPA  TRACE  [http-bio-50025-exec-5]
openjpa.jdbc.SQL - <t 593160440, conn 570232632> executing prepstmnt
890014212
INSERT INTO BearerAccessToken_parameters (BEARERACCESSTOKEN_TOKENKEY,
        propName, value)
    VALUES (?, ?, ?)
[params=?, ?, ?]

I can't explain in, as I said I can only think that the fact there's a
Many to One relationship from AccessToken to Client causes an
auto-refresh of BearerAccessToken & related tables...

I will experiment with moving few properties around...

Cheers, Sergey


On 26/04/16 12:22, Francesco Chicchiriccò wrote:
On 26/04/2016 11:44, Sergey Beryozkin wrote:
Hi All

This is my first post to the list, I've tried to solve the issue
myself by checking StackOverflow, etc. I thought I'd give it a try at
OpenJPA users list, given that I do work with OpenJPA 2.4.0.

I have the following class hierarchy (listing the most relevant
details):

@Entity
public class Client {
   private String clientId;
}


@Entity
public class BearerAccessToken extends ServerAccessToken {
}

@MappedSuperclass
public abstract class ServerAccessToken extends AccessToken {

@ManyToOne
private Client client;
}

@MappedSuperclass
public abstract class AccessToken {

@Id
String tokenKey;

@ElementCollection
@MapKeyColumn(name="propName")
private Map<String, String> parameters = new LinkedHashMap<String,
String>();
}


Now, after initializing the DB as follows:

- Create Client instance (ex, "Client1"), add it to DB:
  Client c1 = new Client("Client1"); // and save
- Create another Client instance (ex, "Client2"), add it to DB:
  Client c2 = new Client("Client2"); // and save
- add a new BearerAccessToken associated with Client2 to DB:
  BearerAccessToken at = new BearerAccessToken();
  at.setClient(c2); // and save

(Note no tokens are associated with Client1)

the following sequence works OK:

1. delete Client2 (c2)
2. delete Client1 (c1)

This is OK, but if I start from deleting Client1 (the one with no
tokens) I immediately see:

Caused by: <openjpa-2.4.0-r422266:1674604 fatal general error>
org.apache.openjpa.persistence.PersistenceException: data exception:
string data, right truncation;  table: BEARERACCESSTOKEN_PARAMETERS
column: VALUE {prepstmnt 453026232 INSERT INTO
BearerAccessToken_parameters (BEARERACCESSTOKEN_TOKENKEY, propName,
value) VALUES (?, ?, ?)} [code=3401, state=22001]
    at
org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:5001).




I honestly do not know where to start looking. I've seen plenty of
StackOverflow messages about the "string data, right truncation", in
this case AccessToken.parameters map is never touched by my code, it
is empty. And the most confusing thing why this is even happening when
I delete a Client with no tokens associated with it.

I suspect when the Client is deleted, given a Many to One relationship
from ServerAccessToken to Client (but no OneToMany from Client to
ServerAccessToken), the mapping table gets refreshed in order to find any tokens which may be linking to Client being deleted). But that is
as far as I can get.

Can someone please suggest why the above might be occurring, is it a
mapping issue, or possibly OpenJPA issue ?

Hi Sergey,
I'd start by trying to understand exactly which SQL statement generates
the error above, so adding

<property name="openjpa.Log" value="SQL=TRACE"/>
<property name="openjpa.ConnectionFactoryProperties"
     value="PrettyPrint=true, PrettyPrintLineLength=72"/>

to your persistence.xml and trying again.

HTH
Regards.

--
Francesco Chicchiriccò

Tirasa - Open Source Excellence
http://www.tirasa.net/

Involved at The Apache Software Foundation:
member, Syncope PMC chair, Cocoon PMC, Olingo PMC, CXF committer
http://home.apache.org/~ilgrosso/


Reply via email to