2

I have items that can contain further items, therefore I need a @OneToMany relationship with the same Entity. I have configured my field like this:

@ManyToOne(targetEntity=PersistentItem.class, fetch=FetchType.EAGER)
@JoinColumn(name="ID_CHILDREN", nullable=false)
HashSet<PersistentItem> children=new HashSet<PersistentItem>();

However, Java always throws the following error:

SEVERE: Servlet.service() for servlet HelloWorld threw exception
javax.persistence.RollbackException: java.lang.NullPointerException

Is that because some items don't have any children?

My JPA implementation provider is EclipseLink.

EDIT: The full stack trace is:

03-Aug-2009 19:22:09 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet HelloWorld threw exception
javax.persistence.RollbackException: java.lang.NullPointerException
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102)
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
    at info.lenni.gate.servlet.HelloWorld.doGet(HelloWorld.java:52)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Thread.java:637)
Caused by: java.lang.NullPointerException
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.checkForUnregisteredExistingObject(UnitOfWorkImpl.java:678)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4007)
    at org.eclipse.persistence.mappings.ObjectReferenceMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectReferenceMapping.java:743)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectBuilder.java:1511)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4019)
    at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.discoverUnregisteredNewObjects(RepeatableWriteUnitOfWork.java:182)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:628)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1387)
    at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:160)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1060)
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:84)
    ... 16 more
4

2 回答 2

2

Your mapping is most definitely incorrect.
First of all, it should be @OneToMany, not `@ManyToOne' - you're mapping a collection (that is, MANY). Perhaps that's a typo, though, as question title does say "OneToMany".

Secondly, the way it's mapped will make association unidirectional. That's not a recommended approach. Are you 100% positive that's what you want? It may be better to change this to a bi-directional mapping by adding a "parent" property.

Finally, eager fetching on an association like this would pull the entire sub-tree when you select an item (e.g. item itself, its children, their children, etc...) While there are some circumstances where that may be desirable, they're rather uncommon. Do you really want that behavior? Perhaps it would be better to use a different model (like nested sets)?

于 2009-08-03T19:18:46.183 回答
0

What do you intend by setting nullable to false?

@JoinColumn(name="ID_CHILDREN", nullable=false)

If some items can't have children is that right?

于 2009-08-03T17:18:38.237 回答