У меня есть класс с именем Parent , и я храню эти объекты в хранилище данных высокой репликации.
У каждого объекта есть несобственные отношения с дочерними объектами.которым я управляю, храня список объектов Key .
У меня есть веб-служба REST, которая возвращает родительский и все дочерние объекты в виде представления JSON.Чтобы использовать маршаллера Джексона, я беру коллекцию объектов Child и добавляю эту коллекцию в Parent, используя необработанную коллекцию без заданных параметризованных типов.
Поле Collection не было тем, что я намеревался сохранить.Тем не менее, поскольку По словам Энди из DataNucleus, документация Google JDO @Persistent является потенциально неверной , я не поместил аннотацию @NotPersistent в поле.Теперь у меня есть пользовательские данные в хранилище данных, и я должен быть осторожен, чтобы случайно не уничтожить их, изменив класс Parent.Я не уверен, возможно ли это или может ли это произойти, поэтому я действую осторожно.
Нет данных, хранящихся в этом нулевом Collection cardList ;однако я часто получаю ошибки из-за невозможности отсоединить поле.
- Без каких-либо аннотаций на поле (который, по словам Энди, по умолчанию равен @Persistent), я не могу удалить объект.
- Если я добавлю @NotPersistent в поле, тогда ни один из данных не будет доступен, и ничего не будет работать.
Вот класс "Parent":
public class Parent implements Serializable {
private static final long serialVersionUID = 1L;
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
@Persistent
private String keyString;
@Persistent
private String name;
// store keys that associate with Child objects
@Persistent
private List<Key> childRealKeys = new ArrayList<Key>();
/**
* If @NotPersistent, no Parent is accessible.
* If @NotPersistent is commented, the data loads, but I cannot delete the parent.
*
* This field was not intended to be stored and is just used to serialize the Parent
* and Children to a single JSON object to be returned in a REST call.
*/
// @NotPersistent
private Collection childList = null;
// getter for the field I don't want to store but just use to return children in the REST service as JSON
public Collection getChildList() { return childList; }
// remaining getters and setters follow ...
Вот код, который я использую для удаления объекта :
public void deleteParent(String keyString) {
PersistenceManager pm = PMF.getInstance().getPersistenceManager();
Parent parent = null;
Key parentKey = KeyFactory.stringToKey(keyString);
parent = pm.getObjectById(Parent.class, parentKey);
// I tried detaching to see if that helps. It still says the field is not detached!
Parent detachedParent = pm.detachCopy(parent);
pm.deletePersistent(detachedParent.getChildList());
pm.deletePersistent(detachedParent);
pm.close();
}
StackTrace при попытке удалить объект:
Обратите внимание, что опять же, данные не сохраняются для этого поля.Я также не могу успешно отсоединить поле.
javax.jdo.JDODetachedFieldAccessException: You have just attempted to access field "childList" yet this field was not detached when you detached the object. Either dont access this field, or detach it when detaching the object.
at com.fullcreative.loop.Parent.jdoGetChildList(Parent.java)
at com.fullcreative.loop.Parent.getChildList(Parent.java:112)
at com.fullcreative.loop.LoopDaoJdo.deleteParent(LoopDaoJdo.java:690)
at com.fullcreative.loop.LoopService.deleteParent(LoopService.java:551)
at com.fullcreative.loop.LoopController.deleteParent(LoopController.java:1022)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:104)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:582)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:643)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:369)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at com.fullcreative.loop.security.auth.GaeAuthenticationFilter.doFilter(GaeAuthenticationFilter.java:227)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:35)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:60)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:122)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.BackendServersFilter.doFilter(BackendServersFilter.java:97)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at 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:78)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:362)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Вопросы:
Как я могу удалить родительский объект?
Что мне нужно сделать, чтобы удалить пустое поле «Коллекция» из хранилища данных без потери всех моих данных?Мне кажется, что наилучшим подходом может быть использование 2 отдельных, но зеркальных объектов: один для хранения родительского и дочернего ключей в хранилище данных, а другой для возврата родительского и всех связанных дочерних объектов в виде представления JSON.
Есть ли способ задним числом сделать поле Collection cardList NotPersistent, чтобы я мог просто использовать его для сериализации данных во внешнем интерфейсе?