使用带有JdoCredentialStore和DataNucleus的GoogleAuthorizationCodeFlow复制条目异常

时间:2012-07-10 19:43:39

标签: mysql jdo datanucleus google-api-java-client duplicates

我遇到了GoogleAuthorizationCodeFlow( Java )的问题。我正在尝试使用Google的#Web; OAuth 2.0 for Web Server Applications"为我的网络项目构建Google日历连接。因此,您可以使用Google的Java API库。

我使用Google的AuthorizationCallbackServlet来接收访问和刷新令牌。

GoogleAuthorizationCodeFlow使用GoogleAuthorizationCodeFlow及其JdoCredentialStore保留创建的凭据。作为JDO实现,我正在使用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();
}

无状态Bean中的用法:

public List<CalendarListEntry> getCalendarList() {  
    Credential credential = null;


    AuthorizationCodeFlow authCodeFlow = Constants.getNewAuthorizationCodeFlow();

    try {
        credential = authCodeFlow.loadCredential("USERID");
    } catch (Exception e) {
    //...
}

一切正常(我能够列出我的日历条目,Credential在我的MySQL数据库中保留)除了时间来使用持久刷新令牌(GoogleAuthorizationCodeFlow所做的)来引用访问令牌。

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)

总结一下,我能够

  1. 使用accessToken和refreshToken
  2. 接收并保留凭据
  3. 列出日历条目(只要访问令牌的时间尚未过期)
  4. 我无法使用GoogleAuthorizationCodeFlow刷新我的访问令牌,而无法获得&#34; javax.jdo.JDODataStoreException:重复条目&#39; USERID & #39;关键&#39; PRIMARY&#39;&#34;异常。

    我做错了什么?

    非常感谢你的帮助!

1 个答案:

答案 0 :(得分:0)

通过“刷新”,你可能意味着“坚持”,因为这就是你正在做的事情。并且它持续存在与现有存在相同的“id”。如果您打算更新它,那么您将检索并更新它并在数据存储区中更新它。如果这是一些谷歌lib在幕后做持久性,那么问他们在他们的API中哪里可能是“更新”调用。