2009-09-10 40 views
12

Tôi đang sử dụng Google AppEngine, với Java. Khi tôi sử dụng một số tính năng kho dữ liệu, tôi nhận được thông báo lỗi:Kho dữ liệu AppEngine: "Đối tượng có id ... được quản lý bởi một Trình quản lý đối tượng khác"

Object with id "[email protected]" is managed by a different Object Manager 

Tôi không biết điều này có nghĩa là gì hoặc cách khắc phục hoặc tìm tài liệu về lỗi này ở đâu. Ai giúp tôi với? Mã tôi đang sử dụng là:

@PersistenceCapable(identityType = IdentityType.APPLICATION) 
public class School { 
@PrimaryKey 
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
private String shortname; 

@Persistent 
private String fullname; 

@Persistent 
@Order(extensions = @Extension(vendorName="datanucleus", key="list-ordering", value="code asc")) 
private List<Teacher> Teachers; 

... 

public Teacher FindOrCreateTeacher(String code) 
{ 
    // Can we find the teacher without any database code? 
    Teacher newTeacher = FindTeacher(code); 
    if (newTeacher != null) 
     return newTeacher; 

    // Create the teacher: 
    PersistenceManager pm = PMF.get().getPersistenceManager(); 
    Transaction tx = pm.currentTransaction(); 
    try { 
     tx.begin(); 
     for (Teacher teacher : Teachers) { 
      if (teacher.getCode() == code) { 
       tx.rollback(); 
       return teacher; 
      } 
     } 
     newTeacher = new Teacher(code); 
     Teachers.add(newTeacher); 
     pm.makePersistent(newTeacher); 
     pm.makePersistent(Teachers); 
     tx.commit(); 
    } finally { 
     tx.commit(); 
    } 
    return newTeacher; 
} 

Tôi tin rằng "private List<Teacher> Teachers;" đề cập đến mối quan hệ "sở hữu, một đến nhiều".

Trả lời

9

Một đối tượng liên tục chỉ có thể được "quản lý" bởi một PersistenceManager. Trong DataNucleus, nó được hỗ trợ bởi một "ObjectManager". Thông báo nói rằng bạn đang cố gắng liên kết một đối tượng được quản lý bởi một PM với một PM khác. Bạn có thể dễ dàng gỡ lỗi bằng cách in ra PM cho từng đối tượng (liên tục)

JDOHelper.getPersistenceManager(obj); 

Vì bạn không xác định được thông điệp đến từ đâu, không thể nói nhiều hơn. Các mục nhật ký DataNucleus sẽ cho bạn biết cách thức nhiều hơn thế.

Bế Thủ tướng luôn là một điều cần thiết để làm gì (trừ khi bạn muốn rò rỉ tài nguyên)

+0

Giải thích thú vị. +1 – VonC

+0

Bạn có thể giải thích thêm cho tôi về tuổi thọ phù hợp cho một cá thể PM không? Giả sử tôi đang viết một ứng dụng web. Tôi có nên mở và đóng nó trên mọi yêu cầu trang không? Hoặc giữ một ví dụ mở cho toàn bộ thời gian của quá trình? (Nếu tôi cam kết một giao dịch nhưng không đóng PM, điều này có nghĩa là điều tồi tệ nhất xảy ra là rò rỉ bộ nhớ? Ý tôi là, dữ liệu của tôi an toàn?) –

+1

Quá trình này diễn ra trong bao lâu? Một hệ thống web điển hình sẽ sử dụng một PM cho mỗi yêu cầu. Tạo một PM không đắt (tạo ra một PMF * là * đắt tiền). Nếu sử dụng txns thì bạn có thể để PM mở một cách an toàn ... miễn là bạn không thực hiện cập nhật phi giao dịch cũng với PM đó. – DataNucleus

3

Như được minh họa trong this ticket, bạn không nên đóng giờ chiều (PersistenceManager)?

} finally { 
    tx.commit(); 
    pm.close(); 
} 
+0

Ban đầu tôi nghĩ rằng điều này đã giải quyết được vấn đề của tôi, nhưng không. Để bắt đầu, tôi vẫn không biết những gì đang xảy ra và tại sao đóng cửa của người quản lý kiên trì là cần thiết, hoặc khi nó nên được thực hiện. Thứ hai, tài liệu AppEngine khuyến khích sử dụng một mẫu đơn với PersistenceManager và pm.close() có nghĩa là bạn không thể làm gì hơn với kho dữ liệu của Google cho phần còn lại của quá trình. –

+0

Mẫu Singleton với PMF, không phải là PM. pm.close() * không * pmf.close() – DataNucleus

2

DataNucleus,

Cảm ơn bạn đã pm.close(); tip. tôi đã thực hiện một truy vấn với một em

em = EMF.get().createEntityManager();

và thực hiện một cam kết với nhau mà không đóng đầu tiên.

Các vấn đề liên quan