gpt4 book ai didi

java - 如何将 JAVA 对象从 App Engine 发送到 GET?类型 'org.datanucleus.store.types.sco.simple.Date'

转载 作者:行者123 更新时间:2023-11-30 04:12:27 25 4
gpt4 key购买 nike

我正在尝试使用 AppEngine 和 JPA 持久性保存和加载带有日期的对象。但是,当我加载对象并尝试将其发送到 GWT 时,它会抛出此异常:

SEVERE: javax.servlet.ServletContext log: Exception while dispatching incoming RPC call com.google.gwt.user.client.rpc.SerializationException: Type 'org.datanucleus.store.types.sco.simple.Date' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = Wed Oct 09 22:47:22 EDT 2013

这是我的服务器查询:

        Query q = em.createQuery("select ee from EmailEvent ee");
al.addAll( q.getResultList() );

for (EmailEvent row: al) {
log.info(row.getSenderEmail() + ", " + row.getSendDate());
}
return al;

这是一些日志:

Oct 09, 2013 10:47:43 PM com.onixnet.sdm.server.SDMServiceImpl getSentItems
INFO: chloe@domain.com, Wed Oct 09 22:47:21 EDT 2013

这是有问题的类:

package com.onixnet.sdm.shared;
import java.util.Date;
@Entity
public class EmailEvent implements Serializable {
...
private Date sendDate;

我尝试过 java.util.Date 和 java.sql.Date。我尝试删除 AppEngine 管理界面中实体的所有行。两次它都会正确保存并加载,但不会序列化。 (另一个错误是“org.datanucleus.store.types.sco.simple.SqlDate”无法序列化。当它是 java.sql.Date 时,它​​以 long 形式保存到 DataStore 中。)

AppEngine SDK v1.8.5、Java 7、GWT 2.5.1。

最佳答案

找到了:http://bpossolo.blogspot.com/2013/03/upgrading-gae-app-from-jpa1-to-jpa2.html

Enhanced Date properties

I'll start by saying this difference turned out to be extremely annoying.

In JPA1, an entity with a java.util.Date property functioned just as one would expect. You could set the property with new Date(), persist the entity, load it normally and the property was always a true java.util.Date.

In JPA2 this changed. Now, when an entity with a java.util.Date property is persisted to the datastore, datanucleus replaces the Date instance with a org.datanucleus.store.types.sco.simple.Date.

The problem is that the org.datanucleus.store.types.sco.simple.Date cannot be serialized over GWT-RPC. That means any entity with a Date property which has been retrieved from the datastore must be detached from the EntityManager's persistence context before GWT-RPC serialization occurs. During detachment, all those special Date objects are converted back into java.util.Date objects.

There are several ways to do this.

The first option is to explicitly detach a persistent object by calling

entityManager.detach(obj).

There is also a way to cascade detachment to child entities although you probably won't need to do worry about this since your GAE datastore entities probably won't have a nested object graph.

The second option is to set a datanucleus property that automatically detaches all objects when the EntityManager is closed. This is recommended if you can ensure that your EntityManagers are closed before GWT-RPC serialization occurs. In your persistence.xml file, add

True is the default behaviour but it's good to be explicit.

If you are using an "open-session-in-view" style pattern (where you create the EntityManager in a servlet filter and store it in a thread-local variable for use during the http request), then 'detach-on-close' will not work because GWT-RPC serialization will occur before your EntityManager is closed.

The third option is to set a data nucleus property that automatically detaches all objects on commit. This is good if you are using a "open-session-in-view" pattern. In your persistence.xml file, add

You can read more about detachment here. Beware of leaking datanucleus dates

Imagine the following scenario.

@Entity public class User { @Id Long key; Date memberSince; }

public class ProfileViewDTO { Date userJoinDate; }

//in GWT-RPC servlet User user = (User)entityManager.find(User.class, userKey);

ProfileViewDTO dto = new ProfileViewDTO(); dto.userJoinDate = user.memberSince; //date leak!

entityManager.detach(user); entityManager.close();

return dto; //serialization error occurs!

As you can see, the datanucleus date object has leaked and will cause a serialization error. To avoid this, either detach the user before setting the dto's property or copy the date explicitly. It is also important to do this before caching an object in GAE memcache.

I had "date leaks" all over which is why I found this new JPA2 behaviour really annoying. It took me a while to track them all down and fix them.

我用过

for (EmailEvent row: al) {
em.detach(row);
log.info(row.getSenderEmail() + ", " + row.getSendDate());
}

我还设置了该属性(但这似乎没有帮助)。

关于java - 如何将 JAVA 对象从 App Engine 发送到 GET?类型 'org.datanucleus.store.types.sco.simple.Date',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19286354/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com