抽象的
我在 Appengine 中有一个使用 Java 和 JDO 3 的工作应用程序。我发现这些参数(auto_now 和 auto_now_add)与我想在 Java 中实现的完全对应。所以本质上的问题是:如何将 AppEngine 的 Python DateTimeProperty 转换为 Java JDO?
约束
- 将我的应用程序转换为 Python 不是一种选择。
- 添加两个 Date 属性并在创建/更新发生时手动填充这些值不是一种选择。
- 我正在寻找一种解决方案,它与 JDO/Appengine/Database 作者在创建 API 时针对此场景的想法相对应。
- 最好有一个通用选项:假设我在类中有 4 个实体:C1、C2、C3、C4,解决方案是添加一个基类 C0,所有 4 个实体都会扩展,所以 4 个实体不会甚至知道他们正在被“审计”。
[更新]我试过(使用一个简单的实体)
@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(); }
正如答案所建议的那样,但它似乎总是更新值,即使我只是从数据存储中加载值或只是修改不相关的字段(例如String name
)。
您可以轻松地在 java 类上拥有一个属性(setter/getter),并使该属性可持久化(而不是字段)。在该 getter 中,您可以编写任何您想要控制进入数据存储区的值的代码。
如果我没有执行以下 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; }
有什么方法可以区分是否正在进行持久性操作或我的代码正在调用 getter?
2.@Persistent(customValueStrategy = "auto_now_add") private Date lastUpdate;
我用.替换auto_now_add
后建模。但它只在第一次调用时填充一次,无论我修改了多少次其他字段并调用了. 另请注意,它的行为似乎不像文档所说的那样(或者我的英语生疏了):org.datanucleus.store.valuegenerator.TimestampGenerator
Timestamp
java.util.Date
makePersistent
makePersistent
请注意,通过为字段定义值策略,默认情况下,它将始终在持久化时为该字段生成一个值。如果该字段可以存储空值,并且您只希望它在为空时生成持久值(即您自己没有分配值),那么您可以将扩展名“strategy-when-notnull”添加为 false
3.preStore
使用PersistenceManager.addInstanceLifecycleListener
按预期工作,但我可以使用基类使其跨多个实体工作。
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
和public void jdoPreStore() { this.setLastUpdate(new Date()); }
按预期工作,但我可以使用基类使其跨多个实体工作。
为了满足我的第四个约束(使用解决方案 3 或 4)
无论我做什么,我都无法使以下结构起作用:
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;
增强器运行时的问题:
public abstract class Dateable
:DataNucleus.MetaData 将类“[...].Dateable”注册为没有元数据。
public abstract class Dateable
使用上面的日志,但仍然运行代码:
每当我从数据存储中创建或读取数据时,创建日期都会发生变化。@PersistenceCapable public abstract class Dateable
:DataNucleus.MetaData 类“[...].MyEntity”已指定有 1 个主键字段,但此类使用数据存储标识并且应该是应用程序标识。