[英]Java - How to delete an entity from Google Cloud Datastore
Architecture: I have a web application from where I'm interacting with the Datastore and a client (raspberry pi) which is calling methods from the web application using Google Cloud Endpoints. 体系结构:我有一个Web应用程序,从中与数据存储区进行交互,还有一个客户端(树莓派),该客户端使用Google Cloud Endpoints从Web应用程序中调用方法。
I have to add that I'm not very familiar with web applications and I assume that something's wrong with the setConsumed() method because I can see the call of /create in the app engine dashboard but there's no entry for /setConsumed. 我必须补充一点,我对Web应用程序不是很熟悉,并且我认为setConsumed()方法出了点问题,因为我可以在应用程序引擎仪表板上看到/ create的调用,但是/ setConsumed没有任何条目。
I'm able to add entities to the Datastore using objectify: 我可以使用objectify将实体添加到数据存储区:
//client method
private static void sendSensorData(long index, String serialNumber) throws IOException {
SensorData data = new SensorData();
data.setId(index+1);
data.setSerialNumber(serialNumber);
sensor.create(data).execute();
}
//api method in the web application
@ApiMethod(name = "create", httpMethod = "post")
public SensorData create(SensorData data, User user) {
// check if user is authenticated and authorized
if (user == null) {
log.warning("User is not authenticated");
System.out.println("Trying to authenticate user...");
createUser(user);
// throw new RuntimeException("Authentication required!");
} else if (!Constants.EMAIL_ADDRESS.equals(user.getEmail())) {
log.warning("User is not authorised, email: " + user.getEmail());
throw new RuntimeException("Not authorised!");
}
data.save();
return data;
}
//method in entity class SensorData
public Key<SensorData> save() {
return ofy().save().entity(this).now();
}
However, I'm not able to delete an entity from the datastore using the following code. 但是,我无法使用以下代码从数据存储区中删除实体。
EDIT: There are many logs of the create-request in Stackdriver Logging, but none of setConsumed()
. 编辑:
setConsumed()
Logging中有很多创建请求的日志,但没有setConsumed()
。 So it seems like the calls don't even reach the API although both methods are in the same class. 因此,尽管这两种方法都在同一类中,但调用似乎没有到达API。
EDIT 2: The entity gets removed when I invoke the method from the Powershell so the problem is most likely on client side. 编辑2:当我从Powershell调用该方法时,该实体被删除,因此该问题最有可能发生在客户端。
//client method
private static void removeSensorData(long index) throws IOException {
sensor.setConsumed(index+1);
}
//api method in the web application
@ApiMethod(name = "setConsumed", httpMethod = "put")
public void setConsumed(@Named("id") Long id, User user) {
// check if user is authenticated and authorized
if (user == null) {
log.warning("User is not authenticated");
System.out.println("Trying to authenticate user...");
createUser(user);
// throw new RuntimeException("Authentication required!");
} else if (!Constants.EMAIL_ADDRESS.equals(user.getEmail())) {
log.warning("User is not authorised, email: " + user.getEmail());
throw new RuntimeException("Not authorised!");
}
Key serialKey = KeyFactory.createKey("SensorData", id);
datastore.delete(serialKey);
}
I was able to solve it by myself finally! 我终于能够自己解决!
The problem was just related to the data type of the index used for removeSensorData(long index)
which came out of a for-loop and therefore was an Integer instead of a long. 问题仅与用于
removeSensorData(long index)
的索引的数据类型有关,该数据来自for循环,因此是Integer而不是long。
This is what I follow to delete an entity from datastore. 这就是我要从数据存储中删除实体的过程。
public boolean deleteEntity(String propertyValue) {
String entityName = "YOUR_ENTITY_NAME";
String gql = "SELECT * FROM "+entityName +" WHERE property= "+propertyValue+"";
Query<Entity> query = Query.newGqlQueryBuilder(Query.ResultType.ENTITY, gql)
.setAllowLiteral(true).build();
try{
QueryResults<Entity> results = ds.run(query);
if (results.hasNext()) {
Entity rs = results.next();
ds.delete(rs.getKey());
return true;
}
return false;
}catch(Exception e){
logger.error(e.getMessage());
return false;
}
}
If you don't want to use literals, you can also use binding as follows: 如果您不想使用文字,也可以如下使用绑定:
String gql = "SELECT * FROM "+entityName+" WHERE property1= @prop1 AND property2= @prop2";
Query<Entity> query = Query.newGqlQueryBuilder(Query.ResultType.ENTITY, gql)
.setBinding("prop1", propertyValue1)
.setBinding("prop2", propertyValue2)
.build();
Hope this helps. 希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.