部署时GAE / J OneToMany JPA持久性失败

时间:2012-12-25 23:10:29

标签: google-app-engine jpa deployment persistence one-to-many

我正在使用带有JPA的Google App Engine来实现一对多的双向关系。当我在家里的机器上调试和测试我的应用程序时,一切正常,但在我将它部署到App Engine之后,持久性似乎已经崩溃。

这是我的模型(为简单起见而剥离):

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; }
}

Book.java:

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

    @ManyToOne(fetch = FetchType.LAZY)
    private User owner;

    private String name;
}

创建新的User

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实体的持久性,因此我添加了“TEST”一书。问题仍然存在,只是现在我有了第一本书(“TEST”),每当我尝试添加一本新书时,我会不断更换列表中的第二本书。

同样,只有在我部署之后调试我的应用程序时才会发生这种情况。

我在调用em.persist(book)之前尝试调用em.merge(user),但是这导致了一个例外情况,即该图书的所有者已经设置为持久且无法更改。我尝试自己设置关系(就像在此thread中一样),但是在添加图书时导致交易失败。

我不确定它是否相关,但我看到的“图书”列的类型是datastore_types.Key.from_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')]

任何帮助将不胜感激, 谢谢!

1 个答案:

答案 0 :(得分:1)

你可以尝试下面的内容:

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();
}