2013-02-20 21 views
8

Tôi đang sử dụng Goole App Engine để xây dựng API REST của tôi, tôi đã đánh dấu lớp học của tôi như PersistenceCapable và tôi cũng đã được xác định của tôi @PrimaryKey và cũng đánh dấu là @Persistent (valueStrategy = IdGeneratorStrategy.IDENTITY), tôi cũng đã tạo EndPoints. nhưng khi tôi gõ vào cửa sổ thiết bị đầu cuối một lệnh curl để chèn một thực thể mới hoặc đăng ký nó không hoạt động. đây là đoạn code:Tạo Id Automatic IdGeneratorStrategy

@PersistenceCapable(identityType = IdentityType.APPLICATION) 
class Student{ 
    @PrimaryKey 
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
    private Long  id; 
    private String studentName; 
    .... 
    .... 
    .... 
} 

đây là lệnh và phản hồi từ máy chủ địa phương của tôi curl. khi tôi cố gắng để chèn một thực thể mới

curl -H 'Content-Type: application/json' -d'{"studentName": "myname"}' htto://localhost:8889/_ah/api/utp/v1/student 

và đây là phản hồi từ máy chủ địa phương.

"error" : { 
"message" : "javax.jdo.JDOFatalInternalException: El valor de llave dado para construir una identidad de SingleFieldIdentity de tipo \"class javax.jdo.identity.LongIdentity\" para la clase \"class com.alex.wserver.Student\" es nulo.\nNestedThrowables:\norg.datanucleus.exceptions.NucleusException: El valor de llave dado para construir una identidad de SingleFieldIdentity de tipo \"class javax.jdo.identity.LongIdentity\" para la clase \"class com.alex.wserver.Student\" es nulo." 

Tôi đã nghĩ rằng id được tạo tự động khi được chèn. nhưng điều đó không xảy ra ở đây. Không giống như các chèn một id cùng


  1. là lớp học của tôi sai?
  2. là yêu cầu POST/json của tôi Ok?

Xin cảm ơn trước.

+0

và nhật ký nói gì? (Tôi cũng không thể đọc những chữ tượng hình mà bạn đã đăng ở trên; tôi thấy không có mã kiên trì Java ở đó, chẳng hạn như pm.makePersistent). – DataNucleus

+0

Bạn có thể dán trực tiếp đoạn mã. Những hình ảnh này khá nhỏ và khó tìm ra. –

+0

Tôi đã thay đổi hình ảnh bằng mã bị cắt ... xin lỗi vì hình ảnh xấu ... – AlexSanchez

Trả lời

8

Tôi nghĩ rằng tôi đã tìm ra giải pháp. Dường như mọi điểm cuối được tạo bởi khung công cụ Google App Engine (GAE) đều có phương pháp đơn giản kiểm tra mỗi lần ai đó đang cố gắng chèn hoặc cập nhật và phiên bản kiên trì, vì vậy thực tế là mỗi lần tôi cố gắng chèn sinh viên sử dụng curl/json mà không ghi rõ de id mới cho các trường hợp nó hiển thị một thông báo lỗi như thế này:

"error": { 
     "message": javax.jdo.JDOFatalInternalException: The key value passed to construct a 
     SingleFieldIdentity type \ class javax.jdo.identity.LongIdentity \ for class \ class com.alex.wserver.Student \ is null. \ nNestedThrowables: \ norg.datanucleus.exceptions.NucleusException: the key value passed to construct a SingleFieldIdentity type \ class javax.jdo.identity.LongIdentity \ for class \ class com.alex . wserver.Student \ is null. 

vì vậy tôi đã giải quyết vấn đề chỉnh sửa lớp endpoint của tôi bằng cách kiểm tra nếu đối tượng mới (được gửi bởi lệnh curl và định dạng json được bao bọc) có giá trị id không null trước khi kiểm tra xem đối tượng đã được lưu trước đó với mã này chưa:

 if(student.getKey() != null){ 
      if (containsStudent(student)) { 
       throw new EntityExistsException("Object already exists"); 
      } 
     } 
     mgr.makePersistent(student); 

Tôi chưa thấy bất kỳ tài liệu nào có thể làm rõ khía cạnh đó cho tôi. Ngoài ra tôi thêm, tôi đã dành rất nhiều thời gian đọc tài liệu trên GAE trước khi cố gắng tìm ra những gì đang xảy ra.


Tất cả điều đó khiến tôi nghĩ rằng có thể tài liệu GAE không cập nhật hoặc có thể không đủ tìm kiếm, vì vậy nếu ai đó biết. hãy cho tôi biết và phát triển kiến ​​thức chung. cảm ơn @DataNucleus.

LƯU Ý: "Cái nĩa mà tôi đã tạo ra không được đặt thành câu trả lời đúng, có thể đưa bạn đến ứng xử không mong muốn của ứng dụng."

+1

+1 Bạn đã cứu ngày của tôi! Điều này có thể được coi là một lỗi của GPE tạo ra mã không mong muốn cho Google Cloud Endpoints. –

+2

hello @ToyHunter, tôi đã thực hiện một số nghiên cứu và tôi đã tìm thấy một giải pháp tốt hơn. bây giờ tôi đang sử dụng một đối tượng Iterator tĩnh chứa một dãy các khóa. vì vậy mỗi khi tôi POST một thực thể mới, tôi lấy Key mới cho đối tượng mới. tôi đã viết một phương thức tĩnh riêng bên trong lớp Endpoint để khởi tạo trình lặp, vì vậy khi tôi POST một đối tượng mới, trình vòng lặp nhận được một khóa mới và tôi chỉ gán nó cho đối tượng mới và duy trì nó.không một số tham chiếu (https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/KeyRange) – AlexSanchez

+1

+1 Cách tiếp cận của bạn chắc chắn hữu ích từ quan điểm mà những người có thể muốn giữ lại id thông qua di chuyển dữ liệu. Chỉ cần tự hỏi tại sao không phải tất cả các vấn đề này đều được App Engine chăm sóc. –

0

Như đã nhận xét trong câu trả lời của AlexSanchez, mã điểm cuối được tạo ra dự kiến ​​khóa chính đã được đặt trên chèn các định danh mới.

Trong khi một số có thể coi đây là lỗi, một số khác có thể xem dưới dạng đối tượng địa lý, vì yêu cầu khách hàng tạo khóa bằng cách nào đó (ví dụ: bằng cách tạo uuid ngẫu nhiên khi loại khóa là Chuỗi). Bằng cách này, khách hàng có thể tạo một biểu đồ đầy đủ các thực thể ngay cả khi ngoại tuyến và tải chúng lên máy chủ khi trực tuyến.

(Tôi nghĩ rằng khuôn khổ cột sống là một ví dụ cho ý tưởng này:. http://spinejs.com/)

1

Vấn đề nằm ở chỗ chứa phương pháp của thiết bị đầu cuối được tạo ra tự động. Ngoại lệ được ném là javax.jdo.JDOFatalInternalException khi id là null và phương thức bắt ngoại lệ javax.jdo.JDOObjectNotFoundException.

Ngoại lệ không bao giờ bị bắt và bạn gặp lỗi. Tôi không nếu đó là một lỗi hoặc những gì, nhưng sau khi cập nhật các tuyên bố bắt để bắt cả hai, vấn đề đã được giải quyết.

Hy vọng điều đó sẽ hữu ích!

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