问题
I have a problem with the GoogleAuthorizationCodeFlow (Java). I am trying to build a Google Calender connection for my web project using Google's "OAuth 2.0 for Web Server Applications". Therefore you are able to use Google's Java api libraries.
I use Google's AuthorizationCallbackServlet to recieve an access and refresh token.
GoogleAuthorizationCodeFlow persists the created Credential with GoogleAuthorizationCodeFlow and their JdoCredentialStore. As a JDO implementation I am using DataNucleus.
static PersistenceManagerFactory pmf;
static{
Properties properties = new Properties();
properties.setProperty("javax.jdo.PersistenceManagerFactoryClass",
"org.datanucleus.api.jdo.JDOPersistenceManagerFactory");
properties.setProperty("javax.jdo.option.ConnectionDriverName","com.mysql.jdbc.Driver");
properties.setProperty("javax.jdo.option.ConnectionURL","jdbc:mysql://localhost:3306/rssparsetest");
properties.setProperty("javax.jdo.option.ConnectionUserName","root");
properties.setProperty("javax.jdo.option.ConnectionPassword","root");
pmf = JDOHelper.getPersistenceManagerFactory(properties);
}
public static CredentialStore JDO_CREDENTIAL_STORE = new JdoCredentialStore(pmf);
public static AuthorizationCodeFlow AUTHORIZATION_CODE_FLOW = getNewAuthorizationCodeFlow();
public static AuthorizationCodeFlow getNewAuthorizationCodeFlow(){
return new GoogleAuthorizationCodeFlow.Builder(Constants.HTTP_TRANSPORT, Constants.JSON_FACTORY,
Constants.CLIENT_ID, Constants.CLIENT_SECRET,
Collections.singleton(CalendarScopes.CALENDAR)).setCredentialStore(Constants.JDO_CREDENTIAL_STORE).setAccessType("offline")
.build();
}
Usage in stateless Bean:
public List<CalendarListEntry> getCalendarList() {
Credential credential = null;
AuthorizationCodeFlow authCodeFlow = Constants.getNewAuthorizationCodeFlow();
try {
credential = authCodeFlow.loadCredential("USERID");
} catch (Exception e) {
//...
}
Everything is working fine (I am able to list my calendar entries, Credential is persisted in my MySQL database) except time comes to referesh the access token with the persisted refresh token (what GoogleAuthorizationCodeFlow does).
Caused by: javax.jdo.JDODataStoreException: Duplicate entry 'USERID' for key 'PRIMARY'
NestedThrowables:
java.sql.BatchUpdateException: Duplicate entry 'USERID' for key 'PRIMARY'
at org.datanucleus.api.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:421)
at org.datanucleus.api.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:735)
at org.datanucleus.api.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.java:755)
at com.google.api.client.extensions.jdo.auth.oauth2.JdoCredentialStore.store(JdoCredentialStore.java:47)
To sum it up, I am able to
- Receive and persist the Credential with accessToken and refreshToken
- List calendar entries (as long as access token's time has not expired)
I am not able to refresh my access token with the GoogleAuthorizationCodeFlow without obtaining an "javax.jdo.JDODataStoreException: Duplicate entry 'USERID' for key 'PRIMARY'" exception.
What am I doing wrong?
Thank you very much for your help!
回答1:
By "refresh" you presumably mean "persist", since that is what you're doing. And it's persisting one with the same "id" as an existent one. If you meant to update it then you retrieve it and update it and it gets updated in datastore. If this is some Google lib doing the persistence behind the scenes then ask them where in their API is an "update" call possible.
来源:https://stackoverflow.com/questions/11420727/duplicate-entry-exception-using-googleauthorizationcodeflow-with-jdocredentialst