1

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

这是我的模型(为简单起见,已删除):

用户.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; }
}

书.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)在调用 to 之前调用em.merge(user),但这导致了一个异常,说这本书的所有者在它被持久化时已经设置并且无法更改。我尝试自己设置关系(就像在这个线程中一样),但是在添加书籍时导致事务失败。

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

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

4

1 回答 1

1

Can you try below:

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();
}
于 2012-12-26T06:01:30.910 回答