为什么EntityManager.flush()在JPA 1.0 / AppEngine中不起作用?

时间:2013-07-10 21:46:07

标签: google-app-engine jpa datanucleus

当我有一个名为“em”的EntityManager对象并且调用em.flush()时,没有任何反应。我期待当前的事务到flush - 即此时写入数据库的数据。为什么不发生?

这是我正在使用的商务课程:

@Entity
public class SomeObject {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long Id;
    public String Property1;
    public String Property2;
}

这是写入和刷新的测试代码:

public void transactionTest() {     
    EntityManager em = Database.getEntityManager();
    em.getTransaction().begin();        

    SomeObject obj = new SomeObject();
    obj.Id = 2L;
    obj.Property1 = "A";
    em.persist(obj); 
    em.flush(); 
    obj.Property2 = "B"; // Breakpoint here, expecting data to have be written
    em.getTransaction().commit(); // ...but the data is not written until after this line.
    em.close(); 
}  

这是我的persistence.xml

<persistence>
    <persistence-unit name="no-xtransactions">
        <provider>org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider</provider>
        <properties>
            <property name="datanucleus.nontx.atomic" value="false"/>
            <property name="datanucleus.NontransactionalRead" value="true"/>
            <property name="datanucleus.NontransactionalWrite" value="true"/>
            <property name="datanucleus.ConnectionURL" value="appengine"/>
            <property name="datanucleus.appengine.datastoreEnableXGTransactions" value="false"/>
        </properties>
    </persistence-unit>
</persistence>

我正在使用JPA / JDO 1.0在AppEngine SDK v1.7.4的本地数据存储区上测试它,方法是在检查来自AppEngine API生成的localhost Web界面的数据的同时在注释行上设置断点。在关闭EntityManager之前,不会存储该对象。

我还在生产AppEngine上通过同时实例化两个EntityManage来测试它,以便第二个EntityManager在em.flush() - 行之后读取。我不确定测试方法是否合适(你有两个EntityManagers吗?),所以我不确定我是否可以相信结果。

1 个答案:

答案 0 :(得分:0)

您正在使用旧的(不支持的)代码(即JPA1 GAE)。 您正在更新实体的公共字段(JPA规范无效,无论如何都是错误的做法)。

解决方案很简单:使用JPA2 GAE(大约2年前发布),并且不更新实体的公共字段(使用setter,或使用DataNucleus“PersistenceAware”扩展)