0

ページのリストをエンティティとして持つユーザーがいるプロジェクトがあります。ページを使用して最初にユーザーを作成すると、すべてのフェッチが期待どおりに機能しますが、local_db.bin appengine-datanucleus サーバーを再起動すると、ページのリストをフェッチするときにエラーが発生します。リクエスト ファクトリを使用しているため、ページの ID を文字列として取得しています。これが間違っている場合は修正してください。以下のコードでは、ページ リストのフェッチを強制していますが、実際には、リクエストに .with("pages") メソッドが追加されたときに、リクエスト ファクトリ コードによってリストが読み込まれました。しかし、ページを強制的に読み込むと同じエラーが発生し、コードに簡単にステップインできます。
私が得るエラーはjava.lang.Long cannot be cast to java.lang.Integerです. 多くの datanucleus コードを調べましたが、ストアからのデータが新しく作成されたクラスに読み込まれるときにエラーが発生しているようです。クラス内の唯一の整数は、バージョンと 1 つのフィールドです。どちらも Long にしようとしました。データベースをクリアし、データを再作成してから、同じエラーが発生したサーバーを再起動します。私の感じでは、id を文字列にすることと関係があると思います。

設定が間違っているか、datanucleus JPA 2 サポートにバグがあります。うまくいけば、誰かがこれに対する答えを知っているでしょう。以下は、エラーの原因となった 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: 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. replacementObjectField(AbstractStateManager.java:2353) com.ihg.dashboard.server.domain.Page.jdoReplaceField(Page.java) com.ihg.dashboard.server.domain.Page.jdoReplaceFields(Page.java) org.datanucleus org.datanucleus.state.JDOStateManager の .state.JDOStateManager.replaceFields(JDOStateManager.java:1935)。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.replaceFields(JDOStateManager.java:1962) で com.google.appengine.datanucleus.DatastorePersistenceHandler.fetchObject(DatastorePersistenceHandler.java:567) で org.datanucleus.state.JDOStateManager.loadFieldsFromDatastore(JDOStateManager. 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) at com.ihg.dashboard.server.services.HplUIService.getCurrentIHGUser(HplUIService.java:188) at 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. google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:115) com.google.web.bindery.requestfactory.server.com.google.web.bindery.requestfactory.server.ServiceLayerDecorator.invoke(ServiceLayerDecorator.java:111) の 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.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) で.google.web.bindery.requestfactory.server.RequestFactoryServlet.com.ihg.dashboard.server.DashboardServlet.doPost(DashboardServlet.java:61) の doPost(RequestFactoryServlet.java:133) javax.servlet.http の HttpServlet.service(HttpServlet.java:637) .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) at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74) at 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 でorg.mortbay.jetty.servlet.ServletHandler$CachedChain の .dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:61)。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 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) の .development.BackendServersFilter.doFilter(BackendServersFilter.java:97) org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java) :388) org.mortbay.jetty.servlet の org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) で。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) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at 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. org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938) の org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)。mortbay.jetty.HttpParser.parseNext(HttpParser.java:755) org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218) org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) org .mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409) at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

編集 2: 例外がスローされるブレークポイントを設定した後、列挙型フィールドが問題の原因であることがわかります。私がそこでしていることは正しくありません。

例外が発生した行のコードは次のとおりです。

 value = enumClass.getEnumConstants()[(Integer)value];

したがって、データベースからの読み取りが長い場合は価値があるように見えますが、新しく作成されたエンティティからキャッシュに保持されている場合は整数であると思います。

編集時 3

列挙型フィールドを次のように変更します

@Enumerated(STRING) private LayoutType layoutType = LayoutType.Col3StyleEven;

これにより、値が序数ではなく文字列として格納されます。Ordinal ほど効率的ではありませんが、このエラーを回避できます。

4

0 に答える 0