Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google app engine 部署时GAE/J OneToMany JPA持久性故障_Google App Engine_Jpa_Deployment_Persistence_One To Many - Fatal编程技术网

Google app engine 部署时GAE/J OneToMany JPA持久性故障

Google app engine 部署时GAE/J OneToMany JPA持久性故障,google-app-engine,jpa,deployment,persistence,one-to-many,Google App Engine,Jpa,Deployment,Persistence,One To Many,我正在使用Google App Engine和JPA来实现一对多的双向关系。当我在家里的机器上调试和测试我的应用程序时,一切都很好,但在我将其部署到应用程序引擎后,持久性似乎崩溃了 这就是我的模型(为了简单起见,将其简化): User.java: @Entity class User implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Key i

我正在使用Google App Engine和JPA来实现一对多的双向关系。当我在家里的机器上调试和测试我的应用程序时,一切都很好,但在我将其部署到应用程序引擎后,持久性似乎崩溃了

这就是我的模型(为了简单起见,将其简化):

User.java:

@Entity
class User implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key id;

    @OneToMany(mappedBy = "owner",
               cascade = CascadeType.ALL,
               fetch = FetchType.EAGER)
    private List<Book> books;

    public getBooks() { return this.books; }
}
要创建新的
用户

User user = new User()

// This is done just for testing. It works fine.
user.getBooks().add(new Book("TEST"))

EntityManager em = /* ... */
EntityTransaction transaction = em.getTransaction();

try
{
    transaction.begin();
    em.persist(user);
    transaction.commit();
}

/* Exceptions handling. */

finally
{
    if (transaction.isActive())
        transaction.rollback();

    em.close();
}
并添加一本书:

User user = /* ... */
Book book = new Book("A new book");

user.getBooks().add(book);

EntityManager em = /* ... */
EntityTransaction transaction = em.getTransaction();

try
{
    transaction.begin();
    /* user.getBooks().add(book);  - placing this here doesn't change anything */
    em.merge(user);
    transaction.commit();
}

/* Exceptions handling. */

finally
{
    if (transaction.isActive())
        transaction.rollback();

    em.close();
}
在我添加与用户一起创建的“测试”书籍之前,我看到的是,创建第一个书籍实体的工作正常,但每当我创建另一个实体时,前一个实体会以某种方式从数据存储中删除,并被我刚创建的新实体所取代(我可以看出,因为书籍的名称)。因此,我不能为同一用户创建多本书

我试图看看我是否以某种方式弄乱了Book实体的持久性,出于这个原因,我添加了“测试”书。问题依然存在,只是现在我有了第一本书(“测试”),每当我试图添加一本新的书时,我总是替换列表上的第二本书

同样,这在调试应用程序时不会发生,只有在部署之后才会发生

在调用
em.merge(user)
之前,我尝试调用
em.persist(book)
,但这导致了一个异常,即图书的所有者在持久化时已设置,无法更改。我尝试自己设置关系(如下图所示),但在添加书籍时导致事务失败

我不确定它是否相关,但我看到的“books”列的类型是
datastore\u types.Key.from\u path
,如所示:

[datastore_types.Key.from_path(u'User', 9001L, u'Book', 1L, _app=u's~myapp'),
 datastore_types.Key.from_path(u'User', 9001L, u'Book', 2001L, _app=u's~myapp')]
任何帮助都将不胜感激, 谢谢大家!

你能试试下面的方法吗:

User user = /* ... */
Book book = new Book("A new book");

book.setOwner(user);

EntityManager em = /* ... */
EntityTransaction transaction = em.getTransaction();

try{
    transaction.begin();
    em.persist(user);
    transaction.commit();

}finally{
    if (transaction.isActive())
        transaction.rollback();

    em.close();
}
你能试试下面吗

User user = /* ... */
Book book = new Book("A new book");

book.setOwner(user);

EntityManager em = /* ... */
EntityTransaction transaction = em.getTransaction();

try{
    transaction.begin();
    em.persist(user);
    transaction.commit();

}finally{
    if (transaction.isActive())
        transaction.rollback();

    em.close();
}

这是一个双向关系,但你还没有设置关系的两面。没有理由认为对txn中分离的对象执行某些操作会产生影响。。。物体毕竟是分离的。不知道这是什么“不知何故”。。。您有一个日志,它告诉您所有持久性操作的所有DB调用,因此,您需要了解itI的所有信息。当我添加新用户时,我只有以下警告:
com.google.appengine.datanucleus.MetaDataValidator警告:user.books的元数据警告:user.books的元数据错误。books:数据存储不支持联接,因此无法满足将相关对象放入默认值的请求获取组。在第一次访问时,该字段将被延迟提取。
我不认为图书对象是分离的,因为我可以在重定向到的JSP中看到它们的属性。顺便说一句,我在GAE的管理控制台中可以看到的唯一日志是在“日志”和“管理日志”下,这两个日志都没有告诉我“我的所有持久性操作”的任何信息和/或我的数据存储调用(从应用程序进行的调用,而不是由我作为管理员手动进行的调用)。是否有一个设置以某种方式启用这些详细的数据存储日志?GAE文档引用DataNucleus(用于持久化),如果存在Log4j,则可以使用它,否则使用JDK1.4日志。这些是标准的日志记录包。在调试某些东西时,使用调试级别日志记录(而不是警告或更高级别日志记录)是正常的。OK,我修改了代码,将事务中的图书所有者设置为从
merge
返回的值(即
book.setOwner(em.merge(user))
)。这是因为在事务外部调用
book.setOwner(user)
导致异常,表示
book
的所有者与事务期间试图设置的所有者不同。然而,问题依然存在——一本新书的创作压倒了旧书。这是一种双向关系,但你还没有设定这种关系的双方。没有理由认为对txn中分离的对象执行某些操作会产生影响。。。物体毕竟是分离的。不知道这是什么“不知何故”。。。您有一个日志,它告诉您所有持久性操作的所有DB调用,因此,您需要了解itI的所有信息。当我添加新用户时,我只有以下警告:
com.google.appengine.datanucleus.MetaDataValidator警告:user.books的元数据警告:user.books的元数据错误。books:数据存储不支持联接,因此无法满足将相关对象放入默认值的请求获取组。在第一次访问时,该字段将被延迟提取。
我不认为图书对象是分离的,因为我可以在重定向到的JSP中看到它们的属性。顺便说一句,我在GAE的管理控制台中可以看到的唯一日志是在“日志”和“管理日志”下,这两个日志都没有告诉我“我的所有持久性操作”的任何信息和/或我的数据存储调用(从应用程序进行的调用,而不是由我作为管理员手动进行的调用)。是否有一个设置以某种方式启用这些详细的数据存储日志?GAE文档引用DataNucleus(用于持久化),如果存在Log4j,则可以使用它,否则使用JDK1.4日志。这些是标准的日志记录包。在调试某些东西时,使用调试级别日志记录(而不是警告或更高级别日志记录)是正常的。OK,我修改了代码,将事务中的图书所有者设置为从
merge
返回的值(即
book.setOwner(em.merge(user))
)。这是因为在事务外部调用
book.setOwner(user)
导致异常,表示
book
的所有者与事务期间试图设置的所有者不同。然而,问题依然存在——一本新书的创作压倒了旧书。这似乎不起作用。首先是因为对已持久化的
用户
第二次调用了
persist
。第二,我把它切换到了一个
merge
,但是显然
user
不知道
book
的任何信息,而没有调用
books.add
。。。我试着在事务之前同时调用
书籍。add
setOwner
,但这不起作用