gpt4 book ai didi

java - 如何删除持久/非持久集合字段为空的对象?

转载 作者:行者123 更新时间:2023-12-01 15:32:31 25 4
gpt4 key购买 nike

我有一个名为 Parent 的类,我将这些对象存储在高复制数据存储中。

每个对象都与我通过存储Key对象列表进行管理的对象之间存在无主关系。

我有一个 REST Web 服务,它以 JSON 表示形式返回父对象和所有子对象。为了使用 Jackson 编码器,我获取了子对象的集合,并使用未定义参数化类型的原始集合将该集合添加到父对象中。

Collection 字段不是我打算保留的内容。然而,因为 According to DataNucleus's Andy, Google's JDO @Persistent documentation is potentially incorrect ,我没有在该字段上添加@NotPercient 注解。现在我在数据存储中拥有用户数据,需要小心不要通过修改 Parent 类而意外破坏它。我不确定这是否可能或是否会发生,所以我会谨慎行事。

此空 Collection cardList 值中没有存储任何数据;但是,我经常会遇到无法分离该字段的错误。

  • 如果字段上没有任何注释(根据 Andy 的说法,默认为 @Persistent),我无法删除该对象。
  • 如果我在字段上放置 @NotPercient,则无法访问任何数据,也不会产生任何效果。

这是“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 字段不持久,以便我可以使用它在前端序列化数据?

最佳答案

在这种情况下:

// pm.deletePersistent(detachedParent.getChildList()); becomes unnecessary, and
pm.deletePersistent(parent); //should work

在这种情况下您还会遇到另一个异常吗?

@jmort253 更新:

已检查以确保项目中不包含重复的 appengine JAR 文件。我之前升级过,一些旧的 JAR 没有从 CLASSPATH 中删除。类加载器可能会加载旧版本并忽略新版本,这就是我的情况。事实证明,解决依赖关系就可以解决这个问题。

此外,我可以毫无问题地使用 @NotPersistent,并且可以使用 Transaction 和 PMF DataNucleus DetachOnClose property 分离对象。如Andy describes in this Google Group .

删除父级:

public boolean deleteLoop(String parentId) {
PersistenceManager pm = PMF.getInstance().getPersistenceManager();
Transaction tx = pm.currentTransaction();
try {
tx.begin();
pm.setDetachAllOnCommit(true);
Parent parent = null;

Key parentKey = KeyFactory.stringToKey(parentId);
loop = pm.getObjectById(Parent.class, parentKey);

Parent detachedParent = pm.detachCopy(parent);

// this was indeed not necessary
//pm.deletePersistent(detachedParent.getChildList());

// no detachment issues, object deletes just fine.
pm.deletePersistent(detachedParent);

tx.commit();
//pm.close();

} catch(Exception e) {
log.error("Exception trying to delete Parent :: ",e);
e.printStackTrace();


} finally {

if(tx.isActive()) {
tx.rollback();
}

pm.close();
}
}

父类:

现在可以添加@NotPercient,而不会收到类路径警告。除了 JAR 依赖性问题之外,我还必须向 Collection 定义添加参数化类型。如果省略,您会收到以下警告:

  • 在 CLASSPATH 中找不到类“”。请检查您的规范和 CLASSPATH。

     @PersistenceCapable(detachable = "true")
    public class Parent implements Serializable {
    ...
    @NotPersistent
    private Collection<Child> childList;
    ...
    }

关于java - 如何删除持久/非持久集合字段为空的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9402744/

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