2014-03-07 3 views
1

코드를 Java7 및 최신 Datanucleus App Engine 플러그인으로 이동하는 중에 주문 문제가 발생했습니다.Google App Engine에서 JDO로 정의 된 컬렉션에서 임의 순서를 유지합니다.

나는 사용자가 정의한 특정 순서를 유지해야하는 일부 자식을 소유 한 조상 클래스가 있습니다. 그래서 @Otension없이 @Order annotion을 사용했습니다. 이전 JDO 버전에서는 모든 것이 불리하게 적용되어 이제이 _INTEGER_IDX 속성을 찾지 못해 단위 테스트가 실패합니다.

신선한 예제로 시작하기 위해이 설명서 Owned one-to-many relationship에 이어 간단한 테스트 프로젝트를 만들었지 만 여전히 작동하지 않습니다. GitHub-project.

@PersistenceCapable(identityType = IdentityType.APPLICATION) 
public class Book { 
    @PrimaryKey 
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
    @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true") 
    private String key = null; 

    @Persistent 
    private String title = null; 

    @Persistent(mappedBy="book") 
    @Order 
    private List<Chapter> chapters = null; 

..와 .. 여기

@PersistenceCapable(identityType = IdentityType.APPLICATION) 
public class Chapter { 
    @PrimaryKey 
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
    @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true") 
    private String key = null; 

    @Persistent 
    private String name = null; 

    @Persistent 
    private Book book = null; 

..와 실패 단위 테스트입니다 :

여기
@Test 
public void testJdoDependingEntities() throws EntityNotFoundException { 
    PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory("transactions-optional"); 

    PersistenceManager pm = pmf.getPersistenceManager(); 

    Book bookJdo = null; 

    try { 
     pm.currentTransaction().begin(); 

     bookJdo = new Book("myTitle"); 
     Chapter cpt1 = new Chapter("myname1"); 
     Chapter cpt2 = new Chapter("myname2"); 
     Chapter cpt3 = new Chapter("myname3"); 
     Chapter cpt4 = new Chapter("myname4"); 
     Chapter cpt5 = new Chapter("myname5"); 
     Chapter cpt6 = new Chapter("myname6"); 

     bookJdo.getChapters().add(cpt1); 
     cpt1.setBook(bookJdo); 
     bookJdo.getChapters().add(cpt2); 
     cpt2.setBook(bookJdo); 
     bookJdo.getChapters().add(cpt3); 
     cpt3.setBook(bookJdo); 
     bookJdo.getChapters().add(cpt4); 
     cpt4.setBook(bookJdo); 
     bookJdo.getChapters().add(cpt5); 
     cpt5.setBook(bookJdo); 
     bookJdo.getChapters().add(cpt6); 
     cpt6.setBook(bookJdo); 

     pm.makePersistent(bookJdo); 

     pm.currentTransaction().commit(); 
    } catch(Exception e) { 
     e.printStackTrace(); 
    } 
    finally { 
     if(pm.currentTransaction().isActive()) { 
      pm.currentTransaction().rollback(); 
     } 
     pm.close(); 
    } 

    Entity book = datastore.get(KeyFactory.stringToKey(bookJdo.getKey())); 
    assertEquals("myTitle", book.getProperty("title")); 

    Query query = new com.google.appengine.api.datastore.Query(
      "Chapter", 
      KeyFactory.stringToKey(bookJdo.getKey())); 
    FetchOptions options = FetchOptions.Builder.withDefaults(); 

    QueryResultList<Entity> resultEntity = datastore.prepare(query) 
      .asQueryResultList(options); 

    assertEquals(6, resultEntity.size()); 

    // print values 
    System.out.println("From ancestor query:"); 
    System.out.println("All the props: "+resultEntity.get(0).getProperties()); 
    System.out.println("idx prop: "+resultEntity.get(0).getProperty("chapters_INTEGER_IDX")); 
    System.out.println(); 

    Entity chapter = datastore.get(resultEntity.get(0).getKey()); 
    System.out.println("All the props: "+chapter.getProperties()); 
    System.out.println("idx prop: "+chapter.getProperty("chapters_INTEGER_IDX")); 

    // test against JUnit 
    assertNotNull(resultEntity.get(0).getProperty("chapters_INTEGER_IDX")); 
    assertNotNull(chapter.getProperty("chapters_INTEGER_IDX")); 
} 

가있다

는 여기 모델을 요약 GitHub-project.

답변

1

발견!

당신은 jdoconfig.xml이 줄을 추가해야

:

다음

<property name="datanucleus.appengine.storageVersion" value="PARENTS_DO_NOT_REFER_TO_CHILDREN"/>

그것은 귀하의 제안 닐에 대한 다른 데이터 저장소 구성을 너무

+0

을 디버그하십시오. Google의 자체 테스트 사례는 '고대 스토리지 버전'을 사용하여 실행되지 않으며 색인 생성 된 목록을 처리합니다. 그러나 당신에게는 "해결책"이 있습니다. – DataNucleus

+0

Mmhhh ... DataNucleus의 의미를 이해하지 못했습니다! 문제는 내 컴퓨터에서 테스트 케이스를 실행하는 것이 었습니다 (Google 클라우드가 아닌 경우). 따라서 JDO는 기본적으로 INTEGER_IDX를 더 이상 유지하지 않습니다. 이제 https://code.google.com/p/datanucleus-appengine/wiki/DataMigrationProcess_for_Version2 –

+0

에 따라 클라우드에서 데이터를 이전하는 과정에 있습니다. 다른 포스터가 사용자 컴퓨터 *에서 실행되는 테스트를 지적했습니다. 그들은 색인 된 목록을 명확하게 보여줍니다. 그들은 기본적으로 최신 저장소 버전을 사용하지만 이전 저장소 버전에서도 실행됩니다. 소유자의 속성에 Collection에있는 요소의 ID를 저장합니다. 그러한 인공 지능 INTEGER_IDX 속성은 필요하지 않으며 코드의 구현 세부 사항에 의존하는 것은 좋지 않습니다. 고대 스토리지 버전과 마찬가지로이 새로운 스토리지 버전을 사용하면 주문이 보존됩니다.컬렉션 세부 정보의 저장은이 새로운 스토리지 버전 – DataNucleus

1

"chapter.book"에 mappedBy가있는 이유는 무엇입니까? 그것은 불법입니다. 관계가 양방향 인 경우 FK가없는쪽에 mappedBy가 있습니다.

+0

덕분에 설명되어있는 piece of code입니다 하지만 제거하려고 시도했지만 여전히 문제가 있습니다. (샘플 및 github 저장소를 업데이트 할 예정입니다.) –

+0

Google은 https://code.google.com/p/datanucleus-appengine/source/browse/#svn%2Ftrunk%2Ftests%2Fcom에서 많은 테스트를 거쳤습니다. % 2Fgoogle % 2Fappengine % 2Fdat 핵으로 구성되며 인덱싱 된 목록을 포함합니다. 모두 통과. HasOneToManyListJDO와 BidirectionalChildListJDO를 보라. 당신이 LOG를보고 당신의 설정이 무엇이 문제인지 디버그하지 마라. –

+0

사실, LOG는 데이터 저장소와 관련된 모든 정보를 저장하고, 저장된 정보를 보여 주며, DB 뷰어는 저장된 정보 (열 등)를 보여주기 때문에 충분히 간단해야한다. –

관련 문제