2012-03-20 115 views
2

我正在爲我的數據庫開發一個寧靜的Web服務。我正在使用jpa從數據庫和彈簧中爲該體系結構重新獲取數據。我已經用基本的dao查詢(findById,save ...)測試了這個體系結構,並且它完美地工作。然後,在DAO實現我增加了一個新方法至極基本上執行被直接測試的MySQL數據庫的查詢(和它的工作)未能懶洋洋地初始化集合

public List<PositionHistory> findByFavUserGBuser(Integer favoriteUserId, 
     Integer pageNumber, Integer rowsPerPage, String usernameFilter) { 
    String queryString="" + 
      "SELECT ph.* " + 
      "FROM user u, position_history ph, spot s " + 
      "WHERE " + 
       "ph.date IN (SELECT MAX(ph2.date) FROM position_history ph2 GROUP BY ph2.user_iduser) and " + 
       "s.id_spot=ph.spot_idspot and " + 
       "u.id_user=ph.user_iduser and "; 

    if (usernameFilter!=null) 
     queryString+="u.username like '%:usernameFilter%' and "; 

    queryString+="" + 
       "ph.user_iduser IN (SELECT ALL fu.user_iduserto FROM favorite_user fu WHERE fu.user_iduserfrom=:favoriteUserId) " + 
      "GROUP BY ph.user_iduser " + 
      "LIMIT :startLimit,:rowsPerPage"; 

    Query query = entityManager.createNativeQuery(queryString,PositionHistory.class); 
    query.setParameter("favoriteUserId", favoriteUserId); 
    query.setParameter("startLimit", pageNumber*rowsPerPage); 
    query.setParameter("rowsPerPage", rowsPerPage); 

    if (usernameFilter!=null) 
     query.setParameter("usernameFilter", usernameFilter); 

    return query.getResultList(); 
} 

,然後我創建了一個控制器以檢索數據如下:

@Controller 
@Transactional 
public class MyController { 

    @Autowired 
    public DaoPositionHistory dph; 

    @Transactional 
    @RequestMapping(value = "/getData/{id}/", method = RequestMethod.POST) 
    @ResponseBody 
    public List<PositionHistory> home(@PathVariable int id) { 
     List<PositionHistory> resultlist=(List<PositionHistory>) dph.findByNearestPositionGBuser(id, 0, 10, null, null, null); 
     return resultlist; 
    } 
} 

但是當我撥打服務我得到以下錯誤:

ERROR: org.hibernate.LazyInitializationException - failed to lazily initialize a collection of role: com.windy.spring.data.User.favoriteSports, no session or session was closed 
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.windy.spring.data.User.favoriteSports, no session or session was closed 
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383) 
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375) 
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368) 
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111) 
    at org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:272) 
    at org.codehaus.jackson.map.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:45) 
    at org.codehaus.jackson.map.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23) 
    at org.codehaus.jackson.map.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:86) 
    at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446) 
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150) 
    at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) 
    at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446) 
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150) 
    at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) 
    at org.codehaus.jackson.map.ser.std.StdContainerSerializers$IndexedListSerializer.serializeContents(StdContainerSerializers.java:122) 
    at org.codehaus.jackson.map.ser.std.StdContainerSerializers$IndexedListSerializer.serializeContents(StdContainerSerializers.java:71) 
    at org.codehaus.jackson.map.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:86) 
    at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610) 
    at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256) 
    at org.codehaus.jackson.map.ObjectMapper.writeValue(ObjectMapper.java:1613) 
    at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.writeInternal(MappingJacksonHttpMessageConverter.java:142) 
    at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:179) 
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:137) 
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:81) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:94) 
    at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:73) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) 
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) 
    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:127) 
    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:293) 
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) 
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602) 
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) 
    at java.lang.Thread.run(Unknown Source) 

我不明白爲什麼我得到這個錯誤,如果我宣佈methos爲@Transactional?有關我如何解決問題的任何想法?

這裏也是我的用戶類

@XmlRootElement 
@Entity 
public class User implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name="id_user") 
    private int idUser; 

    private String cellphone; 

    private String email; 

    @Lob() 
    private byte[] foto; 

    private String name; 

    private String notes; 

    private String password; 

    private String surname; 

    private String username; 

    //bi-directional many-to-one association to FavoriteSport 
    @OneToMany(mappedBy="user") 
    private List<FavoriteSport> favoriteSports; 

    //bi-directional many-to-one association to FavoriteSpot 
    @OneToMany(mappedBy="user") 
    private List<FavoriteSpot> favoriteSpots; 

    //bi-directional many-to-one association to FavoriteUser 
    @OneToMany(mappedBy="user2") 
    private List<FavoriteUser> favoriteUsers; 

    //uni-directional many-to-one association to Role 
    @ManyToOne 
    @JoinColumn(name="role_idrole") 
    private Role role; 

    //bi-directional many-to-one association to UserAccount 
    @OneToMany(mappedBy="user") 
    private List<UserAccount> userAccounts; 

    public User() { 
    } 

    public int getIdUser() { 
     return this.idUser; 
    } 

    public void setIdUser(int idUser) { 
     this.idUser = idUser; 
    } 

    public String getCellphone() { 
     return this.cellphone; 
    } 

    public void setCellphone(String cellphone) { 
     this.cellphone = cellphone; 
    } 

    public String getEmail() { 
     return this.email; 
    } 

    public void setEmail(String email) { 
     this.email = email; 
    } 

    public byte[] getFoto() { 
     return this.foto; 
    } 

    public void setFoto(byte[] foto) { 
     this.foto = foto; 
    } 

    public String getName() { 
     return this.name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getNotes() { 
     return this.notes; 
    } 

    public void setNotes(String notes) { 
     this.notes = notes; 
    } 

    public String getPassword() { 
     return this.password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

    public String getSurname() { 
     return this.surname; 
    } 

    public void setSurname(String surname) { 
     this.surname = surname; 
    } 

    public String getUsername() { 
     return this.username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    public List<FavoriteSport> getFavoriteSports() { 
     return this.favoriteSports; 
    } 

    public void setFavoriteSports(List<FavoriteSport> favoriteSports) { 
     this.favoriteSports = favoriteSports; 
    } 

    public List<FavoriteSpot> getFavoriteSpots() { 
     return this.favoriteSpots; 
    } 

    public void setFavoriteSpots(List<FavoriteSpot> favoriteSpots) { 
     this.favoriteSpots = favoriteSpots; 
    } 

    public List<FavoriteUser> getFavoriteUsers() { 
     return this.favoriteUsers; 
    } 

    public void setFavoriteUsers(List<FavoriteUser> favoriteUsers) { 
     this.favoriteUsers = favoriteUsers; 
    } 

    public Role getRole() { 
     return this.role; 
    } 

    public void setRole(Role role) { 
     this.role = role; 
    } 

    public List<UserAccount> getUserAccounts() { 
     return this.userAccounts; 
    } 

    public void setUserAccounts(List<UserAccount> userAccounts) { 
     this.userAccounts = userAccounts; 
    } 

} 

回答

1

堆棧跟蹤清楚地表明,異常發生時後的控制器的方法已經完成(以及交易關閉)。因此,無論是使用擴展持久化上下文(其中會話活動時間超過事務處理時間),在控制器方法返回之前訪問延遲集合,修改DAO或映射以熱切加載集合,或者不返回包含該集合的對象採集。

0

你的錯誤是因爲你沒有初始化DAO中的實體關聯,然後Jackson轉換器試圖將返回對象中的所有關聯轉換爲JSON。由於關聯沒有初始化,因爲Controller沒有處理Hibernate Session,所以會引發錯誤。

見我的答案這裏如何糾正:Spring @ResponseBody Json Cyclic Reference

2

我從閱讀其他回答您的問題想通了這一點。以下是一個例子:

@Override 
public OriginServer get(Integer id){ 
    OriginServer server = (OriginServer) sessionFactory 
     .getCurrentSession().get(OriginServer.class, id); 
    Hibernate.initialize(server.getPools()); 
    return server; 
} 

在這個例子中'getPools'是OriginServer的@OneToMany關係。

相關問題