我使用Java使用Google App Engine,并通过JPA使用数据存储。 我想为每个用户保存个人资料图片:
@Entity
public class User implements Serializable {
@Id
private String userId;
private String imageKey; // saves BlobKey.getKeyString()
// ... other fields and getter/setter methods ...
}
如果用户想要更改其个人资料图片,我(应该)更新imageKey字段并删除与旧imageKey关联的旧图像。
但是,the document of Blobstore for Python说:
删除Blobstore值与数据存储区事务分开。如果在数据存储区事务期间调用此方法,则无论事务是成功提交还是重试,它都会立即生效。
这似乎无法更新imageKey并删除旧图像作为一个原子动作,它也会影响Java。
这是我尝试做这项工作的方法:
public class Engine implements ServletContextListener {
private EntityManagerFactory emf;
private BlobstoreService blobstoreService;
// Servlet will call getUser, modify returned object, and call updateUser with that object
public User getUser(final String userId) throws EngineException {
return doTransaction(new EngineFunc<User>() { // Utility method for create Entity manager and start transaction
@Override
public User run(EntityManager em) throws EngineException {
return em.find(User.class, key);
}
});
}
public void updateUser(final User user) throws EngineException {
doTransaction(new EngineFunc<Void>() {
@Override
public Void run(EntityManager em) throws EngineException {
em.merge(user);
return null;
}
});
user.purgeOldImages(blobstoreService);
}
// ... Other methods ...
}
public class User {
@Transient
private transient Set<String> oldImageList = new CopyOnWriteArraySet<>();
public void setImageKey(String imageKey) {
if (this.imageKey != null) {
oldImageList.add(this.imageKey);
}
this.imageKey = imageKey;
if (imageKey != null) {
oldImageList.remove(imageKey);
}
}
public void purgeOldImages(BlobstoreService blobService) {
Set<BlobKey> toDelete = new HashSet<>();
for (String s : oldImageList) {
toDelete.add(new BlobKey(s));
oldImageList.remove(s);
}
blobService.delete(toDelete.toArray(new BlobKey[0]));
}
// ... Other methods ...
}
我认为这既不是“美丽”也不是正确的代码。 有没有正确的方法来做到这一点?