我有一个项目,我有一个用户将页面列表作为实体。当我第一次使用页面创建用户时,所有提取都按预期工作,但是在我重新启动 local_db.bin appengine-datanucleus 服务器后,我在提取页面列表时收到错误消息。我正在使用请求工厂,所以我将页面的 ID 作为字符串 - 如果这是错误的,请纠正我。在下面的代码中,我强制获取页面列表,但实际上,当 .with("pages") 方法添加到请求时,请求工厂代码会加载列表。但是页面的强制加载会导致相同的错误,它使我可以轻松地进入代码。
我得到的错误是java.lang.Long 不能转换为 java.lang.Integer. 我已经遍历了很多数据核代码,并且错误似乎正在发生,因为来自商店的数据被加载到新创建的类中。类中唯一的整数是版本和一个字段 - 我尝试将这两个字段都设置为 Longs - 清除数据库,重新创建数据然后重新启动服务器,我得到了同样的错误。我的感觉是它与使 id 成为字符串有关。
要么我设置错误,要么 datanucleus JPA 2 支持存在错误。希望有人知道这个问题的答案。下面是导致错误的两个实体类和服务方法。
@Entity
public class User {
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "userIds") @SequenceGenerator(name = "userIds")
private Long id;
@Version private Integer version;
private String name = "";
private String lowerName = "";
private Date lastLoginDate;
private Date createDate;
private boolean isAdmin;
private String language = "en";
private String country = "US";
private String timezone = "EST";
private String theme = "HI";
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Page> pages ;
private String startPageName = "";
public User() {
createDate = new Date();
pages = new ArrayList<Page>();
}
Plus some getters and setters.
和页面类
@Entity
public class Page {
@Id
@GeneratedValue(strategy = IDENTITY)
@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
private String id;
@Version private Integer version;
@ManyToOne(fetch = FetchType.LAZY) private User user;
private String name = "";
private String description = "";
private Integer columnCount = 3;
@Enumerated private LayoutType layoutType = LayoutType.Col3StyleEven;
Plus some getters and setters.
以及将产生错误的方法。
public User getCurrentUser() {
Long id = securityProvider.get().getUserId();
if (id == null) {
return null;
}
EntityManager em = emProvider.get();
try {
User user = em.find(User.class, id);
List<Page> pages = user.getPages(); // Force loading
return user;
} catch (Exception e) {
log.throwing(Service.class.getName(), "getCurrentUser", e);
log.severe("Could not get user data: " + e.getLocalizedMessage());
return null;
}
}
任何帮助,将不胜感激。谢谢。
编辑时:添加了堆栈跟踪:
java.lang.Long 无法转换为 java.lang.Integer java.lang.ClassCastException:java.lang.Long 无法转换为 java.lang.Integer 在 com.google.appengine.datanucleus.TypeConversionUtils.datastoreValueToPojoValue(TypeConversionUtils.java :403) 在 com.google.appengine.datanucleus.FetchFieldManager.fetchFieldFromEntity(FetchFieldManager.java:463) 在 com.google.appengine.datanucleus.FetchFieldManager.fetchObjectField(FetchFieldManager.java:408) 在 org.datanucleus.state.AbstractStateManager。在 com.ihg.dashboard.server.domain.Page.jdoReplaceField(Page.java) 在 com.ihg.dashboard.server.domain.Page.jdoReplaceFields(Page.java) 在 org.datanucleus 替换ObjectField(AbstractStateManager.java:2353) .state.JDOStateManager.replaceFields(JDOStateManager.java:1935) 在 org.datanucleus.state.JDOStateManager。replaceFields(JDOStateManager.java:1962) 在 com.google.appengine.datanucleus.EntityUtils$1.fetchFields(EntityUtils.java:974) 在 org.datanucleus.state.JDOStateManager.loadFieldValues(JDOStateManager.java:764) 在 org.datanucleus。 state.JDOStateManager.initialiseForHollow(JDOStateManager.java:205) 在 org.datanucleus.state.StateManagerFactory.newForHollowPopulated(StateManagerFactory.java:89) 在 org.datanucleus.state.ObjectProviderFactory.newForHollowPopulated(ObjectProviderFactory.java:75) 在 org.datanucleus .ObjectManagerImpl.findObject(ObjectManagerImpl.java:2882) 在 com.google.appengine.datanucleus.EntityUtils.entityToPojo(EntityUtils.java:1014) 在 com.google.appengine.datanucleus.FetchFieldManager.getCollectionFromDatastoreObject(FetchFieldManager.java:680) 在com.google.appengine.datanucleus。FetchFieldManager.fetchRelationField(FetchFieldManager.java:483) 在 com.google.appengine.datanucleus.FetchFieldManager.fetchObjectField(FetchFieldManager.java:405) 在 org.datanucleus.state.AbstractStateManager.replacingObjectField(AbstractStateManager.java:2353) 在 com.ihg .dashboard.server.domain.IHGUser.jdoReplaceField(IHGUser.java) 在 com.ihg.dashboard.server.domain.IHGUser.jdoReplaceFields(IHGUser.java) 在 org.datanucleus.state.JDOStateManager.replaceFields(JDOStateManager.java:1935 ) 在 org.datanucleus.state.JDOStateManager.loadFieldsFromDatastore(JDOStateManager) 在 com.google.appengine.datanucleus.DatastorePersistenceHandler.fetchObject(DatastorePersistenceHandler.java:567) java:1638) 在 org.datanucleus.state。JDOStateManager.loadSpecifiedFields(JDOStateManager.java:1240) 在 org.datanucleus.state.JDOStateManager.isLoaded(JDOStateManager.java:1728) 在 com.ihg.dashboard.server.domain.IHGUser.jdoGetpages(IHGUser.java) 在 com.ihg .dashboard.server.domain.IHGUser.getPages(IHGUser.java:209) 在 com.ihg.dashboard.server.services.HplUIService.getCurrentIHGUser(HplUIService.java:188) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在 java.lang.reflect.Method.invoke(Method.java:597) 在 com。 com.google.web.bindery.requestfactory.server 上的 google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:115)。ReflectiveServiceLayer.invoke(ReflectiveServiceLayer.java:182) 在 com.google.web.bindery.requestfactory.server.ServiceLayerDecorator.invoke(ServiceLayerDecorator.java:111) 在 com.google.web.bindery.requestfactory.server.ServiceLayerDecorator.invoke( ServiceLayerDecorator.java:111) 在 com.google.web.bindery.requestfactory.server.ServiceLayerDecorator.invoke(ServiceLayerDecorator.java:111) 在 com.google.web.bindery.requestfactory.server.SimpleRequestProcessor.processInvocationMessages(SimpleRequestProcessor.java: 463) 在 com.google.web.bindery.requestfactory.server.SimpleRequestProcessor.process(SimpleRequestProcessor.java:233) 在 com.google.web.bindery.requestfactory.server.SimpleRequestProcessor.process(SimpleRequestProcessor.java:135) 在 com .google.web.bindery.requestfactory.server.RequestFactoryServlet。doPost(RequestFactoryServlet.java:133) 在 com.ihg.dashboard.server.DashboardServlet.doPost(DashboardServlet.java:61) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:637) 在 javax.servlet.http .HttpServlet.service(HttpServlet.java:717) 在 com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:263) 在 com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:178) 在com.google.inject.servlet.ManagedServletPipeline.service(ManagedServletPipeline.java:91) 在 com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:62) 在 com.google.inject.servlet.ManagedFilterPipeline.dispatch( ManagedFilterPipeline.java:118) 在 com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:113) 在 org.mortbay.jetty.servlet。ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 在 com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter( ServletHandler.java:1157) 在 com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:123) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 在 com .google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 在 com.google.appengine.api.blobstore .dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:61) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain。doFilter(ServletHandler.java:1157) 在 com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)在 com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 在 com.google.appengine.tools .development.BackendServersFilter.doFilter(BackendServersFilter.java:97) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 在 org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java :388) 在 org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) 在 org.mortbay.jetty.servlet。SessionHandler.handle(SessionHandler.java:182) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) at com .google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:94) 在 org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) 在 com.google.appengine.tools.development.JettyContainerService $ApiProxyHandler.handle(JettyContainerService.java:409) 在 org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) 在 org.mortbay.jetty.Server.handle(Server.java:326) 在 org. mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938) at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755) at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) at org .mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409) 在 org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
在编辑 2 上: 在设置抛出异常的断点后,我看到它是导致问题的枚举字段。我在那里做的事情是不对的。
发生异常的行的代码是:
value = enumClass.getEnumConstants()[(Integer)value];
因此,从数据库中读取的值似乎是 Long,但我猜当它从新创建的实体保存在缓存中时,它是一个 Integer。
在编辑 3
我将枚举字段更改为
@Enumerated(STRING) private LayoutType layoutType = LayoutType.Col3StyleEven;
这会将值存储为 String 而不是 Ordinal。它不如 Ordinal 高效,但它会让我克服这个错误。