Исключение повторяющейся записи с использованием GoogleAuthorizationCodeFlow с JdoCredentialStore и DataNucleus

У меня проблема с GoogleAuthorizationCodeFlow (Java). Я пытаюсь создать соединение Google Calender для своего веб-проекта, используя Google «OAuth 2.0 для приложений веб-сервера». Поэтому вы можете использовать API-библиотеки Java от Google.

Я использую AuthorizationCallbackServlet Google для получения токена доступа и обновления.

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) {
    //...
}

Все работает нормально (я могу перечислить свои записи календаря, учетные данные сохраняются в моей базе данных 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. Список записей календаря (пока время токена доступа не истекло)

Я не могу обновить свой токен доступа с помощью GoogleAuthorizationCodeFlow без получения исключения "javax.jdo.JDODataStoreException: повторяющаяся запись "USERID" для ключа "PRIMARY"".

Что я делаю не так?

Большое спасибо за Вашу помощь!


person user1515786    schedule 10.07.2012    source источник


Ответы (1)


Под «обновлять» вы, вероятно, подразумеваете «сохранение», поскольку именно это вы и делаете. И он сохраняется с тем же «id», что и существующий. Если вы хотели обновить его, вы извлекаете его и обновляете, и он обновляется в хранилище данных. Если это какая-то библиотека Google, выполняющая постоянство за кулисами, спросите их, где в их API возможен вызов «обновления».

person DataNucleus    schedule 11.07.2012
comment
Я пометил его с помощью DataNucleus, потому что подумал, что может быть установлен тег, чтобы избежать этого исключения. Да GoogleAuthorizationCodeFlow сохраняет объект Credential после обновления его токена доступа. - person user1515786; 11.07.2012