2017-08-27 64 views
0

當我嘗試使用Jersey rest服務創建新用戶時,我從POSTMAN獲取500 - Internal Server Error。有人能告訴我什麼是加載和形成休眠一對多映射的正確方法。我使用jersey-media-moxy作爲JSON的支持。Jersey Web服務和休眠一對多映射

在我的代碼,我有我的資源:

@Path("/users") 
@Consumes(MediaType.APPLICATION_JSON) 
@Produces(MediaType.APPLICATION_JSON) 
public class UserResource { 

    private UserService userService = new UserService(); 

    @POST 
    public User addUser(User user) { 
     return userService.addUser(user); 
    } 
} 

UserService

public class UserService { 

    public UserService() { 
    } 

    public User addUser(User user) { 
     Object<User> newUser = new ObjectImpl<User>(); 
     return newUser.addObject(User.class, user); 
    } 
} 

我的用戶實體模型

@Entity 
@NamedQuery(name="User.authenticate", query="from User u where u.userEmail=:email") 
@Table(name="USER", schema="mastercard") 
@XmlRootElement 
public class User { 
    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name="user_id") 
    private long userId; 
    @Column(name="user_email", unique=true, nullable=false) 
    private String userEmail; 
    private String password; 
    @Column(updatable=false) 
    @CreationTimestamp 
    private Timestamp created; 
    @UpdateTimestamp 
    private Timestamp modified; 
    @OneToMany(mappedBy="user") 
    private Collection<Favourite> favourite = new ArrayList<Favourite>(); 
} 

的錯誤跟蹤:

javax.ws.rs.WebApplicationException: HTTP 500 Internal Server Error 
    at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.writeTo(MOXyJsonProvider.java:951) 
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265) 
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250) 
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162) 
    at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:106) 
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162) 
    at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:86) 
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162) 
    at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1130) 
    at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:711) 
    at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:444) 
    at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:434) 
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:329) 
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) 
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267) 
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) 
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) 
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) 
    at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473) 
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427) 
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388) 
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341) 
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) 
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) 
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) 
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) 
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) 
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Thread.java:748) 
Caused by: javax.xml.bind.MarshalException 
- with linked exception: 
[org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.algattas.savour.savour_rewards.model.User.favourite, could not initialize proxy - no Session] 
    at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:487) 
    at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.writeTo(MOXyJsonProvider.java:949) 
    ... 47 more 
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.algattas.savour.savour_rewards.model.User.favourite, could not initialize proxy - no Session 
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:582) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:201) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:561) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:132) 
    at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:277) 
    at org.eclipse.persistence.internal.queries.CollectionContainerPolicy.iteratorFor(CollectionContainerPolicy.java:171) 
    at org.eclipse.persistence.internal.oxm.XMLCompositeCollectionMappingNodeValue.marshal(XMLCompositeCollectionMappingNodeValue.java:92) 
    at org.eclipse.persistence.internal.oxm.NodeValue.marshal(NodeValue.java:149) 
    at org.eclipse.persistence.internal.oxm.NodeValue.marshal(NodeValue.java:102) 
    at org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext.marshal(ObjectMarshalContext.java:59) 
    at org.eclipse.persistence.internal.oxm.XPathNode.marshal(XPathNode.java:443) 
    at org.eclipse.persistence.internal.oxm.XPathObjectBuilder.buildRow(XPathObjectBuilder.java:243) 
    at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(TreeObjectBuilder.java:118) 
    at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(TreeObjectBuilder.java:1) 
    at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:766) 
    at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshalStreamOrWriter(XMLMarshaller.java:1147) 
    at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:934) 
    at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:877) 
    at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:483) 
    ... 48 more 

當我讀到這個錯誤時,發現它發生是因爲在會話關閉後嘗試訪問相關的表。但是,我不嘗試訪問代碼中任何地方的相關對象。我的addUser實現如下:

@Override 
    public T addObject(Class<T> entityClass, T newObject) { 
     SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); 
     Session session = sessionFactory.openSession(); 
     Transaction transaction = null; 
     long newObjectId = -1L; 
     try { 
      transaction = session.beginTransaction(); 
      newObjectId = (long) session.save(newObject); 
      session.getTransaction().commit(); 
     } catch (HibernateException e) { 
      if (transaction != null) { 
       transaction.rollback(); 
      } 
     } finally { 
      session.close(); 
     } 
     return getObject(entityClass, newObjectId); 
    } 

回答

1

此問題是由這個代碼引起:

@OneToMany(mappedBy="user") 
private Collection<Favourite> favourite = new ArrayList<Favourite>(); 


你能告訴你的Favourite實體? 您應該嘗試@OneToMany(mappedBy = "itemType", fetch = FetchType.EAGER, cascade = CascadeType.ALL)Favourite

+0

謝謝,在這裏我改變了急於加載並使用'@ XmlTransient'從XML響應中刪除它。 – swdon

+0

你可以爲「謝謝」代替這個答案嗎?給出使用'@ XmlTransient'的例子,並將其標記爲接受的答案。對於存在相同問題的其他用戶來說,這將非常有用。 –

+0

我無法完全接受您的答案,因爲我不認爲Eager加載是一個不錯的選擇。你可以改進它來處理嘗試加載可能導致性能問題的所有事情的問題。 – swdon