简体   繁体   English

如何使用Java JDO 3将创建的/ lastUpdate字段存储在AppEngine DataStore中?

[英]How to store created/lastUpdate fields in AppEngine DataStore using Java JDO 3?

Abstract 抽象

I have a working application in Appengine using Java and JDO 3. I found these arguments ( auto_now and auto_now_add ) which correspond exactly what I want to implement in Java. 我在使用Java和JDO 3的Appengine中有一个正在运行的应用程序。我发现这些参数( auto_now和auto_now_add )与我要在Java中实现的确切对应。 So essentially the question is: How to convert AppEngine's Python DateTimeProperty to Java JDO? 因此,本质上的问题是:如何将AppEngine的Python DateTimeProperty转换为Java JDO?

Constraints 约束条件

  1. Converting my application to Python is not an option. 不能将我的应用程序转换为Python。
  2. Adding two Date properties and manually populating these values whenever a create/update happens is not an option. 不能选择添加两个Date属性并在每次创建/更新时手动填充这些值。
  3. I'm looking for a solution which corresponds to what JDO/Appengine/Database authors had in mind for this scenario when they created the APIs. 我正在寻找一种解决方案,该解决方案与JDO / Appengine / Database作者在创建API时针对此场景的想法相对应。
  4. It would be preferable to have a generic option: say I have 4 entities in classes: C1, C2, C3, C4 and the solution is to add a base class C0, which all 4 entities would extend, so the 4 entities don't even know they're being "audited". 最好有一个通用选项:说我在类中有4个实体:C1,C2,C3,C4,解决方案是添加一个基类C0,所有这4个实体都将扩展,所以这4个实体不会甚至知道他们正在被“审核”。

[update] I tried (using a simple entity) [更新]我尝试过(使用一个简单的实体)

@PersistenceCapable public class MyEntity {
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY, primaryKey = "true")
    private Long id;
    @Persistent private String name;
    ...

1. @Persistent public void getLastUpdate() { return new Date(); } 1. @Persistent public void getLastUpdate() { return new Date(); } @Persistent public void getLastUpdate() { return new Date(); }

As suggested by answer, but it seems to always update the value, even when I just load the value from the datastore or just modify an unrelated field (eg String name ). 如答案所示,但即使我只是从数据存储区中加载值或只是修改不相关的字段(例如String name ),它似乎总是会更新该值。

You can easily enough have a property (setter/getter) on a java class and have the property persistable (rather than the field). 您可以轻松地在java类上具有一个属性(setter / getter),并使该属性可持久(而不是字段)。 Within that getter you can code whatever you want to control what value goes into the datastore. 在该getter中,您可以编写任何代码,以控制将什么值放入数据存储区。

If I didn't do the following hack, I can't read the value stored in the datastore [neither with the hack :( ]: 如果未进行以下修改,则无法读取存储在数据存储区中的值[hack :(]均不可用:

@Persistent public Date getLastUpdate() { return new Date(); }
private Date prevUpdate;
public void setLastUpdate(Date lastUpdate) { this.prevUpdate = lastUpdate; }
public Date getPrevUpdate() { return prevUpdate; }

Is there any way to differentiate if a persistence operation is in progress or my code is calling the getter? 有什么方法可以区分是正在进行持久性操作还是代码正在调用getter?

2. @Persistent(customValueStrategy = "auto_now_add") private Date lastUpdate; 2. @Persistent(customValueStrategy = "auto_now_add") private Date lastUpdate;

I modeled auto_now_add after org.datanucleus.store.valuegenerator.TimestampGenerator replacing Timestamp with java.util.Date . org.datanucleus.store.valuegenerator.TimestampGeneratorjava.util.Date替换Timestamp之后,我对auto_now_add进行了建模。 But it was only populated once at the first makePersistent call, regardless of how many times I modified other fields and called makePersistent . 但是,无论我修改其他字段并调用makePersistent多少次,它在第一次makePersistent调用中仅填充一次。 Also note that it doesn't seem to behave as the documentation says (or my English is rusty): 还要注意,它似乎不像文档中所说的那样工作(或者我的英语很生锈):

Please note that by defining a value-strategy for a field then it will, by default, always generate a value for that field on persist. 请注意,通过为字段定义值策略,默认情况下,它将在持久化时始终为该字段生成值。 If the field can store nulls and you only want it to generate the value at persist when it is null (ie you haven't assigned a value yourself) then you can add the extension "strategy-when-notnull" as false 如果该字段可以存储空值,并且您只希望它在为空值时(即您自己尚未分配值)在persist时生成值,则可以将扩展名“ strategy-when-notnull”添加为false

3. preStore using PersistenceManager.addInstanceLifecycleListener 3.使用PersistenceManager.addInstanceLifecycleListener preStore

Works as expected, but I could make it work across multiple entities using a base class. 可以按预期工作,但是我可以使用基类使其跨多个实体工作。

pm.addInstanceLifecycleListener(new StoreLifecycleListener() {
    @Override public void preStore(InstanceLifecycleEvent event) {
        MyEntity entity = (MyEntity)event.getPersistentInstance();
        entity.setLastUpdate(new Date());
    }
    @Override public void postStore(InstanceLifecycleEvent event) {}
}, MyEntity.class);

4. implements StoreCallback and public void jdoPreStore() { this.setLastUpdate(new Date()); } 4. implements StoreCallbackpublic void jdoPreStore() { this.setLastUpdate(new Date()); } public void jdoPreStore() { this.setLastUpdate(new Date()); }

Works as expected, but I could make it work across multiple entities using a base class. 可以按预期工作,但是我可以使用基类使其跨多个实体工作。

To satisfy my 4th constraint (using solutions 3 or 4) 满足我的第4个约束(使用解决方案3或4)

Whatever I do I can't make the following structure work: 无论我做什么,我都无法使以下结构起作用:

public abstract class Dateable implements StoreCallback {
    @Persistent private Date created;
    @Persistent private Date lastUpdate;
    public Dateable() { created = new Date(); }
    public void jdoPreStore() { this.setLastUpdate(new Date()); }
    // ... normal get/set properties for the above two
}
@PersistenceCapable public class MyEntity extends Dateable {
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY, primaryKey = "true") private Long id;
    @Persistent private String name;

The problems when the enhancer runs: 增强器运行时的问题:

  • public abstract class Dateable : public abstract class Dateable

    DataNucleus.MetaData Registering class "[...].Dateable" as not having MetaData. DataNucleus.MetaData注册类“ [...]。Dateable”为没有MetaData。

  • public abstract class Dateable with the above log, but running the code anyway: public abstract class Dateable与上面的日志,但仍然运行代码:
    Creation date changes whenever I create or read the data from datastore. 每当我从数据存储区创建或读取数据时,创建日期都会更改。

  • @PersistenceCapable public abstract class Dateable : @PersistenceCapable public abstract class Dateable

    DataNucleus.MetaData Class "[...].MyEntity" has been specified with 1 primary key fields, but this class is using datastore identity and should be application identity. 已经使用1个主键字段指定了DataNucleus.MetaData类“ [...]。MyEntity”,但是此类使用的是数据存储标识,应为应用程序标识。

JDO simply provides persistence of Java classes (and its fields/properties) so don't see what the design of JDO has to do with it. JDO只是提供Java类(及其字段/属性)的持久性,因此看不到JDO的设计与它有什么关系。

You can easily enough have a property (setter/getter) on a java class and have the property persistable (rather than the field). 您可以轻松地在java类上具有一个属性(setter / getter),并使该属性可持久(而不是字段)。 Within that getter you can code whatever you want to control what value goes into the datastore. 在该getter中,您可以编写任何代码,以控制将什么值放入数据存储区。 Either that or you use a preStore listener to be able to set things just before persistence so the desired value goes into the datastore. 要么,要么您使用preStore侦听器就可以在持久性之前进行设置,以便所需的值进入数据存储区。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用JDO存储键值对(datanucleus&appengine) - How to store Key-Value pairs using JDO (datanucleus & appengine) 如何优化AppEngine Java / JDO数据存储区put()以减少写入次数 - How can I optimize an AppEngine Java/JDO datastore put() to use less writes 如何使用Java将Unicode字符串保存到数据存储区Google Appengine - How to save unicode string into datastore google appengine using java 如何在AppEngine数据存储区中存储单个实例对象 - How to store a single instance object in the AppEngine datastore 如何在Java中设置Appengine DataStore的loglevel - How to set loglevel of the Appengine DataStore in Java 如何使用JDO在AppEngine中的多对一中按其父项过滤实体 - How to filter entities by their parents in Many-To-One in AppEngine using JDO 如何将二进制数据字段从Appengine数据存储区导出到其他数据库? - How to export binary data fields from appengine datastore to other databases? 如何在数据库中存储“ com.google.appengine.api.datastore.Text” - How to store “com.google.appengine.api.datastore.Text” in database 如何使用Java确定Google AppEngine数据存储区中给定键的对象是否存在? - How to I determine if an object exists for a given key in the Google AppEngine datastore using Java? 使用Java中的AppEngine和EntityManager将记录存储到Google DataStore中时出错 - Error when storing record into Google DataStore using AppEngine and EntityManager in Java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM